"use client"

import {
  useState,
  type ReactNode,
  type CSSProperties,
  type KeyboardEvent,
  type DragEvent,
} from "react"
import { Check, GripVertical } from "lucide-react"
import { Icon } from "@iconify/react"
import { cn, formatCount } from "@/lib/utils"
import {
  MAIL_SIDEBAR_MENU_ITEM_CLASS,
  MAIL_SIDEBAR_OVERFLOW_BTN_CLASS,
} from "@/lib/mail-chrome-classes"
import {
  DropdownMenuItem,
} from "@/components/ui/dropdown-menu"
import {
  ContextMenuItem,
} from "@/components/ui/context-menu"
import type { FolderTreeNode } from "@/lib/sidebar-nav-data"
import {
  folderTreeNavIconName,
  navFolderIconColorFromBgClass,
} from "@/lib/folder-nav-icons"
import type { SidebarNavDropPlacement } from "@/lib/sidebar-nav-dnd"

export function LabelMenuOptionWithCheck({
  checked,
  onPick,
  children,
}: {
  checked: boolean
  onPick: () => void
  children: ReactNode
}) {
  return (
    <DropdownMenuItem
      onClick={(e) => {
        e.stopPropagation()
        onPick()
      }}
      className={MAIL_SIDEBAR_MENU_ITEM_CLASS}
    >
      <span className="min-w-0 flex-1 text-left">{children}</span>
      <span
        className="flex size-4 shrink-0 items-center justify-center"
        aria-hidden={!checked}
      >
        {checked ? (
          <Check className="size-4 text-foreground" strokeWidth={2} aria-hidden />
        ) : null}
      </span>
    </DropdownMenuItem>
  )
}

export function ContextLabelMenuOptionWithCheck({
  checked,
  onPick,
  children,
}: {
  checked: boolean
  onPick: () => void
  children: ReactNode
}) {
  return (
    <ContextMenuItem
      onClick={() => onPick()}
      className={MAIL_SIDEBAR_MENU_ITEM_CLASS}
    >
      <span className="min-w-0 flex-1 text-left">{children}</span>
      <span
        className="flex size-4 shrink-0 items-center justify-center"
        aria-hidden={!checked}
      >
        {checked ? (
          <Check className="size-4 text-foreground" strokeWidth={2} aria-hidden />
        ) : null}
      </span>
    </ContextMenuItem>
  )
}

export function folderParentSelectOptions(tree: FolderTreeNode[]): {
  value: string
  label: string
}[] {
  const out: { value: string; label: string }[] = [
    { value: "__root__", label: "Racine" },
  ]
  const walk = (nodes: FolderTreeNode[], depth: number) => {
    for (const n of nodes) {
      out.push({
        value: n.id,
        label: `${"\u2003".repeat(depth * 2)}${n.label}`,
      })
      if (n.children?.length) walk(n.children, depth + 1)
    }
  }
  walk(tree, 0)
  return out
}

export function navRowRoundedWhenActive(active: boolean) {
  return active ? "rounded-r-full" : "rounded-r-none hover:rounded-r-full"
}

export function SidebarNavIconUnreadDot({ show }: { show: boolean }) {
  if (!show) return null
  return (
    <>
      <span
        className="pointer-events-none absolute -right-0.5 -top-0.5 size-2 rounded-full bg-yellow-400 opacity-75 motion-reduce:animate-none animate-ping"
        aria-hidden
      />
      <span
        className="pointer-events-none absolute -right-0.5 -top-0.5 size-2 rounded-full bg-yellow-400"
        aria-hidden
      />
    </>
  )
}

export function SidebarNavIconSlot({
  showUnreadDot,
  children,
}: {
  showUnreadDot?: boolean
  children: ReactNode
}) {
  return (
    <span className="relative flex h-5 w-5 shrink-0 items-center justify-center">
      {children}
      <SidebarNavIconUnreadDot show={!!showUnreadDot} />
    </span>
  )
}

export function markNavDragSource(el: HTMLElement | null) {
  el?.setAttribute("data-nav-drag-source", "true")
}

export function unmarkNavDragSource(el: HTMLElement | null) {
  el?.removeAttribute("data-nav-drag-source")
}

export function setNavDropIndicator(
  el: HTMLElement | null,
  placement: SidebarNavDropPlacement | null
) {
  if (!el) return
  if (placement) {
    el.setAttribute("data-nav-drop", placement)
  } else {
    el.removeAttribute("data-nav-drop")
  }
}

