import { useState } from 'react';
import { Loader2 } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { useLockActions } from '../useWalletData';

// Re-encrypt the seed under a new passphrase. The sidecar decrypts with the old one and re-seals with the
// new one, then re-locks — there is no window where the wallet is left open as a side effect.
//
// Both passphrases live only in this component's state and are cleared as soon as the request settles.

type ChangePassphraseDialogProps = { open: boolean; onOpenChange: (open: boolean) => void; walletId: number };

export const ChangePassphraseDialog = ({ open, onOpenChange, walletId }: ChangePassphraseDialogProps) => {
  const { changePassphrase } = useLockActions(walletId);
  // Never persisted: no localStorage, no sessionStorage, no React Query cache, no URL.
  const [oldPassphrase, setOldPassphrase] = useState('');
  const [newPassphrase, setNewPassphrase] = useState('');
  const [confirm, setConfirm] = useState('');

  const clearSecrets = () => {
    setOldPassphrase('');
    setNewPassphrase('');
    setConfirm('');
  };

  const close = () => {
    clearSecrets();
    onOpenChange(false);
  };

  const mismatch = confirm.length > 0 && confirm !== newPassphrase;
  const canSubmit =
    !!oldPassphrase && newPassphrase.length >= 8 && confirm === newPassphrase && !changePassphrase.isPending;

  const submit = async (ev: React.FormEvent) => {
    ev.preventDefault();
    if (!canSubmit) return;
    try {
      await changePassphrase.mutateAsync({ oldPassphrase, newPassphrase });
      close();
    } finally {
      // Cleared on failure too — a rejected passphrase is still a passphrase held in memory.
      clearSecrets();
    }
  };

  return (
    <Dialog open={open} onOpenChange={(next) => (next ? onOpenChange(true) : close())}>
      <DialogContent className="max-w-md">
        <form onSubmit={submit}>
          <DialogHeader>
            <DialogTitle>Change passphrase</DialogTitle>
            <DialogDescription>
              The seed is re-sealed under the new passphrase and the wallet is locked again. Lose it and the coins go
              with it — there is no reset.
            </DialogDescription>
          </DialogHeader>

          <div className="mt-4 space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="wallet-pass-old">Current passphrase</Label>
              {/* Controlled input → request body → cleared. Never written to any store. */}
              <Input
                id="wallet-pass-old"
                type="password"
                autoFocus
                autoComplete="off"
                value={oldPassphrase}
                onChange={(ev) => setOldPassphrase(ev.target.value)}
              />
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="wallet-pass-new">New passphrase</Label>
              {/* Controlled input → request body → cleared. Never written to any store. */}
              <Input
                id="wallet-pass-new"
                type="password"
                autoComplete="new-password"
                value={newPassphrase}
                onChange={(ev) => setNewPassphrase(ev.target.value)}
              />
              <p className="text-[11px] text-muted-foreground">At least 8 characters.</p>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="wallet-pass-confirm">Confirm new passphrase</Label>
              {/* Controlled input → request body → cleared. Never written to any store. */}
              <Input
                id="wallet-pass-confirm"
                type="password"
                autoComplete="new-password"
                value={confirm}
                onChange={(ev) => setConfirm(ev.target.value)}
              />
              {mismatch && <p className="text-[11px] text-destructive">These do not match.</p>}
            </div>
          </div>

          <DialogFooter className="mt-6">
            <Button type="button" variant="ghost" onClick={close}>
              Cancel
            </Button>
            <Button type="submit" disabled={!canSubmit}>
              {changePassphrase.isPending && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
              Change
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
};
