import { useCallback, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { exportDeviceBackup } from '../lib/deviceBackup';
import { AlertIcon, CopyIcon, LockIcon, ShieldIcon, SpinnerIcon, XIcon } from './icons';

interface Props {
  open: boolean;
  userId: string;
  deviceId: string;
  privateKey: Uint8Array;
  onClose: () => void;
}

// Exports the device's private key + identity into a passphrase-protected
// portable string. The user can store this string anywhere (password manager,
// printed paper, encrypted file on a USB stick). Without it, losing local
// storage on this install means losing all past conversation keys.
export function BackupExportDialog({ open, userId, deviceId, privateKey, onClose }: Props) {
  const { t } = useTranslation(['app']);
  const [passphrase, setPassphrase] = useState('');
  const [confirm, setConfirm] = useState('');
  const [busy, setBusy] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [backup, setBackup] = useState<string | null>(null);
  const [copied, setCopied] = useState(false);

  const canGenerate = useMemo(() => {
    return passphrase.length >= 8 && passphrase === confirm && !busy;
  }, [passphrase, confirm, busy]);

  const reset = useCallback(() => {
    setPassphrase('');
    setConfirm('');
    setBackup(null);
    setError(null);
    setCopied(false);
  }, []);

  const handleClose = useCallback(() => {
    reset();
    onClose();
  }, [reset, onClose]);

  const handleGenerate = useCallback(async () => {
    if (!canGenerate) return;
    setBusy(true);
    setError(null);
    try {
      const str = await exportDeviceBackup({ userId, deviceId, privateKey, passphrase });
      setBackup(str);
    } catch (err: unknown) {
      setError(err instanceof Error ? err.message : String(err));
    } finally {
      setBusy(false);
    }
  }, [canGenerate, userId, deviceId, privateKey, passphrase]);

  const handleCopy = useCallback(async () => {
    if (!backup) return;
    try {
      await navigator.clipboard.writeText(backup);
      setCopied(true);
      window.setTimeout(() => setCopied(false), 1500);
    } catch {
      /* fall back — user can select manually */
    }
  }, [backup]);

  const handleDownload = useCallback(() => {
    if (!backup) return;
    const blob = new Blob([backup], { type: 'text/plain;charset=utf-8' });
    const url = URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = `chatapp-device-backup-${deviceId.slice(0, 8)}.txt`;
    a.click();
    URL.revokeObjectURL(url);
  }, [backup, deviceId]);

  if (!open) return null;

  return (
    <div
      role="dialog"
      aria-modal="true"
      aria-label={t('app:backup.export_title', { defaultValue: 'Gerätesicherung erstellen' })}
      className="fixed inset-0 z-50 flex items-center justify-center bg-black/50 p-4"
      onClick={handleClose}
    >
      <div
        onClick={(e) => e.stopPropagation()}
        className="flex max-h-[90vh] w-full max-w-lg flex-col overflow-hidden rounded-2xl border border-line bg-surface-3 shadow-xl"
      >
        <header className="flex items-center justify-between border-b border-line px-5 py-3">
          <div className="flex items-center gap-2">
            <ShieldIcon className="h-4 w-4 text-accent" />
            <h3 className="font-display text-sm font-semibold text-fg">
              {t('app:backup.export_title', { defaultValue: 'Gerätesicherung erstellen' })}
            </h3>
          </div>
          <button
            type="button"
            onClick={handleClose}
            aria-label="Close"
            className="flex h-8 w-8 cursor-pointer items-center justify-center rounded-lg text-fg-muted transition hover:bg-surface-2 hover:text-fg"
          >
            <XIcon className="h-4 w-4" />
          </button>
        </header>

        <div className="flex-1 overflow-y-auto p-5">
          {!backup ? (
            <>
              <p className="text-sm text-fg-muted">
                {t('app:backup.export_explainer', {
                  defaultValue:
                    'Verschlüssele den Geräteschlüssel mit einer Passphrase. Ohne Passphrase UND Backup-String ist keine Wiederherstellung möglich.',
                })}
              </p>

              <div className="mt-4 space-y-3">
                <div className="space-y-1">
                  <label className="block text-xs font-medium uppercase tracking-wide text-fg-muted">
                    {t('app:backup.passphrase', { defaultValue: 'Passphrase' })}
                  </label>
                  <input
                    type="password"
                    autoFocus
                    minLength={8}
                    value={passphrase}
                    onChange={(e) => setPassphrase(e.target.value)}
                    placeholder="min. 8 Zeichen"
                    className="w-full rounded-lg border border-line bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder-fg-muted transition focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/30"
                  />
                </div>
                <div className="space-y-1">
                  <label className="block text-xs font-medium uppercase tracking-wide text-fg-muted">
                    {t('app:backup.passphrase_confirm', { defaultValue: 'Passphrase wiederholen' })}
                  </label>
                  <input
                    type="password"
                    value={confirm}
                    onChange={(e) => setConfirm(e.target.value)}
                    className="w-full rounded-lg border border-line bg-surface-2 px-3 py-2.5 text-sm text-fg placeholder-fg-muted transition focus:border-accent focus:outline-none focus:ring-2 focus:ring-accent/30"
                  />
                </div>
                {confirm.length > 0 && confirm !== passphrase && (
                  <p className="text-xs text-rose-500 dark:text-rose-300">
                    {t('app:backup.passphrase_mismatch', { defaultValue: 'Passphrasen stimmen nicht überein.' })}
                  </p>
                )}
              </div>

              <div className="mt-4 rounded-lg border border-amber-500/30 bg-amber-500/10 p-3 text-xs text-amber-700 dark:text-amber-200">
                <div className="flex items-start gap-2">
                  <AlertIcon className="mt-0.5 h-4 w-4 shrink-0 text-amber-600 dark:text-amber-300" />
                  <span>
                    {t('app:backup.export_warning', {
                      defaultValue:
                        'Anthropic: Backup + Passphrase sicher aufbewahren. Passphrase kann nicht wiederhergestellt werden.',
                    })}
                  </span>
                </div>
              </div>

              {error && (
                <p role="alert" className="mt-3 text-sm text-rose-600 dark:text-rose-200">
                  {error}
                </p>
              )}
            </>
          ) : (
            <>
              <div className="rounded-lg border border-emerald-500/30 bg-emerald-500/10 p-3 text-xs text-emerald-700 dark:text-emerald-200">
                <div className="flex items-start gap-2">
                  <LockIcon className="mt-0.5 h-4 w-4 shrink-0" />
                  <span>
                    {t('app:backup.export_success', {
                      defaultValue:
                        'Backup erstellt. Speichere diesen String + Passphrase in einem Passwortmanager oder drucke ihn aus.',
                    })}
                  </span>
                </div>
              </div>
              <textarea
                readOnly
                value={backup}
                rows={8}
                onFocus={(e) => e.currentTarget.select()}
                className="mt-3 w-full resize-none rounded-lg border border-line bg-surface-2 p-3 font-mono text-[11px] leading-relaxed text-fg"
              />
              <div className="mt-3 flex gap-2">
                <button
                  type="button"
                  onClick={() => void handleCopy()}
                  className="inline-flex flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-lg border border-line bg-surface-2 px-3 py-2 text-sm font-medium text-fg transition hover:bg-surface-3"
                >
                  <CopyIcon className="h-4 w-4" />
                  <span>
                    {copied
                      ? t('app:backup.copied', { defaultValue: 'Kopiert!' })
                      : t('app:backup.copy', { defaultValue: 'Kopieren' })}
                  </span>
                </button>
                <button
                  type="button"
                  onClick={handleDownload}
                  className="inline-flex flex-1 cursor-pointer items-center justify-center gap-1.5 rounded-lg border border-line bg-surface-2 px-3 py-2 text-sm font-medium text-fg transition hover:bg-surface-3"
                >
                  {t('app:backup.download', { defaultValue: 'Als Datei speichern' })}
                </button>
              </div>
            </>
          )}
        </div>

        <footer className="flex items-center justify-end gap-2 border-t border-line bg-surface-2 px-5 py-3">
          {!backup ? (
            <>
              <button
                type="button"
                onClick={handleClose}
                className="cursor-pointer rounded-md border border-line bg-surface-3 px-3 py-2 text-sm text-fg transition hover:bg-surface-2"
              >
                {t('app:friends.action_cancel', { defaultValue: 'Abbrechen' })}
              </button>
              <button
                type="button"
                onClick={() => void handleGenerate()}
                disabled={!canGenerate}
                className="inline-flex cursor-pointer items-center gap-1.5 rounded-md bg-accent px-3 py-2 text-sm font-semibold text-accent-fg transition hover:brightness-110 disabled:cursor-not-allowed disabled:opacity-60"
              >
                {busy && <SpinnerIcon className="h-4 w-4" />}
                <span>{t('app:backup.generate', { defaultValue: 'Backup erstellen' })}</span>
              </button>
            </>
          ) : (
            <button
              type="button"
              onClick={handleClose}
              className="cursor-pointer rounded-md bg-accent px-3 py-2 text-sm font-semibold text-accent-fg transition hover:brightness-110"
            >
              {t('app:backup.done', { defaultValue: 'Fertig' })}
            </button>
          )}
        </footer>
      </div>
    </div>
  );
}
