'use client';

import { useMemo, useState } from 'react';
import { Check, FolderInput } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import {
  Command,
  CommandEmpty,
  CommandGroup,
  CommandInput,
  CommandItem,
  CommandList,
} from '@/components/ui/command';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import { toastError } from '@/lib/api/toast-error';
import {
  buildFolderPaths,
  useDocumentFolders,
  useMoveDocument,
} from '@/hooks/use-document-folders';

interface MoveToFolderDialogProps {
  documentId: string;
  documentTitle: string;
  currentFolderId: string | null;
  open: boolean;
  onOpenChange: (open: boolean) => void;
}

export function MoveToFolderDialog(props: MoveToFolderDialogProps) {
  // Key-based remount: the inner body is keyed on `open + currentFolderId`
  // so its `useState` initializer re-runs each time the dialog is re-
  // opened, replacing the prior `useEffect(setPickedId)` pattern that the
  // React Compiler flagged as set-state-in-effect.
  return (
    <Dialog open={props.open} onOpenChange={props.onOpenChange}>
      <DialogContent className="sm:max-w-md">
        {props.open ? (
          <DialogBody
            key={`${props.documentId}:${props.currentFolderId ?? '__root__'}`}
            {...props}
          />
        ) : null}
      </DialogContent>
    </Dialog>
  );
}

function DialogBody({
  documentId,
  documentTitle,
  currentFolderId,
  onOpenChange,
}: MoveToFolderDialogProps) {
  const { data: tree = [] } = useDocumentFolders();
  const move = useMoveDocument();
  const [pickedId, setPickedId] = useState<string | null>(currentFolderId);
  const paths = useMemo(() => buildFolderPaths(tree), [tree]);

  return (
    <>
      <DialogHeader>
        <DialogTitle>Move &ldquo;{documentTitle}&rdquo;</DialogTitle>
      </DialogHeader>
      <Command>
        <CommandInput placeholder="Search folders…" />
        <CommandList>
          <CommandEmpty>No folders match.</CommandEmpty>
          <CommandGroup heading="Special">
            <CommandItem
              value="Root (no folder)"
              onSelect={() => setPickedId(null)}
              className="flex items-center gap-2"
            >
              <Check className={pickedId === null ? 'h-4 w-4 opacity-100' : 'h-4 w-4 opacity-0'} />
              Root (no folder)
            </CommandItem>
          </CommandGroup>
          {paths.length > 0 ? (
            <CommandGroup heading="Folders">
              {paths.map((p) => (
                <CommandItem
                  key={p.id}
                  value={p.path}
                  onSelect={() => setPickedId(p.id)}
                  className="flex items-center gap-2"
                >
                  <Check
                    className={pickedId === p.id ? 'h-4 w-4 opacity-100' : 'h-4 w-4 opacity-0'}
                  />
                  <span className="truncate">{p.path}</span>
                </CommandItem>
              ))}
            </CommandGroup>
          ) : null}
        </CommandList>
      </Command>
      <DialogFooter>
        <Button variant="outline" onClick={() => onOpenChange(false)}>
          Cancel
        </Button>
        <Button
          disabled={pickedId === currentFolderId || move.isPending}
          onClick={async () => {
            try {
              await move.mutateAsync({ docId: documentId, folderId: pickedId });
              toast.success('Document moved');
              onOpenChange(false);
            } catch (err) {
              toastError(err);
            }
          }}
        >
          <FolderInput className="mr-1.5 h-4 w-4" aria-hidden />
          Move
        </Button>
      </DialogFooter>
    </>
  );
}
