'use client';

import { useState } from 'react';
import { FolderPlus, Pencil, Trash2, MoreHorizontal } from 'lucide-react';
import { toast } from 'sonner';

import { Button } from '@/components/ui/button';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from '@/components/ui/dialog';
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { ConfirmationDialog } from '@/components/shared/confirmation-dialog';
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '@/components/ui/tooltip';
import { toastError } from '@/lib/api/toast-error';
import {
  useCreateFolder,
  useDeleteFolder,
  useRenameFolder,
  useDocumentFolders,
  type FolderNode,
} from '@/hooks/use-document-folders';

function findInTree(nodes: FolderNode[], id: string): FolderNode | null {
  for (const node of nodes) {
    if (node.id === id) return node;
    const found = findInTree(node.children, id);
    if (found) return found;
  }
  return null;
}

interface FolderActionsMenuProps {
  /** The folder these actions apply to. `null` means root → only the
   *  Create-new-folder action is available. */
  selectedFolderId: string | null | undefined;
  /** Callback after delete so parent can reset selection. */
  onAfterDelete?: () => void;
}

export function FolderActionsMenu({ selectedFolderId, onAfterDelete }: FolderActionsMenuProps) {
  const [createOpen, setCreateOpen] = useState(false);
  const [renameOpen, setRenameOpen] = useState(false);
  const [name, setName] = useState('');

  const createMutation = useCreateFolder();
  const renameMutation = useRenameFolder();
  const deleteMutation = useDeleteFolder();
  const { data: tree = [] } = useDocumentFolders();

  const isFolderSelected = typeof selectedFolderId === 'string';
  const currentName = (() => {
    if (!isFolderSelected) return '';
    function find(nodes: typeof tree): string | null {
      for (const n of nodes) {
        if (n.id === selectedFolderId) return n.name;
        const inChild = find(n.children);
        if (inChild) return inChild;
      }
      return null;
    }
    return find(tree) ?? '';
  })();

  const selectedNode = isFolderSelected ? findInTree(tree, selectedFolderId as string) : null;
  const isSystem = selectedNode?.systemManaged ?? false;

  return (
    <>
      <div className="flex items-center gap-1">
        <Button
          variant="outline"
          size="sm"
          className="flex-1 justify-start"
          onClick={() => {
            setName('');
            setCreateOpen(true);
          }}
        >
          <FolderPlus className="mr-2 h-4 w-4" aria-hidden />
          New folder {isFolderSelected ? 'inside this' : 'at root'}
        </Button>
        {isFolderSelected ? (
          <DropdownMenu>
            <DropdownMenuTrigger asChild>
              <Button variant="ghost" size="icon">
                <MoreHorizontal className="h-4 w-4" aria-hidden />
                <span className="sr-only">More folder actions</span>
              </Button>
            </DropdownMenuTrigger>
            <DropdownMenuContent align="end">
              <TooltipProvider>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <span>
                      <DropdownMenuItem
                        disabled={isSystem}
                        onClick={() => {
                          if (isSystem) return;
                          setName(currentName);
                          setRenameOpen(true);
                        }}
                      >
                        <Pencil className="mr-2 h-4 w-4" aria-hidden />
                        Rename
                      </DropdownMenuItem>
                    </span>
                  </TooltipTrigger>
                  {isSystem ? (
                    <TooltipContent>System folders can&apos;t be renamed.</TooltipContent>
                  ) : null}
                </Tooltip>
                <Tooltip>
                  <TooltipTrigger asChild>
                    <span>
                      <ConfirmationDialog
                        trigger={
                          <DropdownMenuItem
                            disabled={isSystem}
                            onSelect={(e) => e.preventDefault()}
                            className="text-destructive"
                          >
                            <Trash2 className="mr-2 h-4 w-4" aria-hidden />
                            Delete
                          </DropdownMenuItem>
                        }
                        title="Delete folder?"
                        description="Subfolders and documents inside will move up to the parent. The folder itself is removed."
                        confirmLabel="Delete folder"
                        loading={deleteMutation.isPending}
                        onConfirm={async () => {
                          try {
                            await deleteMutation.mutateAsync(selectedFolderId as string);
                            toast.success('Folder deleted; contents moved to parent.');
                            onAfterDelete?.();
                          } catch (err) {
                            toastError(err);
                          }
                        }}
                      />
                    </span>
                  </TooltipTrigger>
                  {isSystem ? (
                    <TooltipContent>System folders can&apos;t be deleted.</TooltipContent>
                  ) : null}
                </Tooltip>
              </TooltipProvider>
            </DropdownMenuContent>
          </DropdownMenu>
        ) : null}
      </div>

      <Dialog open={createOpen} onOpenChange={setCreateOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>
              New folder {isFolderSelected ? 'inside the current folder' : 'at root'}
            </DialogTitle>
          </DialogHeader>
          <div className="space-y-2">
            <Label htmlFor="folder-name">Name</Label>
            <Input
              id="folder-name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              autoFocus
              maxLength={200}
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setCreateOpen(false)}>
              Cancel
            </Button>
            <Button
              disabled={!name.trim() || createMutation.isPending}
              onClick={async () => {
                try {
                  await createMutation.mutateAsync({
                    name: name.trim(),
                    parentId: isFolderSelected ? (selectedFolderId as string) : null,
                  });
                  toast.success('Folder created');
                  setCreateOpen(false);
                } catch (err) {
                  toastError(err);
                }
              }}
            >
              Create
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>

      <Dialog open={renameOpen} onOpenChange={setRenameOpen}>
        <DialogContent className="sm:max-w-md">
          <DialogHeader>
            <DialogTitle>Rename folder</DialogTitle>
          </DialogHeader>
          <div className="space-y-2">
            <Label htmlFor="folder-rename">New name</Label>
            <Input
              id="folder-rename"
              value={name}
              onChange={(e) => setName(e.target.value)}
              autoFocus
              maxLength={200}
            />
          </div>
          <DialogFooter>
            <Button variant="outline" onClick={() => setRenameOpen(false)}>
              Cancel
            </Button>
            <Button
              disabled={!name.trim() || name.trim() === currentName || renameMutation.isPending}
              onClick={async () => {
                try {
                  await renameMutation.mutateAsync({
                    id: selectedFolderId as string,
                    name: name.trim(),
                  });
                  toast.success('Folder renamed');
                  setRenameOpen(false);
                } catch (err) {
                  toastError(err);
                }
              }}
            >
              Save
            </Button>
          </DialogFooter>
        </DialogContent>
      </Dialog>
    </>
  );
}
