import { useRef, useState } from 'react';
import { errorMessage } from '../../api/client';
import {
  Alert,
  Badge,
  Button,
  Card,
  FileInput,
  FormField,
  Input,
  Spinner,
  useToast,
} from '@cameleer/design-system';
import type { FileInputHandle } from '@cameleer/design-system';
import { Upload, ShieldCheck, RotateCcw, Trash2, FileKey, KeyRound, ShieldPlus } from 'lucide-react';
import {
  useVendorCertificates,
  useStageCertificate,
  useActivateCertificate,
  useRestoreCertificate,
  useDiscardStaged,
} from '../../api/certificate-hooks';
import type { CertificateResponse } from '../../api/certificate-hooks';
import styles from '../../styles/platform.module.css';

function formatDate(iso: string | null | undefined): string {
  if (!iso) return '—';
  return new Date(iso).toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' });
}

function daysUntil(iso: string | null | undefined): number {
  if (!iso) return 0;
  return Math.ceil((new Date(iso).getTime() - Date.now()) / 86_400_000);
}

function expiryColor(iso: string | null | undefined): string | undefined {
  const days = daysUntil(iso);
  if (days <= 0) return 'var(--error)';
  if (days <= 30) return 'var(--warning)';
  return undefined;
}

function shortenFingerprint(fp: string | null | undefined): string {
  if (!fp) return '—';
  // Show first 23 chars (8 hex pairs) + ellipsis
  return fp.length > 23 ? fp.slice(0, 23) + '...' : fp;
}

function CertCard({
  cert,
  title,
  actions,
}: {
  cert: CertificateResponse;
  title: string;
  actions?: React.ReactNode;
}) {
  const days = daysUntil(cert.notAfter);
  return (
    <Card title={title}>
      <div className={styles.dividerList}>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>Subject</span>
          <span className={styles.kvValue}>{cert.subject}</span>
        </div>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>Issuer</span>
          <span className={styles.kvValue}>{cert.issuer}</span>
        </div>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>Valid from</span>
          <span className={styles.kvValue}>{formatDate(cert.notBefore)}</span>
        </div>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>Expires</span>
          <span className={styles.kvValue} style={{ color: expiryColor(cert.notAfter) }}>
            {formatDate(cert.notAfter)} ({days}d)
          </span>
        </div>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>Fingerprint</span>
          <span className={styles.kvValueMono} title={cert.fingerprint} style={{ fontSize: '0.7rem' }}>
            {shortenFingerprint(cert.fingerprint)}
          </span>
        </div>
        <div className={styles.kvRow}>
          <span className={styles.kvLabel}>CA bundle</span>
          <span className={styles.kvValue}>{cert.hasCa ? 'Yes' : 'No'}</span>
        </div>
        {cert.selfSigned && (
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Type</span>
            <Badge label="Self-signed" color="warning" />
          </div>
        )}
        {cert.activatedAt && (
          <div className={styles.kvRow}>
            <span className={styles.kvLabel}>Activated</span>
            <span className={styles.kvValue}>{formatDate(cert.activatedAt)}</span>
          </div>
        )}
        {actions && <div style={{ paddingTop: 8, display: 'flex', gap: 8 }}>{actions}</div>}
      </div>
    </Card>
  );
}

