import { useState } from 'react';
import { useLogto } from '@logto/react';
import { errorMessage } from '../../api/client';
import {
  Alert,
  Button,
  Card,
  FormField,
  Input,
  Modal,
  useToast,
} from '@cameleer/design-system';
import {
  useAccountMfaStatus,
  useAccountPasskeyList,
  useAccountRenamePasskey,
  useAccountDeletePasskey,
} from '../../api/account-hooks';
import { registerPasskey } from '../../api/logto-account-api';
import styles from '../../styles/platform.module.css';

export function PasskeyNudgeBanner() {
  const { data: status } = useAccountMfaStatus();
  const [dismissed, setDismissed] = useState(false);

  const lastDismissed = localStorage.getItem('passkey_nudge_dismissed');
  const recentlyDismissed = lastDismissed && (Date.now() - Number(lastDismissed)) < 30 * 24 * 60 * 60 * 1000;

  if (dismissed || recentlyDismissed || !status || status.passkeyEnrolled) return null;

  function handleDismiss() {
    localStorage.setItem('passkey_nudge_dismissed', String(Date.now()));
    setDismissed(true);
  }

  return (
    <Alert variant="info" title="Sign in faster with a passkey">
      <p style={{ margin: '4px 0 12px' }}>
        Use your fingerprint, face, or security key instead of typing a code every time.
      </p>
      <Button size="sm" variant="secondary" onClick={handleDismiss}>Not now</Button>
    </Alert>
  );
}

