import type { TuViStarView } from "@/lib/tuvi-chart-view-model";
import type { StarTone } from "@/lib/tuvi-star-classification";

import type { TuViStarChipWeight } from "./tuvi-star-chip-styles";

type Props = {
  stars: TuViStarView[];
  /** `major` = larger, stronger; `minor` = compact, wraps tightly. */
  variant?: TuViStarChipWeight;
  /** @deprecated Dùng `variant="minor"`. */
  dense?: boolean;
  className?: string;
  palaceBranchVi?: string;
};

const STAR_STATUS_BY_BRANCH: Readonly<Record<string, Readonly<Record<string, string>>>> = {
  suu: {
    thai_duong: "Đ",
    thai_am: "Đ",
  },
  thin: {
    tu_vi: "V",
    thien_tuong: "V",
  },
  mao: {
    thien_co: "M",
    cu_mon: "M",
  },
};

const WEALTH_OR_TRANSFORM_STAR_KEYS = new Set([
  "loc_ton",
  "hoa_loc",
  "hoa_quyen",
  "hoa_khoa",
  "hoa_ky",
  "thien_quy",
  "thien_khoi",
  "thien_viet",
  "thai_phu",
  "thien_quan",
  "thien_phuc",
  "thien_duc",
  "an_quang",
  "duong_phu",
  "quoc_an",
  "tam_thai",
  "phong_cao",
  "thien_tho",
  "dao_hoa",
  "hong_loan",
  "thien_hy",
  "thien_y",
  "luu_loc_ton",
  "luu_hoa_loc",
]);
const HARMFUL_STAR_KEYS = new Set([
  "that_sat",
  "pha_quan",
  "liem_trinh",
  "tham_lang",
  "cu_mon",
  "kinh_duong",
  "da_la",
  "hoa_tinh",
  "linh_tinh",
  "dia_khong",
  "dia_kiep",
  "kiep_sat",
  "tue_pha",
  "tang_mon",
  "bach_ho",
  "pha_toai",
  "thien_khoc",
  "thien_khong",
  "dia_vong",
  "luu_ha",
  "luu_kinh_duong",
  "luu_da_la",
  "luu_phuc_binh",
  "luu_thien_khoc",
  "luu_thien_hu",
  "luu_hoa_ky",
  "luu_tang_mon",
  "luu_bach_ho",
  "thien_thuong",
  "thien_su",
]);

const SECONDARY_STAR_KEYS = new Set([
  "thien_la",
  "thien_hu",
  "truc_phu",
  "benh_phu",
  "dieu_khach",
  "tu_phu",
  "phuc_binh",
  "hong_loan",
  "dao_hoa",
  "luu_thai_tue",
  "luu_thien_ma",
  "luu_phuc_binh",
  "dau_quan",
]);

function normalizeBranchKey(branchVi?: string): string {
  return (branchVi ?? "")
    .trim()
    .toLowerCase()
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .replace(/đ/g, "d")
    .replace(/\s+/g, "_");
}

function statusForStar(starKey: string, palaceBranchVi?: string): string | undefined {
  return STAR_STATUS_BY_BRANCH[normalizeBranchKey(palaceBranchVi)]?.[starKey];
}

function getStarDisplayColor(starKey: string, tone: StarTone, status?: string, role: TuViStarChipWeight = "minor"): string {
  if (status === "H") return "var(--tuvi-chart-vermilion)";
  if (starKey === "thai_duong" && status === "Đ") return "var(--tuvi-chart-vermilion)";
  if (status === "M" || status === "V") return "var(--tuvi-chart-good)";
  if (WEALTH_OR_TRANSFORM_STAR_KEYS.has(starKey)) return "var(--tuvi-chart-orange)";
  if (HARMFUL_STAR_KEYS.has(starKey)) return "var(--tuvi-chart-vermilion)";
  if (tone === "good") return "var(--tuvi-chart-good)";
  if (tone === "bad") return "var(--tuvi-chart-vermilion)";
  if (SECONDARY_STAR_KEYS.has(starKey)) return "var(--tuvi-chart-weak)";
  return role === "major" ? "var(--tuvi-chart-ink)" : "var(--tuvi-chart-ink)";
}

function starDisplayName(star: TuViStarView, palaceBranchVi?: string): string {
  const name = (star.name ?? star.key).trim() || star.key;
  const status = statusForStar(star.key, palaceBranchVi);
  return status ? `${name} (${status})` : name;
}

