import * as React from 'react';
import { Loader2 } from 'lucide-react';
import { cn } from '@/lib/utils';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogFooter,
  DialogTitle,
  DialogDescription,
} from '@/components/ui/dialog';
import { Button } from '@/components/ui/button';

/* ── ConfirmDialog ──────────────────────────────────────────────
   Reusable confirmation dialog that replaces window.confirm.

   Props:
     open          boolean
     onOpenChange  (open: boolean) => void
     title         string
     description   string | ReactNode
     confirmLabel  string  (default: 'Confirm')
     cancelLabel   string  (default: 'Cancel')
     variant       'default' | 'destructive'
     onConfirm     () => void | Promise<void>
     loading       boolean
   ─────────────────────────────────────────────────────────────── */

export function ConfirmDialog({
  open,
  onOpenChange,
  title,
  description,
  confirmLabel = 'Confirm',
  cancelLabel = 'Cancel',
  variant = 'default',
  onConfirm,
  loading = false,
}) {
  const handleConfirm = async () => {
    await onConfirm?.();
  };

  const handleCancel = () => {
    if (!loading) onOpenChange(false);
  };

  return (
    <Dialog open={open} onOpenChange={loading ? undefined : onOpenChange}>
      <DialogContent className="sm:max-w-[400px]">
        <DialogHeader>
          <DialogTitle>{title}</DialogTitle>
          {description && (
            <DialogDescription>{description}</DialogDescription>
          )}
        </DialogHeader>

        <DialogFooter className="gap-2 sm:gap-0">
          <Button
            variant="outline"
            onClick={handleCancel}
            disabled={loading}
          >
            {cancelLabel}
          </Button>

          <Button
            variant={variant === 'destructive' ? 'destructive' : 'default'}
            onClick={handleConfirm}
            disabled={loading}
            className={cn(loading && 'cursor-not-allowed')}
          >
            {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            {confirmLabel}
          </Button>
        </DialogFooter>
      </DialogContent>
    </Dialog>
  );
}

/* ── useConfirm hook ────────────────────────────────────────────
   Imperative API for ConfirmDialog.

   Usage:
     const { confirm, ConfirmDialogComponent } = useConfirm();
     // ...
     const ok = await confirm({ title, description, confirmLabel, variant });
     // Returns true if confirmed, false if cancelled.
     // Render <ConfirmDialogComponent /> anywhere in the tree.
   ─────────────────────────────────────────────────────────────── */

export function useConfirm() {
  const [state, setState] = React.useState({
    open: false,
    title: '',
    description: '',
    confirmLabel: 'Confirm',
    cancelLabel: 'Cancel',
    variant: 'default',
    loading: false,
  });

  // Keep a stable ref to the resolve callback so it survives re-renders
  const resolveRef = React.useRef(null);

  const confirm = React.useCallback(
    ({
      title = 'Are you sure?',
      description = '',
      confirmLabel = 'Confirm',
      cancelLabel = 'Cancel',
      variant = 'default',
    } = {}) => {
      return new Promise((resolve) => {
        resolveRef.current = resolve;
        setState({
          open: true,
          title,
          description,
          confirmLabel,
          cancelLabel,
          variant,
          loading: false,
        });
      });
    },
    []
  );

  const handleConfirm = React.useCallback(async () => {
    setState((s) => ({ ...s, loading: true }));
    resolveRef.current?.(true);
    resolveRef.current = null;
    setState((s) => ({ ...s, open: false, loading: false }));
  }, []);

  const handleOpenChange = React.useCallback((open) => {
    if (!open) {
      resolveRef.current?.(false);
      resolveRef.current = null;
      setState((s) => ({ ...s, open: false }));
    }
  }, []);

  const ConfirmDialogComponent = React.useCallback(
    () => (
      <ConfirmDialog
        open={state.open}
        onOpenChange={handleOpenChange}
        title={state.title}
        description={state.description}
        confirmLabel={state.confirmLabel}
        cancelLabel={state.cancelLabel}
        variant={state.variant}
        loading={state.loading}
        onConfirm={handleConfirm}
      />
    ),
    // eslint-disable-next-line react-hooks/exhaustive-deps
    [state, handleConfirm, handleOpenChange]
  );

  return { confirm, ConfirmDialogComponent };
}
