import { useEffect, useRef, useState, type ReactNode } from "react"
import { Check, ChevronDown } from "lucide-react"

export interface StyledSelectOption<T extends string = string> {
  value: T
  label: string
  description?: string
  hint?: ReactNode
  icon?: ReactNode
}

interface Props<T extends string = string> {
  value: T | ""
  options: StyledSelectOption<T>[]
  onChange: (value: T | "") => void
  placeholder?: string
  allowEmpty?: boolean
  emptyLabel?: string
  disabled?: boolean
}

export default function StyledSelect<T extends string = string>({
  value,
  options,
  onChange,
  placeholder = "请选择...",
  allowEmpty = false,
  emptyLabel = "未指定",
  disabled = false,
}: Props<T>) {
  const [open, setOpen] = useState(false)
  const wrapRef = useRef<HTMLDivElement>(null)

  useEffect(() => {
    if (!open) return
    const onDoc = (e: MouseEvent) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target as Node)) setOpen(false)
    }
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setOpen(false)
    }
    document.addEventListener("mousedown", onDoc)
    document.addEventListener("keydown", onKey)
    return () => {
      document.removeEventListener("mousedown", onDoc)
      document.removeEventListener("keydown", onKey)
    }
  }, [open])

  const selected = options.find((o) => o.value === value)

  return (
    <div ref={wrapRef} className="relative">
      <button
        type="button"
        disabled={disabled}
        onClick={() => !disabled && setOpen((o) => !o)}
        className={`group flex h-10 w-full items-center justify-between gap-2 rounded-xl border bg-white px-3.5 text-sm transition-all ${
          disabled
            ? "cursor-not-allowed border-slate-100 bg-slate-50 text-slate-400"
            : open
              ? "border-sky-400 ring-2 ring-sky-100"
              : "border-slate-200 text-slate-700 hover:border-slate-300"
        }`}
      >
        <span className="flex min-w-0 items-center gap-2">
          {selected ? (
            <>
              {selected.icon && <span className="text-sky-500">{selected.icon}</span>}
              <span className="truncate">{selected.label}</span>
            </>
          ) : (
            <span className="text-slate-300">{placeholder}</span>
          )}
        </span>
        <ChevronDown
          className={`h-3.5 w-3.5 shrink-0 text-slate-400 transition-transform ${
            open ? "rotate-180 text-sky-500" : ""
          }`}
        />
      </button>

      {open && (
        <div className="absolute left-0 right-0 top-full z-30 mt-1.5 overflow-hidden rounded-xl border border-slate-200 bg-white shadow-lg shadow-slate-900/5 qycw-select-pop">
          <ul className="max-h-64 overflow-y-auto py-1">
            {allowEmpty && (
              <li>
                <button
                  type="button"
                  onClick={() => {
                    onChange("")
                    setOpen(false)
                  }}
                  className={`flex w-full items-center justify-between gap-2 px-3.5 py-2 text-left text-sm transition-colors ${
                    !value
                      ? "bg-sky-50/60 text-sky-700"
                      : "text-slate-500 hover:bg-slate-50"
                  }`}
                >
                  <span className="text-slate-400">{emptyLabel}</span>
                  {!value && <Check className="h-3.5 w-3.5 text-sky-500" />}
                </button>
              </li>
            )}
            {options.map((opt) => {
              const active = opt.value === value
              return (
                <li key={opt.value}>
                  <button
                    type="button"
                    onClick={() => {
                      onChange(opt.value)
                      setOpen(false)
                    }}
                    className={`flex w-full items-center justify-between gap-2 px-3.5 py-2 text-left text-sm transition-colors ${
                      active
                        ? "bg-sky-50/60 text-sky-700"
                        : "text-slate-700 hover:bg-slate-50"
                    }`}
                  >
                    <span className="flex min-w-0 items-center gap-2">
                      {opt.icon && (
                        <span className={active ? "text-sky-500" : "text-slate-400"}>
                          {opt.icon}
                        </span>
                      )}
                      <span className="min-w-0">
                        <span className="block truncate font-medium">{opt.label}</span>
                        {opt.description && (
                          <span className="block truncate text-[11px] text-slate-400">
                            {opt.description}
                          </span>
                        )}
                      </span>
                    </span>
                    <span className="flex shrink-0 items-center gap-1.5">
                      {opt.hint}
                      {active && <Check className="h-3.5 w-3.5 text-sky-500" />}
                    </span>
                  </button>
                </li>
              )
            })}
          </ul>
          <style>{`
            .qycw-select-pop { animation: qycw-sel-pop 160ms cubic-bezier(0.22, 1, 0.36, 1); transform-origin: top; }
            @keyframes qycw-sel-pop {
              from { opacity: 0; transform: translateY(-4px) scale(0.98); }
              to { opacity: 1; transform: translateY(0) scale(1); }
            }
          `}</style>
        </div>
      )}
    </div>
  )
}
