import { loadDevicePrivateKey } from '@chat-app/shared/auth';
import { useCallback, useEffect, useState } from 'react';
import { useTranslation } from 'react-i18next';

import { useAuth } from '../context/AuthContext';
import { devLocalSecretStore } from '../lib/secretStore';
import { BackupExportDialog } from './BackupExportDialog';
import { ShieldIcon, XIcon } from './icons';

const DISMISS_KEY = 'chatapp.backup.prompt.dismissed';
const SESSION_KEY = 'chatapp.backup.prompt';

// Post-registration nudge: right after a fresh device provision we set
// `chatapp.backup.prompt` in sessionStorage. This component reads it and
// shows a floating "mach jetzt ein Backup" banner until the user either
// creates one or explicitly dismisses (persisted in localStorage so we stop
// nagging across reloads).
export function BackupPromptBanner() {
  const { t } = useTranslation(['app']);
  const { profile, device } = useAuth();
  const [visible, setVisible] = useState(false);
  const [dialogOpen, setDialogOpen] = useState(false);
  const [privateKey, setPrivateKey] = useState<Uint8Array | null>(null);

  useEffect(() => {
    try {
      if (window.localStorage.getItem(DISMISS_KEY) === '1') return;
      if (window.sessionStorage.getItem(SESSION_KEY) !== '1') return;
      setVisible(true);
    } catch {
      /* storage unavailable */
    }
  }, []);

  const dismiss = useCallback((persist: boolean) => {
    setVisible(false);
    try {
      window.sessionStorage.removeItem(SESSION_KEY);
      if (persist) window.localStorage.setItem(DISMISS_KEY, '1');
    } catch {
      /* ignore */
    }
  }, []);

  const openDialog = useCallback(async () => {
    if (!profile?.userId || !device?.id) return;
    const priv = await loadDevicePrivateKey(devLocalSecretStore, profile.userId, device.id);
    if (!priv) return;
    setPrivateKey(priv);
    setDialogOpen(true);
  }, [profile, device]);

  const closeDialog = useCallback(() => {
    setDialogOpen(false);
    if (privateKey) {
      for (let i = 0; i < privateKey.length; i++) privateKey[i] = 0;
    }
    setPrivateKey(null);
    // After the user interacts with the dialog, drop the banner regardless
    // of whether they actually completed the backup — they're aware now.
    dismiss(true);
  }, [privateKey, dismiss]);

  if (!visible) return null;

  return (
    <>
      <div
        role="status"
        className="fixed bottom-6 left-1/2 z-40 flex w-[min(92vw,520px)] -translate-x-1/2 items-start gap-3 rounded-2xl border border-amber-500/40 bg-amber-500/10 p-4 text-sm text-amber-800 shadow-xl backdrop-blur-md dark:text-amber-100"
      >
        <ShieldIcon className="mt-0.5 h-5 w-5 shrink-0 text-amber-600 dark:text-amber-300" />
        <div className="min-w-0 flex-1">
          <p className="font-semibold">
            {t('app:backup.prompt_title', { defaultValue: 'Erstelle jetzt ein Geräte-Backup' })}
          </p>
          <p className="mt-0.5 text-xs text-amber-700/90 dark:text-amber-200/90">
            {t('app:backup.prompt_body', {
              defaultValue:
                'Ohne Backup verlierst du Zugriff auf alte Nachrichten, wenn Browser oder Gerät ihren Speicher verlieren. Dauert 10 Sekunden.',
            })}
          </p>
          <div className="mt-3 flex flex-wrap gap-2">
            <button
              type="button"
              onClick={() => void openDialog()}
              className="cursor-pointer rounded-md bg-amber-600 px-3 py-1.5 text-xs font-semibold text-white transition hover:bg-amber-500"
            >
              {t('app:backup.prompt_create', { defaultValue: 'Jetzt erstellen' })}
            </button>
            <button
              type="button"
              onClick={() => dismiss(true)}
              className="cursor-pointer rounded-md border border-amber-500/40 bg-transparent px-3 py-1.5 text-xs font-semibold text-amber-700 transition hover:bg-amber-500/15 dark:text-amber-200"
            >
              {t('app:backup.prompt_never', { defaultValue: 'Nicht mehr fragen' })}
            </button>
          </div>
        </div>
        <button
          type="button"
          onClick={() => dismiss(false)}
          aria-label={t('app:backup.prompt_dismiss', { defaultValue: 'Später' })}
          className="cursor-pointer text-amber-600/70 transition hover:text-amber-600 dark:text-amber-200/70 dark:hover:text-amber-200"
        >
          <XIcon className="h-4 w-4" />
        </button>
      </div>

      {dialogOpen && profile?.userId && device?.id && privateKey && (
        <BackupExportDialog
          open={dialogOpen}
          userId={profile.userId}
          deviceId={device.id}
          privateKey={privateKey}
          onClose={closeDialog}
        />
      )}
    </>
  );
}

