"use client"

import type { ReactNode } from "react"
import { toast } from "sonner"
import {
  CheckSquare,
  Copy,
  Download,
  ExternalLink,
  FolderInput,
  Link2,
  Pencil,
  Star,
  Trash2,
  Undo2,
} from "lucide-react"
import { Icon } from "@iconify/react"
import {
  ContextMenuItem,
} from "@/components/ui/context-menu"
import {
  DropdownMenuItem,
} from "@/components/ui/dropdown-menu"
import type { useDriveMutations } from "@/lib/api/hooks/use-drive-queries"
import type { DriveFileInfo } from "@/lib/api/types"
import {
  guardDriveMenuPointer,
  stopDriveMenuEvent,
} from "@/lib/drive/drive-menu-guard"
import { cn } from "@/lib/utils"
import { driveTrashItemKey } from "@/lib/drive/drive-trash"
import { mountCloudSuiteBrand } from "@/lib/drive/cloud-native-open"

export const DRIVE_MENU_ITEM_CLASS =
  "gap-3 py-2 text-[#3c4043] focus:text-[#3c4043] dark:text-[#e8eaed] dark:focus:text-[#e8eaed] [&_svg]:text-[#3c4043] dark:[&_svg]:text-[#e8eaed]"

export const DRIVE_MENU_ITEM_DESTRUCTIVE_CLASS =
  "gap-3 py-2 text-destructive focus:text-destructive [&_svg]:text-destructive"

const SHEET_ACTION_CLASS =
  "flex w-full items-center gap-3 px-4 py-3 text-left text-sm text-[#3c4043] transition-colors hover:bg-accent active:bg-accent/80 dark:text-[#e8eaed] [&_svg]:text-[#3c4043] dark:[&_svg]:text-[#e8eaed]"

export function canShareDriveItem(item: DriveFileInfo) {
  return item.type === "file" || item.type === "directory"
}

function DriveMenuItemIcon({ children }: { children: ReactNode }) {
  return (
    <span className="flex h-4 w-4 shrink-0 items-center justify-center">
      {children}
    </span>
  )
}

type Mutations = ReturnType<typeof useDriveMutations>

type DriveFileMenuActionsProps = {
  variant: "dropdown" | "context" | "sheet"
  targets: DriveFileInfo[]
  isTrash?: boolean
  allowShare?: boolean
  /** When false, hide rename / move / copy / delete. */
  writable?: boolean
  /** When true, hide the "Ouvrir" action (e.g. current folder in breadcrumb). */
  hideOpen?: boolean
  /** When false, hide favorite actions (public share). */
  hideFavorite?: boolean
  onOpen: () => void
  onClose?: () => void
  setSharePath: (path: string | null, itemType?: "file" | "directory" | null) => void
  mutations: Mutations
  onRenameRequest: () => void
  onMoveRequest?: () => void
  onCopyRequest?: () => void
  onDownloadRequest?: () => void
  onQuickLinkRequest?: () => void
  onEnterSelectionMode?: () => void
}

