import { useState } from 'react';
import { Download, Copy, Eye, EyeOff, Shield, AlertTriangle, CheckCircle, ExternalLink, KeyRound, QrCode } from 'lucide-react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
import { Button } from '@/components/ui/button';
import { Alert, AlertDescription } from '@/components/ui/alert';
import { QRCodeCanvas } from '@/components/ui/qrcode';
import { useCurrentUser } from '@/hooks/useCurrentUser';
import { useLocalStorage } from '@/hooks/useLocalStorage';
import { useNostrLogin } from '@nostrify/react/login';
import { toast } from '@/hooks/useToast';
import { useTranslation } from '@/contexts/language';
const sanitizeFilename = (filename: string) => filename.replace(/[^a-z0-9_.-]/gi, '_');
export function SecuritySettings() {
const { user } = useCurrentUser();
const { logins } = useNostrLogin();
const { t } = useTranslation();
const [confirmed, setConfirmed] = useLocalStorage('backup-confirmed', false);
const [showWarning, setShowWarning] = useState(!confirmed);
// Recovery reveal state
const [revealed, setRevealed] = useState(false);
const [showQr, setShowQr] = useState(false);
// The active login. For nsec logins, the recovery code (nsec) is stored on
// the login object itself — this is how we can reveal it later for users who
// skipped backup at signup. For bunker/extension/Amber logins, the app never
// held the key, so there is nothing to reveal here.
const activeLogin = logins[0] as
| (typeof logins[number] & { nsec?: string; data?: { nsec?: string } })
| undefined;
const loginType = activeLogin?.type;
// Nostrify stores the bech32 nsec directly on the login (older builds nested
// it under `data`), so check both to be safe.
const recoveryCode = loginType === 'nsec'
? (activeLogin?.nsec ?? activeLogin?.data?.nsec)
: undefined;
const handleReveal = () => setRevealed(true);
const handleCopyRecovery = () => {
if (!recoveryCode) return;
navigator.clipboard.writeText(recoveryCode);
// Copying the recovery code counts as a real backup — mark confirmed so the
// gentle reminder stops nagging a user who has genuinely saved their login.
setConfirmed(true);
setShowWarning(false);
toast({ title: t('common.copied'), description: t('settingsUi.security.recoveryCopied') });
};
const handleDownloadRecovery = () => {
if (!recoveryCode) return;
try {
const blob = new Blob([recoveryCode], { type: 'text/plain; charset=utf-8' });
const url = globalThis.URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = sanitizeFilename('skatespots-recovery-code.txt');
a.style.display = 'none';
document.body.appendChild(a);
a.click();
globalThis.URL.revokeObjectURL(url);
document.body.removeChild(a);
// A downloaded recovery file is a genuine backup — mark confirmed so the
// reminder stops for good.
setConfirmed(true);
setShowWarning(false);
toast({ title: t('settingsUi.security.savedTitle'), description: t('settingsUi.security.recoveryDownloaded') });
} catch {
toast({ title: t('settingsUi.security.downloadFailedTitle'), description: t('settingsUi.security.downloadFailedDesc'), variant: 'destructive' });
}
};
if (!user) {
return (
{t('settingsUi.security.loginRequiredDesc')}
{t('settingsUi.security.loginRequired')}
{t('settingsUi.security.recoveryCodeBefore')}{' '} {t('settingsUi.security.only')}{' '} {t('settingsUi.security.recoveryCodeAfter')}
{!revealed ? ( ) : ({t('settingsUi.security.qrHint')}
{t('settingsUi.security.neverShareHide')}
{t('settingsUi.security.backupWarningTitle')}
{t('settingsUi.security.backupWarningBody')}
{t('settingsUi.security.notSavedYetBefore')} {t('settingsUi.security.yourRecoveryCode')} {t('settingsUi.security.notSavedYetAfter')}
{t('settingsUi.security.bp1Title')}
{t('settingsUi.security.bp1Desc')}
{t('settingsUi.security.bp2Title')}
{t('settingsUi.security.bp2Desc')}
{t('settingsUi.security.bp3Title')}
{t('settingsUi.security.bp3Desc')}
{t('settingsUi.security.bp4Title')}
{t('settingsUi.security.bp4Desc')}
{t('settingsUi.security.bp5Title')}
{t('settingsUi.security.bp5Desc')}
{t('settingsUi.security.nostrConnectBody')}
{t('settingsUi.security.nsecAppDesc')}
{t('settingsUi.security.nostrumDesc')}
{t('settingsUi.security.howToUse')} {t('settingsUi.security.howToUseDesc')}