export function PasskeySection() {
  const { toast } = useToast();
  const { getAccessToken } = useLogto();
  const { data: passkeys, isLoading, refetch } = useAccountPasskeyList();
  const renamePasskey = useAccountRenamePasskey();
  const deletePasskey = useAccountDeletePasskey();
  const [editingId, setEditingId] = useState<string | null>(null);
  const [editName, setEditName] = useState('');
  const [confirmDeleteId, setConfirmDeleteId] = useState<string | null>(null);
  const [registering, setRegistering] = useState(false);
  const [showPasswordModal, setShowPasswordModal] = useState(false);
  const [regPassword, setRegPassword] = useState('');
  const [regError, setRegError] = useState<string | null>(null);

  function parseAgent(agent: string | null): string {
    if (!agent) return 'Unknown device';
    if (agent.includes('Chrome')) return agent.includes('Windows') ? 'Chrome on Windows' : agent.includes('Mac') ? 'Chrome on macOS' : agent.includes('Android') ? 'Chrome on Android' : 'Chrome';
    if (agent.includes('Safari') && !agent.includes('Chrome')) return agent.includes('iPhone') ? 'Safari on iPhone' : 'Safari on macOS';
    if (agent.includes('Firefox')) return 'Firefox';
    if (agent.includes('Edge')) return 'Edge';
    return 'Browser';
  }

  function startRename(id: string, currentName: string | null) {
    setEditingId(id);
    setEditName(currentName ?? '');
  }

  async function handleRename(id: string) {
    try {
      await renamePasskey.mutateAsync({ id, name: editName });
      setEditingId(null);
      toast({ title: 'Passkey renamed', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to rename passkey', description: errorMessage(err), variant: 'error' });
    }
  }

  function openRegister() {
    setRegPassword('');
    setRegError(null);
    setShowPasswordModal(true);
  }

  async function handleRegister(e: React.FormEvent) {
    e.preventDefault();
    setRegError(null);
    setRegistering(true);
    try {
      await registerPasskey(async () => {
        const token = await getAccessToken();
        if (!token) throw new Error('Not authenticated');
        return token;
      }, regPassword);
      setShowPasswordModal(false);
      await refetch();
      toast({ title: 'Passkey registered', variant: 'success' });
    } catch (err) {
      // User cancelled the WebAuthn prompt — not an error
      if (err instanceof Error && err.name === 'NotAllowedError') {
        setRegistering(false);
        return;
      }
      setRegError(errorMessage(err));
    } finally {
      setRegistering(false);
    }
  }

  async function handleDelete(id: string) {
    try {
      await deletePasskey.mutateAsync(id);
      setConfirmDeleteId(null);
      toast({ title: 'Passkey removed', variant: 'success' });
    } catch (err) {
      toast({ title: 'Failed to remove passkey', description: errorMessage(err), variant: 'error' });
    }
  }

  if (isLoading) return null;
  const credentials = passkeys ?? [];

  return (
    <>
    <Card title="Passkeys">
      <p className={styles.description} style={{ marginTop: 0 }}>
        Use your fingerprint, face, or security key to sign in faster.
      </p>
      <div style={{ marginBottom: 12 }}>
        <Button variant="primary" onClick={openRegister}>
          Register passkey
        </Button>
      </div>
      {credentials.length === 0 ? (
        <p style={{ color: 'var(--text-muted)', fontSize: '0.875rem' }}>
          No passkeys registered yet.
        </p>
      ) : (
        <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
          {credentials.map((pk) => (
            <div key={pk.id} style={{ display: 'flex', alignItems: 'center', gap: 12, padding: '8px 0', borderBottom: '1px solid var(--border)' }}>
              <div style={{ flex: 1 }}>
                {editingId === pk.id ? (
                  <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
                    <Input value={editName} onChange={(e) => setEditName(e.target.value)} placeholder="Passkey name" style={{ maxWidth: 200 }} />
                    <Button size="sm" variant="primary" onClick={() => handleRename(pk.id)} loading={renamePasskey.isPending}>Save</Button>
                    <Button size="sm" variant="secondary" onClick={() => setEditingId(null)}>Cancel</Button>
                  </div>
                ) : (
                  <>
                    <div style={{ fontWeight: 500 }}>{pk.name || 'Unnamed passkey'}</div>
                    <div style={{ fontSize: '0.75rem', color: 'var(--text-muted)' }}>
                      {parseAgent(pk.agent)} &middot; Added {pk.createdAt ? new Date(pk.createdAt).toLocaleDateString() : 'unknown'}
                    </div>
                  </>
                )}
              </div>
              {editingId !== pk.id && (
                <div style={{ display: 'flex', gap: 8 }}>
                  <Button size="sm" variant="secondary" onClick={() => startRename(pk.id, pk.name)}>Rename</Button>
                  {confirmDeleteId === pk.id ? (
                    <>
                      <Button size="sm" variant="danger" onClick={() => handleDelete(pk.id)} loading={deletePasskey.isPending}>Confirm</Button>
                      <Button size="sm" variant="secondary" onClick={() => setConfirmDeleteId(null)}>Cancel</Button>
                    </>
                  ) : (
                    <Button size="sm" variant="danger" onClick={() => setConfirmDeleteId(pk.id)}>Remove</Button>
                  )}
                </div>
              )}
            </div>
          ))}
        </div>
      )}
    </Card>

    <Modal
      open={showPasswordModal}
      onClose={() => { if (!registering) setShowPasswordModal(false); }}
      title="Confirm identity"
      size="sm"
    >
      <p className={styles.description} style={{ marginTop: 0 }}>
        Enter your password to register a new passkey.
      </p>
      {regError && <Alert variant="error">{regError}</Alert>}
      <form onSubmit={handleRegister} style={{ display: 'flex', flexDirection: 'column', gap: 16 }}>
        <FormField label="Password" htmlFor="passkey-reg-password">
          <Input
            id="passkey-reg-password"
            type="password"
            value={regPassword}
            onChange={(e) => setRegPassword(e.target.value)}
            placeholder="Enter your password"
            autoFocus
            autoComplete="current-password"
          />
        </FormField>
        <div style={{ display: 'flex', gap: 8 }}>
          <Button type="submit" variant="primary" loading={registering} disabled={!regPassword}>
            Continue
          </Button>
          <Button type="button" variant="secondary" onClick={() => setShowPasswordModal(false)} disabled={registering}>
            Cancel
          </Button>
        </div>
      </form>
    </Modal>
    </>
  );
}
