'use client';

import { useState, useEffect } from 'react';
import {
  Key,
  Plus,
  Copy,
  MoreHorizontal,
  ShieldCheck,
  ShieldOff,
  Clock,
  CheckCircle2,
  XCircle,
  AlertTriangle,
  Trash2,
} from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Switch } from '@/components/ui/switch';
import {
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableHeader,
  TableRow,
} from '@/components/ui/table';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { mockApiTokens, formatDate, type ApiToken as MockApiToken } from '@/lib/mock-data';
import { apiListTokens, apiCreateToken, apiRevokeToken, apiDeleteToken } from '@/lib/api';

const statusConfig = {
  active: {
    label: 'Active',
    color: 'bg-emerald-50 text-emerald-700',
    icon: CheckCircle2,
  },
  revoked: {
    label: 'Revoked',
    color: 'bg-red-50 text-red-700',
    icon: XCircle,
  },
  expired: {
    label: 'Expired',
    color: 'bg-amber-50 text-amber-700',
    icon: AlertTriangle,
  },
};

const allScopes = ['dictate', 'transcribe', 'cleanup', 'admin'];

export default function TokensPage() {
  const [tokens, setTokens] = useState<MockApiToken[]>(mockApiTokens);
  const [showCreate, setShowCreate] = useState(false);
  const [statusFilter, setStatusFilter] = useState<string>('all');
  const [newTokenName, setNewTokenName] = useState('');
  const [newTokenScopes, setNewTokenScopes] = useState<string[]>(['dictate', 'transcribe']);
  const [newTokenExpiry, setNewTokenExpiry] = useState('90');
  const [generatedToken, setGeneratedToken] = useState<string | null>(null);
  const [copiedPrefix, setCopiedPrefix] = useState<string | null>(null);
  const [copiedToken, setCopiedToken] = useState(false);

  useEffect(() => {
    apiListTokens().then(({ data }) => {
      if (data?.tokens?.length) {
        setTokens(
          data.tokens.map(t => ({
            id: t.id,
            userId: t.userId,
            userName: t.userName,
            name: t.name,
            prefix: t.prefix,
            status: t.status as MockApiToken['status'],
            createdAt: t.createdAt,
            expiresAt: t.expiresAt,
            lastUsed: t.lastUsed,
            scopes: t.scopes,
          }))
        );
      }
    });
  }, []);

  const filtered = tokens.filter(t => statusFilter === 'all' || t.status === statusFilter);

  const activeCount = tokens.filter(t => t.status === 'active').length;
  const revokedCount = tokens.filter(t => t.status === 'revoked').length;
  const expiredCount = tokens.filter(t => t.status === 'expired').length;

  const handleCreate = async () => {
    const { data, error } = await apiCreateToken({
      name: newTokenName,
      scopes: newTokenScopes,
      expiresInDays: parseInt(newTokenExpiry),
    });
    if (data) {
      setGeneratedToken(data.rawToken);
      setTokens(prev => [
        {
          id: data.id,
          userId: data.userId,
          userName: data.userName,
          name: data.name,
          prefix: data.prefix,
          status: data.status as MockApiToken['status'],
          createdAt: data.createdAt,
          expiresAt: data.expiresAt,
          lastUsed: data.lastUsed,
          scopes: data.scopes,
        },
        ...prev,
      ]);
    } else {
      setGeneratedToken(`error: ${error}`);
    }
  };

  const handleRevoke = async (tokenId: string) => {
    const token = tokens.find(t => t.id === tokenId);
    if (!token) return;
    if (!confirm(`Revoke token "${token.name}"? This cannot be undone.`)) return;
    const { error } = await apiRevokeToken(tokenId);
    if (!error) {
      setTokens(prev =>
        prev.map(t => (t.id === tokenId ? { ...t, status: 'revoked' as const } : t))
      );
    }
  };

  const handleDelete = async (tokenId: string) => {
    const token = tokens.find(t => t.id === tokenId);
    if (!token) return;
    if (!confirm(`Permanently delete token "${token.name}"? This cannot be undone.`)) return;
    const { error } = await apiDeleteToken(tokenId);
    if (!error) {
      setTokens(prev => prev.filter(t => t.id !== tokenId));
    }
  };

  const toggleScope = (scope: string) => {
    setNewTokenScopes(prev =>
      prev.includes(scope) ? prev.filter(s => s !== scope) : [...prev, scope]
    );
  };

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h1 className="text-3xl font-bold tracking-tight">API Tokens</h1>
          <p className="text-muted-foreground">Create and manage API access tokens</p>
        </div>
        <Button
          onClick={() => {
            setShowCreate(true);
            setGeneratedToken(null);
            setNewTokenName('');
          }}
        >
          <Plus className="mr-2 h-4 w-4" />
          Generate Token
        </Button>
      </div>

      {/* Summary */}
      <div className="grid gap-4 md:grid-cols-3">
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">
              Active Tokens
            </CardTitle>
          </CardHeader>
          <CardContent>
            <div className="flex items-center gap-2">
              <ShieldCheck className="h-5 w-5 text-emerald-500" />
              <span className="text-2xl font-bold">{activeCount}</span>
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">Revoked</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="flex items-center gap-2">
              <ShieldOff className="h-5 w-5 text-red-500" />
              <span className="text-2xl font-bold">{revokedCount}</span>
            </div>
          </CardContent>
        </Card>
        <Card>
          <CardHeader className="pb-2">
            <CardTitle className="text-sm font-medium text-muted-foreground">Expired</CardTitle>
          </CardHeader>
          <CardContent>
            <div className="flex items-center gap-2">
              <Clock className="h-5 w-5 text-amber-500" />
              <span className="text-2xl font-bold">{expiredCount}</span>
            </div>
          </CardContent>
        </Card>
      </div>

      {/* Filter */}
      <div className="flex gap-4">
        <Select value={statusFilter} onValueChange={setStatusFilter}>
          <SelectTrigger className="w-[180px]">
            <SelectValue placeholder="Filter by status" />
          </SelectTrigger>
          <SelectContent>
            <SelectItem value="all">All Tokens</SelectItem>
            <SelectItem value="active">Active</SelectItem>
            <SelectItem value="revoked">Revoked</SelectItem>
            <SelectItem value="expired">Expired</SelectItem>
          </SelectContent>
        </Select>
      </div>

      {/* Tokens Table */}
      <Card>
        <CardContent className="pt-6">
          <Table>
            <TableHeader>
              <TableRow>
                <TableHead>Name</TableHead>
                <TableHead>User</TableHead>
                <TableHead>Prefix</TableHead>
                <TableHead>Status</TableHead>
                <TableHead>Scopes</TableHead>
                <TableHead>Created</TableHead>
                <TableHead>Expires</TableHead>
                <TableHead>Last Used</TableHead>
                <TableHead className="w-[50px]" />
              </TableRow>
            </TableHeader>
            <TableBody>
              {filtered.map(token => {
                const status = statusConfig[token.status];
                return (
                  <TableRow key={token.id}>
                    <TableCell className="font-medium">
                      <div className="flex items-center gap-2">
                        <Key className="h-4 w-4 text-muted-foreground" />
                        {token.name}
                      </div>
                    </TableCell>
                    <TableCell className="text-sm">{token.userName}</TableCell>
                    <TableCell>
                      <code className="text-xs bg-muted px-1.5 py-0.5 rounded">
                        {token.prefix}...
                      </code>
                    </TableCell>
                    <TableCell>
                      <Badge variant="secondary" className={status.color}>
                        <status.icon className="mr-1 h-3 w-3" />
                        {status.label}
                      </Badge>
                    </TableCell>
                    <TableCell>
                      <div className="flex flex-wrap gap-1">
                        {token.scopes.map(scope => (
                          <Badge key={scope} variant="outline" className="text-[10px]">
                            {scope}
                          </Badge>
                        ))}
                      </div>
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {formatDate(token.createdAt)}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {formatDate(token.expiresAt)}
                    </TableCell>
                    <TableCell className="text-sm text-muted-foreground">
                      {token.lastUsed ? formatDate(token.lastUsed) : 'Never'}
                    </TableCell>
                    <TableCell>
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button variant="ghost" size="icon" className="h-8 w-8">
                            <MoreHorizontal className="h-4 w-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem
                            onClick={() => {
                              navigator.clipboard.writeText(token.prefix);
                              setCopiedPrefix(token.id);
                              setTimeout(() => setCopiedPrefix(null), 2000);
                            }}
                          >
                            {copiedPrefix === token.id ? (
                              <CheckCircle2 className="mr-2 h-4 w-4 text-green-500" />
                            ) : (
                              <Copy className="mr-2 h-4 w-4" />
                            )}
                            {copiedPrefix === token.id ? 'Copied!' : 'Copy Prefix'}
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          {token.status === 'active' && (
                            <DropdownMenuItem
                              className="text-red-600"
                              onClick={() => handleRevoke(token.id)}
                            >
                              <ShieldOff className="mr-2 h-4 w-4" />
                              Revoke Token
                            </DropdownMenuItem>
                          )}
                          <DropdownMenuItem
                            className="text-red-600"
                            onClick={() => handleDelete(token.id)}
                          >
                            <Trash2 className="mr-2 h-4 w-4" />
                            Delete Token
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </TableCell>
                  </TableRow>
                );
              })}
            </TableBody>
          </Table>
        </CardContent>
      </Card>

      {/* Create Token Dialog */}
      <Dialog open={showCreate} onOpenChange={setShowCreate}>
        <DialogContent className="max-w-md">
          <DialogHeader>
            <DialogTitle>Generate API Token</DialogTitle>
            <DialogDescription>Create a new API token for programmatic access.</DialogDescription>
          </DialogHeader>

          {!generatedToken ? (
            <>
              <div className="space-y-4 py-4">
                <div className="space-y-2">
                  <Label>Token Name</Label>
                  <Input
                    placeholder="e.g. Production, CI/CD, Dev..."
                    value={newTokenName}
                    onChange={e => setNewTokenName(e.target.value)}
                  />
                </div>
                <div className="space-y-2">
                  <Label>Expiry</Label>
                  <Select value={newTokenExpiry} onValueChange={setNewTokenExpiry}>
                    <SelectTrigger>
                      <SelectValue />
                    </SelectTrigger>
                    <SelectContent>
                      <SelectItem value="30">30 days</SelectItem>
                      <SelectItem value="90">90 days</SelectItem>
                      <SelectItem value="180">180 days</SelectItem>
                      <SelectItem value="365">1 year</SelectItem>
                    </SelectContent>
                  </Select>
                </div>
                <div className="space-y-3">
                  <Label>Scopes</Label>
                  {allScopes.map(scope => (
                    <div key={scope} className="flex items-center gap-2">
                      <Switch
                        id={`scope-${scope}`}
                        checked={newTokenScopes.includes(scope)}
                        onCheckedChange={() => toggleScope(scope)}
                      />
                      <Label htmlFor={`scope-${scope}`} className="font-normal capitalize">
                        {scope}
                      </Label>
                    </div>
                  ))}
                </div>
              </div>
              <DialogFooter>
                <Button variant="outline" onClick={() => setShowCreate(false)}>
                  Cancel
                </Button>
                <Button onClick={handleCreate} disabled={!newTokenName.trim()}>
                  Generate
                </Button>
              </DialogFooter>
            </>
          ) : (
            <div className="space-y-4 py-4">
              <div className="rounded-lg border bg-muted/50 p-4">
                <p className="text-xs text-muted-foreground mb-2">
                  Your new API token (copy it now, it won&apos;t be shown again):
                </p>
                <div className="flex items-center gap-2">
                  <code className="flex-1 text-sm font-mono break-all">{generatedToken}</code>
                  <Button
                    variant="ghost"
                    size="icon"
                    className="shrink-0"
                    title={copiedToken ? 'Copied!' : 'Copy token'}
                    onClick={() => {
                      navigator.clipboard.writeText(generatedToken);
                      setCopiedToken(true);
                      setTimeout(() => setCopiedToken(false), 2000);
                    }}
                  >
                    {copiedToken ? (
                      <CheckCircle2 className="h-4 w-4 text-green-500" />
                    ) : (
                      <Copy className="h-4 w-4" />
                    )}
                  </Button>
                </div>
              </div>
              <div className="rounded-lg border border-amber-200 bg-amber-50 p-3">
                <p className="text-sm text-amber-800">
                  <AlertTriangle className="inline mr-1 h-4 w-4" />
                  Store this token securely. You will not be able to see it again after closing this
                  dialog.
                </p>
              </div>
              <DialogFooter>
                <Button onClick={() => setShowCreate(false)}>Done</Button>
              </DialogFooter>
            </div>
          )}
        </DialogContent>
      </Dialog>
    </div>
  );
}
