"use client"

import { useCallback, useMemo, useState } from "react"
import { useRouter } from "next/navigation"
import { MoreVertical } from "lucide-react"
import { toast } from "sonner"
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Sheet, SheetContent, SheetDescription, SheetTitle } from "@/components/ui/sheet"
import { DriveMoveDialog, type DriveFolderPickerMode } from "@/components/drive/drive-move-dialog"
import { DriveNameDialog } from "@/components/drive/drive-name-dialog"
import { DriveFileMenuActions } from "@/components/drive/drive-file-menu-actions"
import { DRIVE_MENU_SURFACE_CLASS } from "@/components/drive/drive-file-context-menu"
import { useDriveMutations } from "@/lib/api/hooks/use-drive-queries"
import type { DriveFileInfo } from "@/lib/api/types"
import type { DriveView } from "@/lib/drive/drive-url"
import { useDriveRouteRoot } from "@/lib/drive/drive-route-context"
import { buildDriveFolderHref } from "@/lib/drive/drive-url"
import { displayFileName } from "@/lib/drive/display-file-name"
import { resolveRenameName } from "@/lib/drive/drive-default-name"
import { guardDriveMenuPointer, stopDriveMenuBubble } from "@/lib/drive/drive-menu-guard"
import { useIsMobile } from "@/hooks/use-mobile"
import { useDriveUIStore } from "@/lib/stores/drive-ui-store"
import { DRIVE_MENU_BTN, DRIVE_MENU_BTN_ACTIVE } from "@/lib/drive/drive-chrome-classes"
import { cn } from "@/lib/utils"

function breadcrumbFolderTarget(folderPath: string, name: string): DriveFileInfo {
  return {
    path: folderPath,
    name,
    type: "directory",
    size: 0,
    mime_type: "httpd/unix-directory",
    last_modified: "",
    etag: "",
    is_favorite: false,
  }
}

