"use client"

import { useLayoutEffect, useRef, type ComponentType, type ReactNode } from "react"
import { Check, Minus, Plus } from "lucide-react"
import { Icon } from "@iconify/react"
import { Input } from "@/components/ui/input"
import { cn } from "@/lib/utils"
import type { LabelPickerVisual } from "@/lib/label-picker-visual"

export type CatalogLabelPresence = "none" | "some" | "all"

export type LabelPickerItemComponent = ComponentType<{
  children: ReactNode
  onSelect?: (event: Event) => void
  className?: string
}>

export function LabelPickerLeadingVisual({
  visual,
}: {
  visual: LabelPickerVisual
}) {
  if (visual.kind === "iconify") {
    return (
      <span className="flex h-5 w-5 shrink-0 items-center justify-center">
        <Icon
          icon={visual.icon}
          className="size-[18px] shrink-0 text-[#5f6368]"
          aria-hidden
        />
      </span>
    )
  }
  return (
    <span className="flex h-5 w-5 shrink-0 items-center justify-center">
      <span
        className={cn("block h-3 w-3 rounded-sm", visual.colorClass)}
        aria-hidden
      />
    </span>
  )
}

function LabelPickerCheckboxVisual({
  checked,
}: {
  checked: boolean | "indeterminate"
}) {
  return (
    <span
      aria-hidden
      className={cn(
        "pointer-events-none inline-flex size-4 shrink-0 items-center justify-center rounded-[2.5px] border-[1.5px] border-[#c2c2c2] bg-transparent",
        checked === true && "border-[#0b57d0] bg-[#0b57d0] text-white",
        checked === "indeterminate" && "border-[#0b57d0] bg-[#0b57d0] text-white"
      )}
    >
      {checked === true ? (
        <Check className="size-3 stroke-[2.5] text-white" />
      ) : checked === "indeterminate" ? (
        <Minus className="size-3 stroke-[2.5] text-white" />
      ) : null}
    </span>
  )
}

export function EmailLabelPickerBlock({
  query,
  onQueryChange,
  catalogLabels,
  resolveLabelVisual,
  Item,
  getLabelPresence,
  onToggleCatalogLabel,
  onCreateLabel,
  listClassName,
  searchAutoFocus = true,
}: {
  query: string
  onQueryChange: (v: string) => void
  catalogLabels: string[]
  resolveLabelVisual: (label: string) => LabelPickerVisual
  Item: LabelPickerItemComponent
  getLabelPresence: (label: string) => CatalogLabelPresence
  onToggleCatalogLabel: (label: string) => void
  onCreateLabel: (label: string) => void
  listClassName?: string
  /** Focus search field when the picker mounts (submenu / sheet open). */
  searchAutoFocus?: boolean
}) {
  const searchInputRef = useRef<HTMLInputElement>(null)

  useLayoutEffect(() => {
    if (!searchAutoFocus) return
    let inner = 0
    const outer = requestAnimationFrame(() => {
      inner = requestAnimationFrame(() => {
        searchInputRef.current?.focus({ preventScroll: true })
      })
    })
    return () => {
      cancelAnimationFrame(outer)
      if (inner) cancelAnimationFrame(inner)
    }
  }, [searchAutoFocus])
  const q = query.trim().toLowerCase()
  const filtered = catalogLabels.filter(
    (l) => q.length === 0 || l.toLowerCase().includes(q)
  )
  const trimmed = query.trim()
  const hasExact = catalogLabels.some(
    (l) => l.toLowerCase() === trimmed.toLowerCase()
  )
  const canCreate = trimmed.length > 0 && !hasExact

  return (
    <>
      <div
        className="shrink-0 border-b border-[#eceff1] p-2"
        onPointerDown={(e) => e.stopPropagation()}
      >
        <Input
          ref={searchInputRef}
          value={query}
          onChange={(e) => onQueryChange(e.target.value)}
          placeholder="Rechercher ou créer un libellé…"
          aria-label="Rechercher ou créer un libellé"
          className="h-8 border-[#dadce0] text-sm shadow-none"
          autoComplete="off"
          onPointerDown={(e) => e.stopPropagation()}
          onClick={(e) => e.stopPropagation()}
          onKeyDown={(e) => e.stopPropagation()}
        />
      </div>
      <div className={cn("min-h-0 overflow-y-auto py-1", listClassName ?? "max-h-52")}>
        {canCreate ? (
          <Item
            onSelect={(e) => {
              e.preventDefault()
              onCreateLabel(trimmed)
            }}
          >
            <Plus className="size-[18px] shrink-0 text-[#0b57d0]" strokeWidth={1.5} />
            <span className="min-w-0 flex-1 text-[#0b57d0]">
              Créer le libellé « {trimmed} »
            </span>
          </Item>
        ) : null}
        {filtered.map((label) => {
          const presence = getLabelPresence(label)
          const boxChecked: boolean | "indeterminate" =
            presence === "all" ? true : presence === "some" ? "indeterminate" : false
          return (
            <Item
              key={label}
              onSelect={(e) => {
                e.preventDefault()
                onToggleCatalogLabel(label)
              }}
            >
              <LabelPickerCheckboxVisual checked={boxChecked} />
              <LabelPickerLeadingVisual visual={resolveLabelVisual(label)} />
              <span className="min-w-0 flex-1 truncate">{label}</span>
            </Item>
          )
        })}
        {filtered.length === 0 && !canCreate ? (
          <div className="px-3 py-2 text-sm text-[#5f6368]">
            Aucun libellé correspondant
          </div>
        ) : null}
      </div>
    </>
  )
}