export function DriveFileMenuActions({
  variant,
  targets,
  isTrash,
  allowShare = true,
  writable = true,
  hideOpen = false,
  hideFavorite = false,
  onOpen,
  onClose,
  setSharePath,
  mutations,
  onRenameRequest,
  onMoveRequest,
  onCopyRequest,
  onDownloadRequest,
  onQuickLinkRequest,
  onEnterSelectionMode,
}: DriveFileMenuActionsProps) {
  const single = targets.length === 1 ? targets[0]! : null
  const multi = targets.length > 1
  const mountSuiteBrand = single ? mountCloudSuiteBrand(single) : null

  const runAsync = async (fn: () => Promise<void>, ok: string, err: string) => {
    onClose?.()
    try {
      await fn()
      toast.success(ok)
    } catch {
      toast.error(err)
    }
  }

  const runMenuAction = (
    fn: () => void,
    asyncFn?: () => Promise<void>,
    ok?: string,
    err?: string
  ) => {
    guardDriveMenuPointer()
    onClose?.()
    if (asyncFn && ok && err) {
      void runAsync(asyncFn, ok, err)
      return
    }
    fn()
  }

  const selectAction = (fn: () => void) => () => {
    guardDriveMenuPointer()
    onClose?.()
    window.setTimeout(fn, 0)
  }

  const favoriteLabel = targets.every((f) => f.is_favorite)
    ? "Retirer des favoris"
    : "Ajouter aux favoris"

  const favoriteAsync = async () => {
    for (const f of targets) {
      await mutations.favorite.mutateAsync({
        path: f.path,
        favorite: !f.is_favorite,
      })
    }
  }

  const deleteAsync = async () => {
    for (const f of targets) {
      await mutations.deleteFile.mutateAsync(f.path)
    }
  }

  const restoreAsync = async () => {
    for (const f of targets) {
      await mutations.restore.mutateAsync(driveTrashItemKey(f))
    }
  }

  const deleteTrashAsync = async () => {
    for (const f of targets) {
      await mutations.deleteTrash.mutateAsync(driveTrashItemKey(f))
    }
  }

  const actions: Array<{
    key: string
    label: string
    icon: ReactNode
    destructive?: boolean
    visible: boolean
    onSelect: () => void
  }> = [
    {
      key: "open",
      label: mountSuiteBrand?.label ?? "Ouvrir",
      icon: mountSuiteBrand ? (
        <Icon icon={mountSuiteBrand.icon} className="h-4 w-4" aria-hidden />
      ) : (
        <ExternalLink className="h-4 w-4" aria-hidden />
      ),
      visible: !hideOpen && !multi && Boolean(single),
      onSelect: () => runMenuAction(() => window.setTimeout(() => onOpen(), 0)),
    },
    {
      key: "select",
      label: "Sélectionner",
      icon: <CheckSquare className="h-4 w-4" aria-hidden />,
      visible: variant === "sheet" && Boolean(!isTrash && single && onEnterSelectionMode),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onEnterSelectionMode?.(), 0)
        }),
    },
    {
      key: "share",
      label: "Partager",
      icon: <Link2 className="h-4 w-4" aria-hidden />,
      visible: Boolean(!isTrash && allowShare && !multi && single && canShareDriveItem(single)),
      onSelect: () => runMenuAction(() => setSharePath(single!.path, single!.type)),
    },
    {
      key: "copy",
      label: multi ? `Copier vers (${targets.length})` : "Copier vers",
      icon: <Copy className="h-4 w-4" aria-hidden />,
      visible: Boolean(writable && !isTrash && onCopyRequest),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onCopyRequest?.(), 0)
        }),
    },
    {
      key: "move",
      label: multi ? `Déplacer vers (${targets.length})` : "Déplacer vers",
      icon: <FolderInput className="h-4 w-4" aria-hidden />,
      visible: Boolean(writable && !isTrash && onMoveRequest),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onMoveRequest?.(), 0)
        }),
    },
    {
      key: "download",
      label: "Télécharger",
      icon: <Download className="h-4 w-4" aria-hidden />,
      visible: Boolean(!isTrash && onDownloadRequest),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onDownloadRequest?.(), 0)
        }),
    },
    {
      key: "quick-link",
      label: "Obtenir le lien",
      icon: <Link2 className="h-4 w-4" aria-hidden />,
      visible: Boolean(!isTrash && onQuickLinkRequest && single),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onQuickLinkRequest?.(), 0)
        }),
    },
    {
      key: "favorite",
      label: favoriteLabel,
      icon: <Star className="h-4 w-4" aria-hidden />,
      visible: !isTrash && !hideFavorite,
      onSelect: () =>
        runMenuAction(
          () => {},
          favoriteAsync,
          favoriteLabel === "Retirer des favoris" ? "Retiré des favoris" : "Ajouté aux favoris",
          "Impossible de modifier les favoris"
        ),
    },
    {
      key: "restore",
      label: `Restaurer${multi ? ` (${targets.length})` : ""}`,
      icon: <Undo2 className="h-4 w-4" aria-hidden />,
      visible: Boolean(isTrash),
      onSelect: () =>
        runMenuAction(
          () => {},
          restoreAsync,
          "Élément(s) restauré(s)",
          "Impossible de restaurer"
        ),
    },
    {
      key: "delete-trash",
      label: `Supprimer définitivement${multi ? ` (${targets.length})` : ""}`,
      icon: <Trash2 className="h-4 w-4" aria-hidden />,
      destructive: true,
      visible: Boolean(isTrash && writable),
      onSelect: () =>
        runMenuAction(
          () => {},
          deleteTrashAsync,
          "Élément(s) supprimé(s) définitivement",
          "Impossible de supprimer définitivement"
        ),
    },
    {
      key: "rename",
      label: "Renommer",
      icon: <Pencil className="h-4 w-4" aria-hidden />,
      visible: Boolean(writable && !isTrash && single && !multi),
      onSelect: () =>
        runMenuAction(() => {
          window.setTimeout(() => onRenameRequest(), 0)
        }),
    },
    {
      key: "delete",
      label: `Supprimer${multi ? ` (${targets.length})` : ""}`,
      icon: <Trash2 className="h-4 w-4" aria-hidden />,
      destructive: true,
      visible: writable && !isTrash,
      onSelect: () =>
        runMenuAction(() => {}, deleteAsync, "Supprimé", "Impossible de supprimer"),
    },
  ]

  if (variant === "sheet") {
    return (
      <>
        {actions
          .filter((action) => action.visible)
          .map((action) => (
            <button
              key={action.key}
              type="button"
              className={cn(
                SHEET_ACTION_CLASS,
                action.destructive &&
                  "text-destructive hover:bg-destructive/10 active:bg-destructive/15 [&_svg]:text-destructive"
              )}
              onPointerDown={(e) => stopDriveMenuEvent(e)}
              onClick={() => {
                guardDriveMenuPointer()
                action.onSelect()
              }}
            >
              <DriveMenuItemIcon>{action.icon}</DriveMenuItemIcon>
              {action.label}
            </button>
          ))}
      </>
    )
  }

  if (variant === "context") {
    return (
      <>
        {actions
          .filter((action) => action.visible)
          .map((action) => (
            <ContextMenuItem
              key={action.key}
              variant={action.destructive ? "destructive" : "default"}
              className={cn(
                action.destructive
                  ? DRIVE_MENU_ITEM_DESTRUCTIVE_CLASS
                  : DRIVE_MENU_ITEM_CLASS
              )}
              onPointerDown={(e) => stopDriveMenuEvent(e)}
              onSelect={selectAction(action.onSelect)}
            >
              <DriveMenuItemIcon>{action.icon}</DriveMenuItemIcon>
              {action.label}
            </ContextMenuItem>
          ))}
      </>
    )
  }

  return (
    <>
      {actions
        .filter((action) => action.visible)
        .map((action) => (
          <DropdownMenuItem
            key={action.key}
            variant={action.destructive ? "destructive" : "default"}
            className={cn(
              action.destructive
                ? DRIVE_MENU_ITEM_DESTRUCTIVE_CLASS
                : DRIVE_MENU_ITEM_CLASS
            )}
            onPointerDown={(e) => stopDriveMenuEvent(e)}
            onSelect={() => action.onSelect()}
          >
            <DriveMenuItemIcon>{action.icon}</DriveMenuItemIcon>
            {action.label}
          </DropdownMenuItem>
        ))}
    </>
  )
}
