import { useEffect, useState } from 'react';
import { api, SSHKey } from '../api/client';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Label } from '@/components/ui/Label';
import { Textarea } from '@/components/ui/Textarea';
import { Badge } from '@/components/ui/Badge';
import {
  Modal,
  ModalContent,
  ModalHeader,
  ModalTitle,
  ModalDescription,
  ModalBody,
  ModalFooter,
} from '@/components/ui/Modal';
import { PageHeader } from '@/components/ui/PageHeader';
import { Card, CardBody } from '@/components/ui/Card';
import { EmptyState } from '@/components/ui/EmptyState';
import { CopyButton } from '@/components/ui/CopyButton';
import { Spinner } from '@/components/ui/Spinner';
import {
  Key,
  Plus,
  Upload,
  Download,
  Trash2,
  Fingerprint,
} from 'lucide-react';
import { toast } from 'sonner';
import { cn } from '@/lib/utils';

type ModalType = 'generate' | 'import' | 'delete' | null;

export default function SSHKeys() {
  const [keys, setKeys] = useState<SSHKey[]>([]);
  const [modal, setModal] = useState<ModalType>(null);
  const [deleteId, setDeleteId] = useState<number | null>(null);
  const [genLabel, setGenLabel] = useState('');
  const [importLabel, setImportLabel] = useState('');
  const [importPubKey, setImportPubKey] = useState('');
  const [loading, setLoading] = useState(false);
  const [downloading, setDownloading] = useState<number | null>(null);

  useEffect(() => {
    load();
  }, []);

  async function load() {
    try {
      setKeys(await api<SSHKey[]>('/api/ssh-keys'));
    } catch {}
  }

  async function generate() {
    if (!genLabel.trim()) {
      toast.error('Label is required');
      return;
    }
    setLoading(true);
    try {
      await api('/api/ssh-keys', {
        method: 'POST',
        body: { label: genLabel.trim(), generate: true },
      });
      setModal(null);
      setGenLabel('');
      toast.success('SSH key pair generated');
      load();
    } catch (e: unknown) {
      toast.error((e as Error).message);
    } finally {
      setLoading(false);
    }
  }

  async function importKey() {
    if (!importLabel.trim()) {
      toast.error('Label is required');
      return;
    }
    if (!importPubKey.trim()) {
      toast.error('Public key is required');
      return;
    }
    setLoading(true);
    try {
      await api('/api/ssh-keys', {
        method: 'POST',
        body: {
          label: importLabel.trim(),
          generate: false,
          public_key: importPubKey.trim(),
        },
      });
      setModal(null);
      setImportLabel('');
      setImportPubKey('');
      toast.success('SSH key imported');
      load();
    } catch (e: unknown) {
      toast.error((e as Error).message);
    } finally {
      setLoading(false);
    }
  }

  async function handleDelete() {
    if (deleteId === null) return;
    try {
      await api(`/api/ssh-keys/${deleteId}`, { method: 'DELETE' });
      toast.success('SSH key deleted');
      setDeleteId(null);
      load();
    } catch (e: unknown) {
      toast.error((e as Error).message);
    }
  }

  async function downloadPrivate(id: number) {
    try {
      const res = await fetch(`/api/ssh-keys/${id}/private`, {
        credentials: 'include',
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({ error: 'Failed' }));
        toast.error((err as { error: string }).error);
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const a = document.createElement('a');
      a.href = url;
      a.download = `ssh-key-${id}.key`;
      document.body.appendChild(a);
      a.click();
      document.body.removeChild(a);
      URL.revokeObjectURL(url);
      setDownloading(id);
      toast.success('Private key downloaded');
      setTimeout(() => setDownloading(null), 3000);
    } catch (e: unknown) {
      toast.error((e as Error).message);
    }
  }

  return (
    <div className="space-y-6">
      <PageHeader
        title="SSH Keys"
        description="Manage SSH key pairs for authenticating with remote machines"
        actions={
          <div className="flex items-center gap-2">
            <Button
              variant="secondary"
              size="sm"
              onClick={() => setModal('import')}
            >
              <Upload className="h-4 w-4" />
              Import Public Key
            </Button>
            <Button size="sm" onClick={() => setModal('generate')}>
              <Plus className="h-4 w-4" />
              Generate New
            </Button>
          </div>
        }
      />

      {keys.length === 0 ? (
        <Card>
          <CardBody className="p-0">
            <EmptyState
              icon={<Key className="h-5 w-5" />}
              title="No SSH keys"
              description="Generate a key pair or import a public key to authenticate with remote machines"
              action={
                <div className="flex items-center gap-2">
                  <Button
                    variant="secondary"
                    size="sm"
                    onClick={() => setModal('import')}
                  >
                    <Upload className="h-4 w-4" />
                    Import
                  </Button>
                  <Button size="sm" onClick={() => setModal('generate')}>
                    <Plus className="h-4 w-4" />
                    Generate
                  </Button>
                </div>
              }
            />
          </CardBody>
        </Card>
      ) : (
        <div className="space-y-3">
          {keys.map(k => (
            <Card key={k.id}>
              <CardBody>
                <div className="flex items-start justify-between gap-4">
                  <div className="flex-1 min-w-0">
                    <div className="flex items-center gap-2 mb-2">
                      <h3 className="text-sm font-semibold text-fg truncate">
                        {k.label}
                      </h3>
                      {k.in_use && (
                        <Badge variant="success" label="In Use" />
                      )}
                      {!k.has_private_key && (
                        <Badge variant="neutral" label="Imported Only" />
                      )}
                    </div>
                    <div className="flex items-center gap-1.5 mb-3 text-xs text-fg-subtle">
                      <Fingerprint className="h-3.5 w-3.5" />
                      <span className="font-mono truncate">
                        {k.fingerprint}
                      </span>
                    </div>
                    <div className="bg-canvas-raised rounded-card p-3 font-mono text-xs text-emerald-400/80 break-all max-w-2xl">
                      {k.public_key}
                    </div>
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <CopyButton
                      text={k.public_key}
                      displayText="Copy pub"
                    />
                    {k.has_private_key && (
                      <Button
                        variant="secondary"
                        size="sm"
                        onClick={() => downloadPrivate(k.id)}
                        loading={downloading === k.id}
                      >
                        <Download className="h-3.5 w-3.5" />
                        {downloading === k.id ? 'Done' : 'Private'}
                      </Button>
                    )}
                    <Button
                      variant="danger"
                      size="icon-sm"
                      onClick={() => setDeleteId(k.id)}
                    >
                      <Trash2 className="h-3.5 w-3.5" />
                    </Button>
                  </div>
                </div>
              </CardBody>
            </Card>
          ))}
        </div>
      )}

      <Modal open={modal === 'generate'} onOpenChange={v => !v && setModal(null)}>
        <ModalContent size="md">
          <ModalHeader>
            <ModalTitle>Generate SSH Key Pair</ModalTitle>
            <ModalDescription>
              Generate a new Ed25519 key pair. The private key will be
              downloaded immediately and the public key stored on the server.
            </ModalDescription>
          </ModalHeader>
          <ModalBody className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="gen-label" required>
                Label
              </Label>
              <Input
                id="gen-label"
                placeholder="backup-nas"
                value={genLabel}
                onChange={e => setGenLabel(e.target.value)}
              />
            </div>
          </ModalBody>
          <ModalFooter>
            <Button variant="secondary" onClick={() => setModal(null)}>
              Cancel
            </Button>
            <Button onClick={generate} loading={loading}>
              <Key className="h-4 w-4" />
              Generate
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>

      <Modal open={modal === 'import'} onOpenChange={v => !v && setModal(null)}>
        <ModalContent size="md">
          <ModalHeader>
            <ModalTitle>Import Public Key</ModalTitle>
            <ModalDescription>
              Import an existing public key. Only the public key will be stored
              — you must have the corresponding private key on this server.
            </ModalDescription>
          </ModalHeader>
          <ModalBody className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="import-label" required>
                Label
              </Label>
              <Input
                id="import-label"
                placeholder="work-server"
                value={importLabel}
                onChange={e => setImportLabel(e.target.value)}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="import-pubkey" required>
                Public Key
              </Label>
              <Textarea
                id="import-pubkey"
                placeholder="ssh-ed25519 AAAA..."
                value={importPubKey}
                onChange={e => setImportPubKey(e.target.value)}
                className="font-mono text-xs h-24"
              />
            </div>
          </ModalBody>
          <ModalFooter>
            <Button variant="secondary" onClick={() => setModal(null)}>
              Cancel
            </Button>
            <Button onClick={importKey} loading={loading}>
              <Upload className="h-4 w-4" />
              Import
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>

      <Modal open={deleteId !== null} onOpenChange={v => !v && setDeleteId(null)}>
        <ModalContent size="sm">
          <ModalHeader>
            <ModalTitle>Delete SSH Key</ModalTitle>
            <ModalDescription>
              Are you sure you want to delete this SSH key? Machines using it
              will fall back to the server key.
            </ModalDescription>
          </ModalHeader>
          <ModalFooter>
            <Button variant="secondary" onClick={() => setDeleteId(null)}>
              Cancel
            </Button>
            <Button variant="danger-solid" onClick={handleDelete}>
              Delete
            </Button>
          </ModalFooter>
        </ModalContent>
      </Modal>
    </div>
  );
}
