import { useEffect, useMemo, useState } from "react"
import { Label } from "@/components/ui/label"
import {
  ContextMenu,
  ContextMenuContent,
  ContextMenuTrigger,
} from "@/components/ui/context-menu"
import { useTheme } from "@/components/theme-provider"
import {
  FAMILIES,
  findFamilyShadeFromHex,
  isSameColor,
  isTransparent,
  resolveFamilyShade,
  SHADE_STEPS,
  toBaseHex,
  type Family,
  type Shade,
} from "@/features/board/lib/colors/tailwind"
import { cn } from "@/lib/utils"
import { KeySwatch } from "./key-swatch"


type Props = {
  value?: string | null
  onPick: (hexOrNull: string | null) => void
  allowTransparent?: boolean
  controlledShade?: Shade
  onShadeChange?: (s: Shade) => void
  /** Compact = small swatches, labels hidden; right-click shows shades. */
  variant?: "default" | "compact"
}


/**
 * Tailwind-palette color picker. Lifted verbatim from dim0/style-panel,
 * only import paths and minor lint fixes. Left-click a family swatch
 * picks the current shade; right-click a family swatch opens a shade
 * grid. Below the family row, a shade strip lets the user step through
 * the current family's shades.
 */
export function ColorGrid({
  value,
  onPick,
  allowTransparent = false,
  controlledShade,
  onShadeChange,
  variant = "default",
}: Props) {
  const { resolvedTheme } = useTheme()
  const isDark = resolvedTheme === "dark"
  const isValueTransparent = isTransparent(value)

  const defaultFamily = useMemo(() => FAMILIES.find((f) => !!f.family) ?? FAMILIES[0], [])
  const [activeFamily, setActiveFamily] = useState<Family>(defaultFamily)
  const [internalShade, setInternalShade] = useState<Shade>(500)

  const shade: Shade = controlledShade ?? internalShade
  const isCompact = variant === "compact"
  const activeFamilyLabel = activeFamily.family
    ? `${activeFamily.family.charAt(0).toUpperCase()}${activeFamily.family.slice(1)}`
    : ""

  useEffect(() => {
    if (isTransparent(value)) {
      const transparentFam = FAMILIES.find((f) => f.transparent)
      if (transparentFam) setActiveFamily(transparentFam)
      return
    }

    const base = toBaseHex(value)
    if (!base) return

    if (isSameColor(base, "#ffffff")) {
      setActiveFamily(FAMILIES.find((f) => f.fixedHex === "#ffffff") ?? defaultFamily)
      return
    }
    if (isSameColor(base, "#000000")) {
      setActiveFamily(FAMILIES.find((f) => f.fixedHex === "#000000") ?? defaultFamily)
      return
    }

    const match = findFamilyShadeFromHex(base)
    if (match?.family && match?.shade) {
      const fam = FAMILIES.find((f) => f.family === match.family) ?? defaultFamily
      setActiveFamily(fam)
      setInternalShade(match.shade)
      onShadeChange?.(match.shade)
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [value])

  const resolveEntryHexAtShade = (f: Family, s: Shade): string | null => {
    if (f.transparent) return null
    if (f.fixedHex) return f.fixedHex
    return f.family ? resolveFamilyShade(f.family, s) : null
  }

  const pickFamily = (f: Family) => {
    if (f.transparent) {
      setActiveFamily(f)
      if (allowTransparent) onPick(null)
      return
    }
    if (f.fixedHex) {
      const baseHex = toBaseHex(f.fixedHex)
      if (baseHex) onPick(baseHex)
      setActiveFamily(f)
      return
    }
    setActiveFamily(f)
    if (!f.family) return
    const hex = resolveFamilyShade(f.family, shade)
    const baseHex = toBaseHex(hex)
    if (baseHex) onPick(baseHex)
  }

  const pickShade = (s: Shade, fam: Family = activeFamily) => {
    if (controlledShade == null) setInternalShade(s)
    onShadeChange?.(s)
    if (!fam.family) return
    const hex = resolveFamilyShade(fam.family, s)
    const baseHex = toBaseHex(hex)
    if (baseHex) onPick(baseHex)
  }

  const FamilyItem = ({ f }: { f: Family }) => {
    const colorHex = resolveEntryHexAtShade(f, shade)
    const selected = f.transparent
      ? isValueTransparent
      : !isValueTransparent && !!colorHex && isSameColor(value, colorHex)

    // Special entries (transparent / white / black) — no context menu.
    if (f.transparent || f.fixedHex) {
      return (
        <KeySwatch
          key={f.id}
          color={colorHex}
          label={f.key}
          selected={selected}
          onClick={() => pickFamily(f)}
          checker={!!f.transparent}
          isDark={isDark}
          size={isCompact ? "dot" : "md"}
          hideLabel={isCompact}
          className={isCompact ? "ring-offset-0" : undefined}
        />
      )
    }

    // Tailwind families — compact gets right-click shade selector.
    if (isCompact && f.family) {
      return (
        <ContextMenu key={f.id}>
          <ContextMenuTrigger asChild>
            <KeySwatch
              color={colorHex}
              label={f.key}
              selected={selected}
              onClick={() => pickFamily(f)}
              isDark={isDark}
              size="dot"
              hideLabel
              className="ring-offset-0"
            />
          </ContextMenuTrigger>
          <ContextMenuContent className="p-2">
            <div className="grid grid-cols-6 gap-1">
              {SHADE_STEPS.map((step) => {
                const hex = resolveFamilyShade(f.family ?? "", step)
                const selectedShade = !isValueTransparent && !!hex && isSameColor(value, hex)
                const baseHex = toBaseHex(hex)
                return (
                  <KeySwatch
                    key={step}
                    color={hex}
                    selected={selectedShade}
                    onClick={() => {
                      if (baseHex) {
                        setActiveFamily(f)
                        pickShade(step, f)
                      }
                    }}
                    isDark={isDark}
                    size="dot"
                    hideLabel
                  />
                )
              })}
            </div>
          </ContextMenuContent>
        </ContextMenu>
      )
    }

    return (
      <KeySwatch
        key={f.id}
        color={colorHex}
        label={f.key}
        selected={selected}
        onClick={() => pickFamily(f)}
        isDark={isDark}
        size="md"
      />
    )
  }

  return (
    <div className="space-y-2">
      <div className={cn("grid grid-cols-8 gap-1")}>
        {FAMILIES.filter((f) => allowTransparent || !f.transparent).map((f) => (
          <FamilyItem key={f.id} f={f} />
        ))}
      </div>

      {activeFamily.family ? (
        <div className="space-y-1">
          <Label className="text-xs text-muted-foreground">
            {isCompact ? activeFamilyLabel : `Shades — ${activeFamilyLabel}`}
          </Label>
          <div className={cn("flex flex-wrap items-center", isCompact ? "gap-1" : "gap-2")}>
            {SHADE_STEPS.map((step, i) => {
              const hex = resolveFamilyShade(activeFamily.family ?? "", step)
              const selected = !!hex && isSameColor(value, hex)
              const baseHex = toBaseHex(hex)
              return (
                <KeySwatch
                  key={step}
                  color={hex}
                  label={isCompact ? undefined : `⇧${i + 1}`}
                  selected={selected}
                  onClick={() => baseHex && pickShade(step)}
                  isDark={isDark}
                  size={isCompact ? "dot" : "md"}
                  hideLabel={isCompact}
                />
              )
            })}
          </div>
        </div>
      ) : null}
    </div>
  )
}
