import type { CSSProperties } from "react";
import { useId } from "react";

import { splitPalaceBranchDisplay, type TuViPalaceView } from "@/lib/tuvi-chart-view-model";

import { tierForPalaceView, type TuViPalaceCardTier } from "./TuViPalaceCard";
import {
  TUVI_BOARD_FOCUS_PALACE_KEYS,
  TUVI_BOARD_GRID_TEMPLATE_AREAS,
  TUVI_CHART_BOARD_LAYOUT,
  TUVI_CHART_PALACE_SLOT_KEYS,
} from "./tuvi-chart-layout";

export type TuViPalaceSelectorDesktopVariant = "mini-chart" | "list";

/** `auto`: dropdown trên màn rất nhỏ, chip ngang tablet — giống thiên bàn chủ. */
export type TuViPalaceSelectorMobileVariant = "chips" | "dropdown" | "auto";

const MINI_GRID_STYLE: CSSProperties = {
  gridTemplateAreas: TUVI_BOARD_GRID_TEMPLATE_AREAS,
  gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
  gridTemplateRows: "repeat(4, minmax(2.75rem, auto))",
};

function tierQuietClass(tier: TuViPalaceCardTier): string {
  if (tier === "menh") return "border-[#d4af37]/16";
  if (tier === "than") return "border-violet-400/14";
  if (tier === "focus") return "border-[#d4af37]/12";
  return "border-white/[0.06]";
}

function tierShortLabel(tier: TuViPalaceCardTier): string {
  if (tier === "menh") return "Mệnh";
  if (tier === "than") return "Thân";
  if (tier === "focus") return "Trọng điểm";
  return "";
}

/** Cùng thứ tự ô với `TuViChartBoard` / `TUVI_CHART_PALACE_SLOT_KEYS`. */
export function tuViPalaceSelectorOrderedPalaces(palaces: readonly TuViPalaceView[]): TuViPalaceView[] {
  const byKey = new Map(palaces.map((p) => [p.key, p] as const));
  return TUVI_CHART_PALACE_SLOT_KEYS.map((k) => byKey.get(k)).filter((p): p is TuViPalaceView => p != null);
}

const CHIP_SELECTED =
  "border-[#d4af37]/55 bg-[#d4af37]/18 text-[#fff8e8] shadow-[0_0_0_2px_rgba(212,175,55,0.48),inset_0_1px_0_rgba(255,255,255,0.07)]";
const MINI_SELECTED =
  "border border-[#d4af37]/55 bg-[#d4af37]/16 text-[#fff8ec] shadow-[0_0_0_2px_rgba(212,175,55,0.42),inset_0_1px_0_rgba(255,255,255,0.07)]";
const LIST_SELECTED =
  "border-[#d4af37]/35 bg-[#d4af37]/14 shadow-[inset_3px_0_0_0_rgba(232,200,92,0.95),inset_0_0_0_1px_rgba(212,175,55,0.22)]";

type Props = {
  /** Cùng nguồn `vm.palaces` như `TuViChartBoard`. */
  palaces: TuViPalaceView[];
  palaceOrderIndex: Map<string, number>;
  selectedPalaceKey: string;
  onSelectPalace: (key: string) => void;
  centerHint?: string;
  className?: string;
  desktopVariant?: TuViPalaceSelectorDesktopVariant;
  mobileVariant?: TuViPalaceSelectorMobileVariant;
  /** Ghi đè id `select` (tránh trùng khi nhiều selector). */
  selectId?: string;
};

/**
 * Bộ chọn cung tái sử dụng — dữ liệu chuẩn hoá `TuViPalaceView[]` khớp thiên bàn chính.
 */
