'use client';

import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { AlertTriangle, Loader2, Mail } from 'lucide-react';
import { toast } from 'sonner';

import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { WarningCallout } from '@/components/ui/warning-callout';
import { apiFetch } from '@/lib/api/client';
import { toastError } from '@/lib/api/toast-error';

interface Props {
  open: boolean;
  onOpenChange: (open: boolean) => void;
  clientId: string;
  clientName: string;
  /** Called after successful delete, e.g. to navigate away. */
  onDeleted?: () => void;
}

type Stage = 'intent' | 'confirm';

/**
 * Outer wrapper keeps the Dialog mounted (so its close animation runs);
 * the body only mounts when `open` is true and remounts on each
 * open via the `clientId` key. This avoids the open→reset-state
 * useEffect that React Compiler flags - fresh state per open is just
 * the natural mount.
 */
export function HardDeleteDialog(props: Props) {
  return (
    <Dialog open={props.open} onOpenChange={props.onOpenChange}>
      <DialogContent className="sm:max-w-md">
        {props.open && <HardDeleteDialogBody key={props.clientId} {...props} />}
      </DialogContent>
    </Dialog>
  );
}

function HardDeleteDialogBody({ onOpenChange, clientId, clientName, onDeleted }: Props) {
  const qc = useQueryClient();
  const [stage, setStage] = useState<Stage>('intent');
  const [code, setCode] = useState('');
  const [typedName, setTypedName] = useState('');
  const [maskedEmail, setMaskedEmail] = useState<string | null>(null);

  const requestCode = useMutation({
    mutationFn: () =>
      apiFetch<{ data: { sentToMaskedEmail: string } }>(
        `/api/v1/clients/${clientId}/hard-delete-request`,
        { method: 'POST' },
      ),
    onSuccess: (res) => {
      setMaskedEmail(res.data.sentToMaskedEmail);
      setStage('confirm');
      toast.success(`Code sent to ${res.data.sentToMaskedEmail}`);
    },
    onError: (err: unknown) => {
      toastError(err, 'Failed to send code');
    },
  });

  const hardDelete = useMutation({
    mutationFn: () =>
      apiFetch<{ data: { deletedClientId: string } }>(`/api/v1/clients/${clientId}/hard-delete`, {
        method: 'POST',
        body: { code, typedName },
      }),
    onSuccess: () => {
      toast.success(`${clientName} permanently deleted.`);
      qc.invalidateQueries({ queryKey: ['clients'] });
      onOpenChange(false);
      onDeleted?.();
    },
    onError: (err: unknown) => {
      toastError(err, 'Delete failed');
    },
  });

  const nameMatches = typedName.trim().toLowerCase() === clientName.trim().toLowerCase();
  const codeValid = /^\d{4}$/.test(code.trim());

  return (
    <>
      <DialogHeader>
        <DialogTitle className="flex items-center gap-2 text-destructive">
          <AlertTriangle className="h-5 w-5" aria-hidden />
          Permanently delete {clientName}
        </DialogTitle>
        <DialogDescription>
          This permanently removes the client record and detaches all related history (signed
          documents, emails, files). It cannot be undone.
        </DialogDescription>
      </DialogHeader>

      {stage === 'intent' ? (
        <div className="space-y-3 text-sm">
          <p className="text-muted-foreground">
            Permanent deletion is reserved for archived clients only. We&rsquo;ll email a 4-digit
            confirmation code to your account address. The code expires in 10 minutes.
          </p>
          <WarningCallout title="What gets deleted">
            <ul className="mt-1.5 list-disc pl-5 text-xs space-y-0.5">
              <li>Client record + addresses, contacts, notes, tags</li>
              <li>Portal user account + GDPR consent records</li>
              <li>All pipeline interests + tenancies for this client</li>
            </ul>
            <p className="font-medium mt-2">What is preserved</p>
            <ul className="mt-1.5 list-disc pl-5 text-xs space-y-0.5">
              <li>Signed documents (detached from client, kept for legal history)</li>
              <li>Email threads, files, reminders (detached)</li>
              <li>Audit log entries</li>
            </ul>
          </WarningCallout>
        </div>
      ) : (
        <div className="space-y-3">
          <div className="flex items-start gap-2 rounded-md border border-blue-300 bg-blue-50 p-3 text-xs text-blue-900">
            <Mail className="h-4 w-4 shrink-0 mt-0.5" aria-hidden />
            <div className="flex-1">
              <div>
                Code sent to <span className="font-mono">{maskedEmail}</span>. It expires in 10
                minutes.
              </div>
              <button
                type="button"
                onClick={() => {
                  setCode('');
                  requestCode.mutate();
                }}
                disabled={requestCode.isPending}
                className="mt-1 text-blue-700 underline-offset-2 hover:underline disabled:opacity-60"
              >
                {requestCode.isPending ? 'Sending…' : 'Send a new code'}
              </button>
            </div>
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="hd-code">4-digit code from email</Label>
            <Input
              id="hd-code"
              inputMode="numeric"
              maxLength={4}
              value={code}
              onChange={(e) => setCode(e.target.value.replace(/\D/g, ''))}
              placeholder="0000"
              className="font-mono tracking-[0.4em] text-center text-lg"
              autoComplete="off"
            />
          </div>
          <div className="space-y-1.5">
            <Label htmlFor="hd-name">
              Type <span className="font-semibold">{clientName}</span> to confirm
            </Label>
            <Input
              id="hd-name"
              value={typedName}
              onChange={(e) => setTypedName(e.target.value)}
              placeholder={clientName}
              autoComplete="off"
            />
          </div>
        </div>
      )}

      <DialogFooter>
        <Button variant="outline" onClick={() => onOpenChange(false)}>
          Cancel
        </Button>
        {stage === 'intent' ? (
          <Button
            variant="destructive"
            onClick={() => requestCode.mutate()}
            disabled={requestCode.isPending}
          >
            {requestCode.isPending ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin mr-1.5" aria-hidden /> Sending…
              </>
            ) : (
              'Send confirmation code'
            )}
          </Button>
        ) : (
          <Button
            variant="destructive"
            onClick={() => hardDelete.mutate()}
            disabled={!codeValid || !nameMatches || hardDelete.isPending}
          >
            {hardDelete.isPending ? (
              <>
                <Loader2 className="h-4 w-4 animate-spin mr-1.5" aria-hidden /> Deleting…
              </>
            ) : (
              'Permanently delete'
            )}
          </Button>
        )}
      </DialogFooter>
    </>
  );
}