function tuHoaLabelVi(t: NonNullable<TuViStarView["tuHoa"]>): string {
  switch (t) {
    case "hoa_loc":
      return "Hóa Lộc";
    case "hoa_quyen":
      return "Hóa Quyền";
    case "hoa_khoa":
      return "Hóa Khoa";
    case "hoa_ky":
      return "Hóa Kỵ";
  }
}

function starTitleFallback(star: TuViStarView): string {
  const name = (star.name ?? star.key).trim();
  const mean = star.meaningShort?.trim();
  const hoa = star.tuHoa ? ` — ${tuHoaLabelVi(star.tuHoa)}` : "";
  if (mean) return `${name}${hoa} — ${mean}`;
  return `${name}${hoa}`;
}

function StarText({
  star,
  variant,
  palaceBranchVi,
}: {
  star: TuViStarView;
  variant: TuViStarChipWeight;
  palaceBranchVi?: string;
}) {
  const isMajor = variant === "major";
  const displayName = starDisplayName(star, palaceBranchVi);
  const tipName =
    star.tuHoa ? `${displayName} (${tuHoaLabelVi(star.tuHoa)})` : displayName;
  const tipMean = star.meaningShort?.trim();
  const titleFallback = starTitleFallback(star);
  const hoaLong = star.tuHoa ? tuHoaLabelVi(star.tuHoa) : "";
  const status = statusForStar(star.key, palaceBranchVi);
  const color = getStarDisplayColor(star.key, star.tone, status, variant);

  return (
    <span
      className={
        isMajor ?
          "ctkp-tuvi-major-plaque"
        : "relative inline-block min-w-0 max-w-full"
      }
    >
      <span
        className={[
          "peer relative z-0 cursor-default select-none",
          isMajor ?
            "ctkp-tuvi-major-text"
          : "ctkp-tuvi-minor-text",
        ].join(" ")}
        style={{ color }}
        title={titleFallback}
      >
        {displayName}
        {hoaLong ? (
          <span className="ml-0.5 whitespace-nowrap font-sans text-[0.8em] font-bold text-[color:var(--tuvi-chart-orange)]">
            {hoaLong}
          </span>
        ) : null}
      </span>
      <span
        className={[
          "pointer-events-none absolute left-1/2 z-[80] mt-1.5 w-max max-w-[min(17rem,calc(100vw-1.5rem))] -translate-x-1/2",
          "top-full rounded border border-[#222]/20 bg-[#f7f0dc] px-2.5 py-2",
          "text-left font-sans text-[11px] leading-[1.55] text-[#222] shadow-[0_12px_28px_-12px_rgba(0,0,0,0.32)]",
          "opacity-0 transition-[opacity,transform] duration-150 ease-out",
          "-translate-y-1 peer-hover:translate-y-0 peer-hover:opacity-100",
        ].join(" ")}
        role="tooltip"
      >
        <span className="block font-ctkp-serif text-[12px] font-semibold tracking-normal text-[#222]">
          {tipName}
        </span>
        {tipMean ?
          <span className="mt-1 block text-[10.5px] font-normal leading-[1.6] text-[#777] sm:text-[11px]">
            {tipMean}
          </span>
        : null}
      </span>
    </span>
  );
}

export function TuViStarChips({ stars, variant: variantProp, dense, className = "", palaceBranchVi }: Props) {
  if (stars.length === 0) return null;
  const variant: TuViStarChipWeight = variantProp ?? (dense ? "minor" : "major");
  const isMajor = variant === "major";

  if (isMajor) {
    return (
      <ul
        className={[
          "flex flex-col items-center gap-1.5 text-center",
          className,
        ].join(" ")}
        aria-label="Sao chính trên cung"
      >
        {stars.map((s) => (
          <li
            key={s.key}
            data-tuvi-star-key={s.key}
            data-tuvi-star-name={s.name}
            data-tuvi-star-variant="major"
            className="mx-auto min-w-0 max-w-full list-none"
          >
            <StarText star={s} variant="major" palaceBranchVi={palaceBranchVi} />
          </li>
        ))}
      </ul>
    );
  }

  return (
    <ul
      className={[
        "grid w-full min-w-0 list-none grid-cols-2 gap-x-2 gap-y-0.5 text-left",
        className,
      ].join(" ")}
      aria-label="Sao phụ trên cung"
    >
      {stars.map((s) => (
        <li
          key={s.key}
          data-tuvi-star-key={s.key}
          data-tuvi-star-name={s.name}
          data-tuvi-star-variant="minor"
          className="min-w-0 max-w-full list-none overflow-visible"
        >
          <StarText star={s} variant="minor" palaceBranchVi={palaceBranchVi} />
        </li>
      ))}
    </ul>
  );
}