export function CertificatesPage() {
  const { toast } = useToast();
  const { data, isLoading, isError } = useVendorCertificates();
  const stageMutation = useStageCertificate();
  const activateMutation = useActivateCertificate();
  const restoreMutation = useRestoreCertificate();
  const discardMutation = useDiscardStaged();

  const certRef = useRef<FileInputHandle>(null);
  const keyRef = useRef<FileInputHandle>(null);
  const caRef = useRef<FileInputHandle>(null);
  const [keyPassword, setKeyPassword] = useState('');

  if (isLoading) {
    return (
      <div style={{ display: 'flex', justifyContent: 'center', padding: 64 }}>
        <Spinner />
      </div>
    );
  }

  if (isError || !data) {
    return (
      <div style={{ padding: 24 }}>
        <Alert variant="error" title="Failed to load certificates">
          Could not fetch certificate data. Please refresh.
        </Alert>
      </div>
    );
  }

  async function handleUpload() {
    const certFile = certRef.current?.file;
    const keyFile = keyRef.current?.file;
    const caFile = caRef.current?.file;

    if (!certFile || !keyFile) {
      toast({ title: 'Certificate and key files are required', variant: 'error' });
      return;
    }

    const formData = new FormData();
    formData.append('cert', certFile);
    formData.append('key', keyFile);
    if (caFile) formData.append('ca', caFile);
    if (keyPassword) formData.append('password', keyPassword);

    try {
      const result = await stageMutation.mutateAsync(formData);
      if (result.valid) {
        toast({ title: 'Certificate staged successfully', variant: 'success' });
        certRef.current?.clear();
        keyRef.current?.clear();
        caRef.current?.clear();
        setKeyPassword('');
      } else {
        toast({ title: 'Validation failed', description: result.errors.join(', '), variant: 'error' });
      }
    } catch (err) {
      toast({ title: 'Upload failed', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleActivate() {
    try {
      await activateMutation.mutateAsync();
      toast({ title: 'Certificate activated', variant: 'success' });
    } catch (err) {
      toast({ title: 'Activation failed', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleRestore() {
    try {
      await restoreMutation.mutateAsync();
      toast({ title: 'Certificate restored from archive', variant: 'success' });
    } catch (err) {
      toast({ title: 'Restore failed', description: errorMessage(err), variant: 'error' });
    }
  }

  async function handleDiscard() {
    try {
      await discardMutation.mutateAsync();
      toast({ title: 'Staged certificate discarded', variant: 'success' });
    } catch (err) {
      toast({ title: 'Discard failed', description: errorMessage(err), variant: 'error' });
    }
  }

  const expired = data.archived
    ? daysUntil(data.archived.notAfter) <= 0
    : false;

  return (
    <div style={{ padding: 24, display: 'flex', flexDirection: 'column', gap: 20 }}>
      <h1 className={styles.heading}>Certificates</h1>

      {data.staleTenantCount > 0 && (
        <Alert variant="warning" title="CA bundle updated">
          {data.staleTenantCount} tenant{data.staleTenantCount > 1 ? 's' : ''} need a restart
          to pick up the updated CA bundle.
        </Alert>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(340px, 1fr))', gap: 16 }}>
        {data.active && (
          <CertCard cert={data.active} title="Active Certificate" />
        )}

        {data.staged && (
          <CertCard
            cert={data.staged}
            title="Staged Certificate"
            actions={
              <>
                <Button
                  variant="primary"
                  onClick={handleActivate}
                  loading={activateMutation.isPending}
                >
                  <ShieldCheck size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                  Activate
                </Button>
                <Button
                  variant="secondary"
                  onClick={handleDiscard}
                  loading={discardMutation.isPending}
                >
                  <Trash2 size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                  Discard
                </Button>
              </>
            }
          />
        )}

        {data.archived && (
          <CertCard
            cert={data.archived}
            title="Previous Certificate"
            actions={
              <Button
                variant="secondary"
                onClick={handleRestore}
                loading={restoreMutation.isPending}
                disabled={expired}
              >
                <RotateCcw size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
                {expired ? 'Expired' : 'Restore'}
              </Button>
            }
          />
        )}

        {/* Upload card */}
        <Card title="Upload Certificate">
          <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
            <FormField label="Certificate (PEM) *">
              <FileInput ref={certRef} accept=".pem,.crt,.cer" icon={<FileKey size={16} />} />
            </FormField>
            <FormField label="Private Key (PEM) *">
              <FileInput ref={keyRef} accept=".pem,.key" icon={<KeyRound size={16} />} />
            </FormField>
            <FormField label="Key Password (if encrypted)">
              <Input
                type="password"
                placeholder="Leave empty if key is not encrypted"
                value={keyPassword}
                onChange={(e) => setKeyPassword(e.target.value)}
              />
            </FormField>
            <FormField label="CA Bundle (PEM, optional)">
              <FileInput ref={caRef} accept=".pem,.crt,.cer" icon={<ShieldPlus size={16} />} />
            </FormField>
            <Button
              variant="primary"
              onClick={handleUpload}
              loading={stageMutation.isPending}
            >
              <Upload size={14} style={{ marginRight: 6, verticalAlign: -2 }} />
              Stage Certificate
            </Button>
          </div>
        </Card>
      </div>
    </div>
  );
}