export function TuViLuanCungPalaceSelector({
  palaces,
  palaceOrderIndex,
  selectedPalaceKey,
  onSelectPalace,
  centerHint,
  className = "",
  desktopVariant = "mini-chart",
  mobileVariant = "auto",
  selectId: selectIdProp,
}: Props) {
  const reactId = useId();
  const selectId = selectIdProp ?? `tuvi-palace-select-${reactId.replace(/:/g, "")}`;

  const slotPalaces = tuViPalaceSelectorOrderedPalaces(palaces);
  const byKey = new Map(palaces.map((p) => [p.key, p] as const));

  const dropdownWrapClass =
    mobileVariant === "dropdown" ? "lg:hidden"
    : mobileVariant === "auto" ? "sm:hidden lg:hidden"
    : "";

  const chipToolbarClass = (() => {
    if (mobileVariant === "chips") {
      return "-mx-1 overflow-x-auto pb-1 [-webkit-overflow-scrolling:touch] lg:hidden";
    }
    if (mobileVariant === "auto") {
      return "hidden sm:flex lg:hidden -mx-1 overflow-x-auto pb-1 [-webkit-overflow-scrolling:touch]";
    }
    return "";
  })();

  return (
    <div className={`space-y-3 ${className}`}>
      <div className="border-b border-[#d4af37]/10 pb-3 lg:pb-4">
        <p className="font-ctkp-serif text-[10px] uppercase tracking-[0.26em] text-[#d4af37]/65">
          Chọn cung
        </p>
        <p className="ctkp-tuvi-text-muted mt-1 font-sans text-[11px] leading-relaxed">
          Ô đang chọn có viền vàng rõ; nội dung luận đổi theo ô (cùng dữ liệu với thiên bàn Lá số).
        </p>
      </div>

      {dropdownWrapClass ?
        <div className={dropdownWrapClass}>
          <label htmlFor={selectId} className="sr-only">
            Chọn cung để luận
          </label>
          <select
            id={selectId}
            value={selectedPalaceKey}
            onChange={(e) => onSelectPalace(e.target.value)}
            className="w-full rounded-lg border border-[#d4af37]/22 bg-[#060912]/85 px-3 py-2.5 font-ctkp-serif text-[13px] tracking-[0.04em] text-[#f0e8d8] shadow-[inset_0_1px_0_rgba(255,255,255,0.05)] outline-none transition-[border-color,box-shadow] focus:border-[#d4af37]/45 focus:ring-2 focus:ring-[#d4af37]/18"
          >
            {slotPalaces.map((p) => {
              const idx = palaceOrderIndex.get(p.key) ?? 0;
              return (
                <option key={p.key} value={p.key}>
                  {idx}/12 — {p.name}
                </option>
              );
            })}
          </select>
        </div>
      : null}

      {chipToolbarClass ?
        <div className={chipToolbarClass} role="toolbar" aria-label="Chọn cung (vuốt ngang)">
          <div className="flex w-max min-w-full gap-2 px-1">
            {slotPalaces.map((p) => (
              <PalaceChip
                key={p.key}
                palace={p}
                palaceOrderIndex={palaceOrderIndex}
                selected={p.key === selectedPalaceKey}
                onSelect={() => onSelectPalace(p.key)}
              />
            ))}
          </div>
        </div>
      : null}

      {/* desktop */}
      <div className="hidden lg:block">
        {desktopVariant === "mini-chart" ?
          <MiniChartDesktop
            byKey={byKey}
            palaceOrderIndex={palaceOrderIndex}
            selectedPalaceKey={selectedPalaceKey}
            onSelectPalace={onSelectPalace}
            centerHint={centerHint}
          />
        : (
          <StructuredListDesktop
            slotPalaces={slotPalaces}
            palaceOrderIndex={palaceOrderIndex}
            selectedPalaceKey={selectedPalaceKey}
            onSelectPalace={onSelectPalace}
          />
        )}
      </div>
    </div>
  );
}