export function navRowActivate(e: KeyboardEvent, action: () => void) {
  if (e.key === "Enter" || e.key === " ") {
    e.preventDefault()
    action()
  }
}

export function FolderTreeNavIcon({
  hasChildren,
  open,
  colorBgClass,
  className,
  style,
}: {
  hasChildren: boolean
  open: boolean
  colorBgClass: string
  className?: string
  style?: CSSProperties
}) {
  return (
    <Icon
      icon={folderTreeNavIconName(hasChildren, open)}
      className={cn("h-5 w-5 shrink-0", className)}
      style={{ color: navFolderIconColorFromBgClass(colorBgClass), ...style }}
      aria-hidden
    />
  )
}

export function SidebarNavDragHandle({
  label,
  onDragStart,
  onDragEnd,
}: {
  label: string
  onDragStart: (e: DragEvent<HTMLSpanElement>) => void
  onDragEnd: () => void
}) {
  return (
    <span
      draggable
      title={`Réorganiser : ${label}`}
      aria-label={`Réorganiser : ${label}`}
      onDragStart={onDragStart}
      onDragEnd={onDragEnd}
      onClick={(e) => e.stopPropagation()}
      onMouseDown={(e) => e.stopPropagation()}
      className="pointer-events-none absolute left-0 top-1/2 z-10 flex h-8 w-4 -translate-y-1/2 cursor-grab items-center justify-center text-gray-400 opacity-0 transition-opacity hover:opacity-100 active:cursor-grabbing group-hover/folderrow:pointer-events-auto group-hover/folderrow:opacity-100 group-hover/labelrow:pointer-events-auto group-hover/labelrow:opacity-100"
    >
      <GripVertical className="h-3.5 w-3.5" aria-hidden />
    </span>
  )
}

const OVERFLOW_COUNT_HOVER_HIDE = {
  folderrow: "group-hover/folderrow:opacity-0",
  labelrow: "group-hover/labelrow:opacity-0",
  catnav: "group-hover/catnav:opacity-0",
} as const

const OVERFLOW_MENU_HOVER_SHOW = {
  folderrow:
    "group-hover/folderrow:opacity-100 group-has-[button:focus-visible]/folderrow:opacity-100",
  labelrow:
    "group-hover/labelrow:opacity-100 group-has-[button:focus-visible]/labelrow:opacity-100",
  catnav:
    "group-hover/catnav:opacity-100 group-has-[button:focus-visible]/catnav:opacity-100",
} as const

export function SidebarOverflowColumn({
  unread,
  menuOpen,
  hoverGroup,
  isSelected,
  hasUnread,
  className,
  showMenuButton = true,
  children,
}: {
  unread: number
  menuOpen: boolean
  hoverGroup: "folderrow" | "labelrow" | "catnav"
  isSelected?: boolean
  hasUnread?: boolean
  className?: string
  showMenuButton?: boolean
  children?: ReactNode
}) {
  if (!showMenuButton) {
    if (unread <= 0) return null
    return (
      <div className={cn("relative h-8 w-8 shrink-0", className)}>
        <span
          className={cn(
            "flex h-full items-center justify-center text-xs tabular-nums leading-none",
            isSelected && "font-medium",
            hasUnread && !isSelected && "font-semibold"
          )}
        >
          {formatCount(unread)}
        </span>
      </div>
    )
  }

  return (
    <div className={cn("relative h-8 w-8 shrink-0", className)}>
      {unread > 0 && (
        <span
          className={cn(
            "pointer-events-none absolute inset-0 flex items-center justify-center text-xs tabular-nums leading-none transition-opacity duration-150",
            isSelected && "font-medium",
            hasUnread && !isSelected && "font-semibold",
            menuOpen ? "opacity-0" : OVERFLOW_COUNT_HOVER_HIDE[hoverGroup]
          )}
        >
          {formatCount(unread)}
        </span>
      )}
      <div
        className={cn(
          "absolute inset-0 flex items-center justify-center opacity-0 transition-opacity duration-150",
          menuOpen ? "opacity-100" : OVERFLOW_MENU_HOVER_SHOW[hoverGroup]
        )}
      >
        {children}
      </div>
    </div>
  )
}

export const sidebarOverflowMenuButtonClass = MAIL_SIDEBAR_OVERFLOW_BTN_CLASS