export function BreadcrumbFolderMenu({
  view,
  segments,
  folderPath,
  writable = true,
  allowShare = true,
  renameOpen,
  onRenameOpenChange,
  className,
}: {
  view: Extract<DriveView, "files" | "shared" | "org" | "mount">
  segments: string[]
  folderPath: string
  writable?: boolean
  allowShare?: boolean
  renameOpen?: boolean
  onRenameOpenChange?: (open: boolean) => void
  className?: string
}) {
  const isMobile = useIsMobile()
  const router = useRouter()
  const routeRoot = useDriveRouteRoot()
  const [dropdownOpen, setDropdownOpen] = useState(false)
  const [sheetOpen, setSheetOpen] = useState(false)
  const [internalRenameOpen, setInternalRenameOpen] = useState(false)
  const [folderPickerMode, setFolderPickerMode] = useState<DriveFolderPickerMode | null>(null)
  const setSharePath = useDriveUIStore((s) => s.setSharePath)
  const mutations = useDriveMutations()

  const folderName = segments[segments.length - 1] ?? ""
  const folder = useMemo(
    () => breadcrumbFolderTarget(folderPath, folderName),
    [folderPath, folderName]
  )
  const targets = useMemo(() => [folder], [folder])
  const label = displayFileName(folderName)

  const renameControlled = onRenameOpenChange != null
  const renameDialogOpen = renameControlled ? (renameOpen ?? false) : internalRenameOpen
  const setRenameDialogOpen = renameControlled ? onRenameOpenChange : setInternalRenameOpen

  const handleRename = async (input: string) => {
    const newName = resolveRenameName(folder, input)
    if (displayFileName(folder.name) === newName) return
    try {
      await mutations.rename.mutateAsync({ path: folder.path, new_name: newName })
      toast.success("Dossier renommé")
      const parentSegments = segments.slice(0, -1)
      router.push(
        buildDriveFolderHref(view, [...parentSegments, newName], undefined, routeRoot)
      )
    } catch {
      toast.error("Impossible de renommer ce dossier")
      throw new Error("rename failed")
    }
  }

  const closeDropdown = useCallback(() => {
    setDropdownOpen(false)
    guardDriveMenuPointer()
  }, [])

  const openRenameDialog = useCallback(() => {
    guardDriveMenuPointer()
    window.setTimeout(() => setRenameDialogOpen(true), 0)
  }, [setRenameDialogOpen])

  const openFolderPicker = (mode: DriveFolderPickerMode) => {
    setSheetOpen(false)
    closeDropdown()
    window.setTimeout(() => setFolderPickerMode(mode), 0)
  }

  const menuActionsProps = {
    targets,
    writable,
    allowShare,
    hideOpen: true,
    onOpen: () => {},
    setSharePath,
    mutations,
    onRenameRequest: openRenameDialog,
    onMoveRequest: writable ? () => openFolderPicker("move") : undefined,
    onCopyRequest: writable ? () => openFolderPicker("copy") : undefined,
  }

  const dialogs = (
    <>
      <DriveNameDialog
        open={renameDialogOpen}
        onOpenChange={setRenameDialogOpen}
        title="Renommer le dossier"
        defaultValue={label}
        confirmLabel="Renommer"
        onConfirm={handleRename}
      />
      <DriveMoveDialog
        open={folderPickerMode !== null}
        onOpenChange={(next) => {
          if (!next) setFolderPickerMode(null)
        }}
        mode={folderPickerMode ?? "move"}
        sources={targets}
      />
      <Sheet open={sheetOpen} onOpenChange={setSheetOpen}>
        <SheetContent
          side="bottom"
          hideClose
          className="gap-0 overflow-hidden rounded-t-2xl border-border px-0 pb-[max(1rem,env(safe-area-inset-bottom))] pt-2"
        >
          <SheetTitle className="sr-only">Actions pour {label}</SheetTitle>
          <SheetDescription className="sr-only">
            Actions disponibles pour {label}.
          </SheetDescription>
          <p className="truncate px-4 pb-2 text-sm font-medium text-muted-foreground">
            {label}
          </p>
          <div className="flex flex-col border-t border-border">
            <DriveFileMenuActions
              variant="sheet"
              {...menuActionsProps}
              onClose={() => setSheetOpen(false)}
              onRenameRequest={() => {
                setSheetOpen(false)
                openRenameDialog()
              }}
            />
          </div>
        </SheetContent>
      </Sheet>
    </>
  )

  if (isMobile) {
    return (
      <>
        <button
          type="button"
          data-drive-menu-btn
          aria-label={`Actions pour ${label}`}
          aria-expanded={sheetOpen}
          aria-haspopup="dialog"
          className={cn(DRIVE_MENU_BTN, className)}
          onClick={(e) => {
            stopDriveMenuBubble(e)
            setSheetOpen(true)
          }}
          onPointerDown={(e) => stopDriveMenuBubble(e)}
        >
          <MoreVertical className="h-4 w-4" aria-hidden />
        </button>
        {dialogs}
      </>
    )
  }

  return (
    <>
      <DropdownMenu
        modal
        open={dropdownOpen}
        onOpenChange={(next) => {
          if (next) {
            setDropdownOpen(true)
            return
          }
          closeDropdown()
        }}
      >
        <DropdownMenuTrigger asChild>
          <button
            type="button"
            data-drive-menu-btn
            aria-label={`Actions pour ${label}`}
            aria-haspopup="menu"
            className={cn(
              DRIVE_MENU_BTN,
              dropdownOpen && DRIVE_MENU_BTN_ACTIVE,
              className
            )}
            onClick={(e) => stopDriveMenuBubble(e)}
            onPointerDown={(e) => stopDriveMenuBubble(e)}
          >
            <MoreVertical className="h-4 w-4" aria-hidden />
          </button>
        </DropdownMenuTrigger>
        <DropdownMenuContent
          align="start"
          data-drive-menu-surface
          className={cn(DRIVE_MENU_SURFACE_CLASS, "w-52")}
          onCloseAutoFocus={(e) => e.preventDefault()}
          onPointerDown={(e) => stopDriveMenuBubble(e)}
          onClick={(e) => e.stopPropagation()}
        >
          <DriveFileMenuActions
            variant="dropdown"
            {...menuActionsProps}
            onClose={closeDropdown}
            onRenameRequest={() => {
              closeDropdown()
              openRenameDialog()
            }}
          />
        </DropdownMenuContent>
      </DropdownMenu>
      {dialogs}
    </>
  )
}