function PalaceChip({
  palace: p,
  palaceOrderIndex,
  selected,
  onSelect,
}: {
  palace: TuViPalaceView;
  palaceOrderIndex: Map<string, number>;
  selected: boolean;
  onSelect: () => void;
}) {
  const idx = palaceOrderIndex.get(p.key) ?? 0;
  const tier = tierForPalaceView(p);
  return (
    <button
      type="button"
      aria-pressed={selected}
      onClick={onSelect}
      className={`shrink-0 snap-start rounded-lg border px-3 py-2 text-left font-ctkp-serif text-[12px] leading-tight tracking-[0.03em] transition-[background-color,border-color,box-shadow,color] duration-200 ${
        selected ?
          CHIP_SELECTED
        : `border-white/[0.07] bg-[#0a1020]/72 text-slate-300 hover:border-[#d4af37]/22 hover:bg-[#0a1020]/92 hover:text-slate-100 ${tierQuietClass(tier)}`
      }`}
    >
      <span className={`tabular-nums text-[10px] ${selected ? "text-[#d4af37]/75" : "text-slate-500"}`}>
        {idx}/12
      </span>
      <span className="mt-0.5 block">{p.name}</span>
    </button>
  );
}

function MiniChartDesktop({
  byKey,
  palaceOrderIndex,
  selectedPalaceKey,
  onSelectPalace,
  centerHint,
}: {
  byKey: Map<string, TuViPalaceView>;
  palaceOrderIndex: Map<string, number>;
  selectedPalaceKey: string;
  onSelectPalace: (key: string) => void;
  centerHint?: string;
}) {
  return (
    <div
      className="rounded-[11px] border border-[#d4af37]/14 bg-[linear-gradient(165deg,rgba(18,24,40,0.72),rgba(5,8,16,0.92))] p-[3px] shadow-[inset_0_1px_0_rgba(212,175,55,0.08),0_10px_28px_rgba(0,0,0,0.35)]"
      aria-label="Lưới chọn cung (mini)"
    >
      <div
        className="grid gap-px rounded-[9px] bg-black/35 p-px"
        style={{
          ...MINI_GRID_STYLE,
        }}
      >
        {TUVI_CHART_PALACE_SLOT_KEYS.map((palaceKey) => {
          const p = byKey.get(palaceKey);
          const area = TUVI_CHART_BOARD_LAYOUT.palaceToGridArea(palaceKey);
          if (!p || !area) return null;
          const idx = palaceOrderIndex.get(p.key) ?? 0;
          const selected = selectedPalaceKey === p.key;
          const tier = tierForPalaceView(p);
          const focusRing = TUVI_BOARD_FOCUS_PALACE_KEYS.has(p.key);
          return (
            <button
              key={palaceKey}
              type="button"
              style={{ gridArea: area }}
              aria-pressed={selected}
              onClick={() => onSelectPalace(p.key)}
              className={`flex min-h-[2.85rem] flex-col items-stretch justify-center rounded-[6px] px-1.5 py-1.5 text-center transition-[background-color,box-shadow,border-color] duration-200 ${
                selected ?
                  MINI_SELECTED
                : `border ${tierQuietClass(tier)} bg-[#080c18]/90 text-slate-300 hover:border-[#d4af37]/28 hover:bg-[#0a1024]/95 hover:text-slate-100 ${
                    focusRing ? "ring-1 ring-[#d4af37]/10" : ""
                  }`
              }`}
            >
              <span className="line-clamp-2 font-ctkp-serif text-[9px] font-normal leading-[1.25] tracking-[0.02em] sm:text-[10px]">
                {p.name}
              </span>
              <span
                className={`mt-0.5 tabular-nums font-sans text-[8px] ${selected ? "text-[#d4af37]/70" : "text-slate-500/85"}`}
              >
                {idx}/12
              </span>
            </button>
          );
        })}

        <div
          className="flex min-h-[5.75rem] flex-col items-center justify-center gap-0.5 rounded-[6px] border border-[#d4af37]/12 bg-[linear-gradient(168deg,rgba(36,48,78,0.35)_0%,rgba(12,18,36,0.82)_100%)] px-2 py-1 text-center shadow-[inset_0_0_0_1px_rgba(255,245,220,0.06)]"
          style={{ gridArea: TUVI_CHART_BOARD_LAYOUT.centerArea }}
        >
          <span className="font-ctkp-serif text-[8px] uppercase tracking-[0.22em] text-[#d4af37]/45">
            Trung cung
          </span>
          {centerHint ?
            <span className="line-clamp-2 max-w-[8rem] font-ctkp-serif text-[10px] leading-snug text-[#e8dcc0]/88">
              {centerHint}
            </span>
          : (
            <span className="font-ctkp-serif text-[18px] leading-none text-[#d4af37]/25" aria-hidden>
              ◎
            </span>
          )}
        </div>
      </div>
    </div>
  );
}

function StructuredListDesktop({
  slotPalaces,
  palaceOrderIndex,
  selectedPalaceKey,
  onSelectPalace,
}: {
  slotPalaces: TuViPalaceView[];
  palaceOrderIndex: Map<string, number>;
  selectedPalaceKey: string;
  onSelectPalace: (key: string) => void;
}) {
  return (
    <nav aria-label="Danh sách mười hai cung (thứ tự thiên bàn)">
      <ol className="space-y-1.5 rounded-[11px] border border-[#d4af37]/14 bg-[linear-gradient(165deg,rgba(14,20,36,0.72),rgba(4,8,18,0.92))] p-2 shadow-[inset_0_1px_0_rgba(212,175,55,0.08)]">
        {slotPalaces.map((p) => {
          const idx = palaceOrderIndex.get(p.key) ?? 0;
          const selected = p.key === selectedPalaceKey;
          const tier = tierForPalaceView(p);
          const label = tierShortLabel(tier);
          const br = splitPalaceBranchDisplay(p.branch);
          const chiLine = br.han ? `${br.han} ${br.vi}` : br.vi;
          return (
            <li key={p.key}>
              <button
                type="button"
                aria-pressed={selected}
                onClick={() => onSelectPalace(p.key)}
                className={`flex w-full items-start gap-3 rounded-lg border px-3 py-2.5 text-left transition-[background-color,border-color,box-shadow] duration-200 ${
                  selected ?
                    LIST_SELECTED
                  : `border-white/[0.06] bg-[#060912]/55 hover:border-[#d4af37]/22 hover:bg-[#0a1020]/85 ${tierQuietClass(tier)}`
                }`}
              >
                <span
                  className={`mt-0.5 tabular-nums font-sans text-[11px] ${selected ? "text-[#d4af37]/85" : "text-slate-500"}`}
                >
                  {idx}
                </span>
                <span className="min-w-0 flex-1">
                  <span className="flex flex-wrap items-baseline gap-x-2 gap-y-0">
                    <span className="font-ctkp-serif text-[14px] tracking-[0.03em] text-slate-100">{p.name}</span>
                    {label ?
                      <span className="rounded border border-[#d4af37]/22 bg-[#d4af37]/08 px-1.5 py-px font-ctkp-serif text-[9px] uppercase tracking-[0.14em] text-[#e8d9a8]/85">
                        {label}
                      </span>
                    : null}
                  </span>
                  <span className="mt-0.5 block truncate font-sans text-[11px] text-slate-500">{chiLine}</span>
                </span>
              </button>
            </li>
          );
        })}
      </ol>
    </nav>
  );
}
