import { useEffect, useMemo, useState } from "react"
import { createPortal } from "react-dom"
import { ChevronDown, Search, X } from "lucide-react"
import { ICON_CATALOG, ICON_GROUPS, getIconByName, type IconCatalogItem } from "./iconsCatalog"

interface Props {
  value: string | null
  onChange: (name: string | null) => void
  placeholder?: string
}

export default function IconPicker({ value, onChange, placeholder = "选择图标" }: Props) {
  const [open, setOpen] = useState(false)
  const [keyword, setKeyword] = useState("")

  const selected = getIconByName(value)
  const SelectedIcon = selected?.Icon

  useEffect(() => {
    if (!open) return
    setKeyword("")
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") {
        e.stopImmediatePropagation()
        setOpen(false)
      }
    }
    document.addEventListener("keydown", onKey, true)
    return () => document.removeEventListener("keydown", onKey, true)
  }, [open])

  const grouped = useMemo<Array<{ group: string; items: IconCatalogItem[] }>>(() => {
    const k = keyword.trim().toLowerCase()
    const filter = k
      ? (i: IconCatalogItem) =>
          i.name.toLowerCase().includes(k) || i.label.toLowerCase().includes(k)
      : null
    return ICON_GROUPS.map((g) => ({
      group: g,
      items: ICON_CATALOG.filter((i) => i.group === g && (!filter || filter(i))),
    })).filter((s) => s.items.length > 0)
  }, [keyword])

  const totalShown = grouped.reduce((acc, g) => acc + g.items.length, 0)

  return (
    <>
      <button
        type="button"
        onClick={() => setOpen(true)}
        className="flex h-10 w-full items-center justify-between rounded-xl border border-slate-200 bg-white px-3.5 text-sm text-slate-700 transition-all hover:border-slate-300 focus:border-sky-400 focus:ring-2 focus:ring-sky-100"
      >
        <span className="flex min-w-0 items-center gap-2">
          {SelectedIcon ? (
            <>
              <SelectedIcon className="h-4 w-4 text-sky-500" />
              <span className="truncate">
                {selected?.label}
                <span className="ml-1.5 text-[11px] text-slate-400">{selected?.name}</span>
              </span>
            </>
          ) : (
            <span className="text-slate-300">{placeholder}</span>
          )}
        </span>
        <span className="flex items-center gap-1">
          {value && (
            <span
              role="button"
              tabIndex={0}
              onClick={(e) => {
                e.stopPropagation()
                onChange(null)
              }}
              onKeyDown={(e) => {
                if (e.key === "Enter") {
                  e.stopPropagation()
                  onChange(null)
                }
              }}
              className="rounded p-0.5 text-slate-300 hover:bg-slate-100 hover:text-slate-500"
              title="清除"
            >
              <X className="h-3 w-3" />
            </span>
          )}
          <ChevronDown className="h-3.5 w-3.5 text-slate-400" />
        </span>
      </button>

      {open && typeof document !== "undefined" &&
        createPortal(
          <div className="fixed inset-0 z-[110] flex items-center justify-center p-4">
            <div
              className="absolute inset-0 bg-slate-900/40 backdrop-blur-[2px] qycw-iconpicker-fade"
              onClick={() => setOpen(false)}
            />
            <div
              role="dialog"
              aria-modal="true"
              className="relative z-10 flex max-h-[82vh] w-full max-w-[640px] flex-col overflow-hidden rounded-2xl border border-slate-100 bg-white shadow-2xl shadow-slate-900/10 qycw-iconpicker-pop"
            >
              <div className="flex items-center justify-between gap-4 border-b border-slate-100 px-5 py-3.5">
                <h3 className="text-sm font-semibold text-slate-800">
                  选择图标
                  <span className="ml-2 text-xs font-normal text-slate-400">
                    共 {ICON_CATALOG.length} 个
                  </span>
                </h3>
                <button
                  type="button"
                  onClick={() => setOpen(false)}
                  className="rounded-lg p-1.5 text-slate-400 transition-colors hover:bg-slate-100 hover:text-slate-600"
                >
                  <X className="h-4 w-4" />
                </button>
              </div>

              <div className="border-b border-slate-100 px-5 py-3">
                <div className="relative">
                  <Search className="absolute left-2.5 top-1/2 h-3.5 w-3.5 -translate-y-1/2 text-slate-300" />
                  <input
                    type="text"
                    autoFocus
                    value={keyword}
                    onChange={(e) => setKeyword(e.target.value)}
                    placeholder="搜索：cloud / 服务器 / 锁..."
                    className="h-9 w-full rounded-lg border border-slate-200 bg-slate-50/60 pl-8 pr-3 text-sm text-slate-700 placeholder:text-slate-300 outline-none transition-colors focus:border-sky-300 focus:bg-white focus:ring-2 focus:ring-sky-100"
                  />
                </div>
              </div>

              <div className="flex-1 overflow-y-auto px-4 py-3">
                {grouped.length === 0 ? (
                  <p className="px-2 py-12 text-center text-sm text-slate-400">无匹配图标</p>
                ) : (
                  <div className="space-y-4">
                    {grouped.map((sec) => (
                      <div key={sec.group}>
                        <p className="mb-1.5 px-1 text-[11px] font-medium uppercase tracking-wider text-slate-400">
                          {sec.group}
                          <span className="ml-1.5 text-slate-300">({sec.items.length})</span>
                        </p>
                        <div className="grid grid-cols-10 gap-1.5">
                          {sec.items.map((i) => {
                            const active = i.name === value
                            const Icon = i.Icon
                            return (
                              <button
                                key={i.name}
                                type="button"
                                onClick={() => {
                                  onChange(i.name)
                                  setOpen(false)
                                }}
                                title={`${i.label} · ${i.name}`}
                                className={`flex h-10 w-10 items-center justify-center rounded-lg transition-colors ${
                                  active
                                    ? "bg-sky-500 text-white"
                                    : "text-slate-500 hover:bg-slate-100 hover:text-slate-700"
                                }`}
                              >
                                <Icon className="h-4 w-4" />
                              </button>
                            )
                          })}
                        </div>
                      </div>
                    ))}
                  </div>
                )}
              </div>

              <div className="flex items-center justify-between border-t border-slate-100 bg-slate-50/60 px-5 py-2.5 text-xs text-slate-500">
                <span>当前显示 {totalShown} 个</span>
                <button
                  type="button"
                  onClick={() => {
                    onChange(null)
                    setOpen(false)
                  }}
                  className="rounded-lg px-2 py-1 text-slate-500 transition-colors hover:bg-slate-100 hover:text-slate-700"
                >
                  清除选择
                </button>
              </div>
            </div>

            <style>{`
              .qycw-iconpicker-fade { animation: qycw-ipk-fade 160ms ease-out; }
              .qycw-iconpicker-pop { animation: qycw-ipk-pop 200ms cubic-bezier(0.22, 1, 0.36, 1); }
              @keyframes qycw-ipk-fade { from { opacity: 0; } to { opacity: 1; } }
              @keyframes qycw-ipk-pop {
                from { opacity: 0; transform: translateY(6px) scale(0.98); }
                to   { opacity: 1; transform: translateY(0) scale(1); }
              }
            `}</style>
          </div>,
          document.body,
        )}
    </>
  )
}
