import type { CSSProperties, ReactNode } from "react";

import type { TuViPalaceView, TuViProfileView } from "@/lib/tuvi-chart-view-model";

import {
  TUVI_BRANCH_GRID_SLOT_INDICES,
  TUVI_BRANCH_GRID_TEMPLATE_AREAS,
  TUVI_CHART_BOARD_LAYOUT,
  tuViBranchGridAreaFromIndex,
} from "./tuvi-chart-layout";
import { TuViCenterProfile } from "./TuViCenterProfile";
import { TuViPalaceCard, tierForPalaceView } from "./TuViPalaceCard";
import { TuViSummaryBar, type TuViSummaryItem } from "./TuViSummaryBar";

/**
 * Thiên bàn — chiến lược breakpoint (cố ý, không dựa nhầm `sm`):
 * - `< md` (0–767px): trung cung → tóm tắt → **2 cột** cung
 * - `md .. lg` (768–1023px): trung cung → tóm tắt → **3 cột** cung
 * - `lg+` (1024px+): lưới 4×4 cổ điển, trung cung 2×2
 */

const BOARD_GRID_STYLE: CSSProperties = {
  gridTemplateAreas: TUVI_BRANCH_GRID_TEMPLATE_AREAS,
  /** Cột / hàng đều `1fr` — ô vuông cùng kích thước, không phình theo nội dung (nội dung cuộn trong ô). */
  gridTemplateColumns: "repeat(4, minmax(0, 1fr))",
  gridTemplateRows: "repeat(4, minmax(0, 1fr))",
};

type CenterProfileFields = {
  chartTitle?: string;
  viewingYear?: number;
  fullName: string;
  birthYear: number | null;
  birthDateText: string;
  birthYearDetailText?: string | null;
  birthMonthDetailText?: string | null;
  birthDayDetailText?: string | null;
  birthHourText: string;
  genderText?: string | null;
  amDuongText?: string | null;
  ageLine?: string | null;
  menhDisplay: string;
  cucDisplay: string;
  thanCuText?: string | null;
  menhChuText?: string | null;
  thanChuText?: string | null;
  tagline?: string | null;
  lunarYearText?: string | null;
};

type PalaceBranchNode = { branchIndex: number; p: TuViPalaceView; idx: number };

function ChartCenterCell({
  profile,
  className = "",
  style,
}: {
  profile: CenterProfileFields;
  className?: string;
  style?: CSSProperties;
}) {
  return (
    <div
      className={[
        "ctkp-tuvi-chart-center-cell relative flex min-h-0 min-w-0 flex-col overflow-x-hidden overflow-y-visible rounded-none border border-[rgba(72,50,28,0.55)] bg-[color:var(--tuvi-chart-paper-raised)] p-2 shadow-none",
        className,
      ].join(" ")}
      style={style}
    >
      <div className="ctkp-tuvi-chart-center-inner flex min-h-0 w-full flex-col justify-start gap-1">
        <TuViCenterProfile className="relative z-[1] min-h-0 w-full shrink-0" {...profile} />
      </div>
    </div>
  );
}

function PalaceStackBlocks({
  palaceNodes,
  selectedPalaceKey,
  onSelectPalace,
  wrapperClassName,
  maxWidthClassName,
  centerMinHClassName,
  summaryBarClassName,
  palaceGridClassName,
  palaceShellClassName,
  radialBg,
  centerProfileFields,
  summaryItems,
}: {
  palaceNodes: PalaceBranchNode[];
  selectedPalaceKey: string;
  onSelectPalace?: (key: string) => void;
  wrapperClassName: string;
  maxWidthClassName: string;
  centerMinHClassName: string;
  summaryBarClassName: string;
  palaceGridClassName: string;
  palaceShellClassName: string;
  radialBg: ReactNode;
  centerProfileFields: CenterProfileFields;
  summaryItems?: readonly TuViSummaryItem[];
}) {
  return (
    <div className={wrapperClassName}>
      <div className={`relative mx-auto w-full ${maxWidthClassName}`}>
        {radialBg}
        <div className="relative z-[1] flex flex-col gap-4 md:gap-3">
          <ChartCenterCell
            profile={centerProfileFields}
            className={`${centerMinHClassName} shadow-[0_8px_36px_-10px_rgba(0,0,0,0.55),0_0_64px_-14px_rgba(255,230,190,0.18)]`}
          />

          {summaryItems?.length ?
            <TuViSummaryBar items={summaryItems} className={summaryBarClassName} />
          : null}

          <div>
            <p className="mb-2 font-ctkp-serif text-[10px] font-semibold tracking-wide text-stone-700 md:mb-1.5">
              Mười hai cung
            </p>
            <div className={`${palaceGridClassName} items-stretch`}>
              {palaceNodes.map(({ branchIndex, p, idx }) => (
                <div key={`${branchIndex}-${p.key}`} className={`${palaceShellClassName} min-h-0`}>
                  <TuViPalaceCard
                    palace={p}
                    indexOneBased={idx}
                    tier={tierForPalaceView(p)}
                    selected={selectedPalaceKey === p.key}
                    onSelect={onSelectPalace ? () => onSelectPalace(p.key) : undefined}
                    className="h-full min-h-0 min-w-0"
                  />
                </div>
              ))}
            </div>
          </div>
        </div>
      </div>
    </div>
  );
}

type Props = {
  palaces: TuViPalaceView[];
  profile: TuViProfileView;
  /** Tiêu đề lá / trung cung (vd. tiêu đề bản đọc). */
  centerChartTitle?: string;
  /** Năm dương đang xem (niên hiện tại). */
  viewingYear?: number;
  centerMenhDisplay: string;
  centerAgeLine: string;
  centerTagline?: string;
  palaceOrderIndex: Map<string, number>;
  /** Luôn khớp một ô trên lưới — mặc định nên là `menh` */
  selectedPalaceKey: string;
  onSelectPalace?: (key: string) => void;
  footnote?: string;
  /** Dòng giải thích ngắn bên dưới tiêu đề thiên bàn */
  arenaSubtitle?: string;
  /** Tóm tắt trong bản xếp (`< lg`); trên `lg` dùng thanh ngoài `hidden lg:block` trên trang. */
  summaryItems?: readonly TuViSummaryItem[];
  className?: string;
};

export function TuViChartBoard({
  palaces,
  profile,
  centerChartTitle,
  viewingYear,
  centerMenhDisplay,
  centerAgeLine,
  centerTagline,
  palaceOrderIndex,
  selectedPalaceKey,
  onSelectPalace,
  footnote,
  arenaSubtitle,
  summaryItems,
  className = "",
}: Props) {
  const palaceByBranchIndex = new Map<number, TuViPalaceView>();
  for (const p of palaces) {
    if (typeof p.earthlyBranchIndex !== "number" || !Number.isFinite(p.earthlyBranchIndex)) continue;
    palaceByBranchIndex.set(((p.earthlyBranchIndex % 12) + 12) % 12, p);
  }

  const centerProfileFields: CenterProfileFields = {
    chartTitle: centerChartTitle,
    viewingYear,
    fullName: profile.fullName,
    birthYear: profile.birthYear,
    birthDateText: profile.birthDateText,
    birthYearDetailText: profile.birthYearDetailText,
    birthMonthDetailText: profile.birthMonthDetailText,
    birthDayDetailText: profile.birthDayDetailText,
    birthHourText: profile.birthHourText,
    genderText: profile.genderText,
    amDuongText: profile.amDuongText,
    ageLine: centerAgeLine,
    menhDisplay: centerMenhDisplay,
    cucDisplay: profile.cucText ?? "—",
    thanCuText: profile.thanCuText,
    menhChuText: profile.menhChuText,
    thanChuText: profile.thanChuText,
    tagline: centerTagline,
    lunarYearText: profile.lunarYearText,
  };

  const palaceNodes: PalaceBranchNode[] = TUVI_BRANCH_GRID_SLOT_INDICES.flatMap((branchIndex) => {
    const p = palaceByBranchIndex.get(branchIndex);
    if (!p) return [];
    const idx = palaceOrderIndex.get(p.key) ?? 0;
    return [{ branchIndex, p, idx }];
  });

  const radialMobile = (
    <div
      className="pointer-events-none absolute left-1/2 top-[20%] z-0 h-[min(52vw,14rem)] w-[min(92vw,22rem)] -translate-x-1/2 rounded-full opacity-[0.06] md:hidden"
      style={{
        background:
          "radial-gradient(circle, rgba(212,175,55,0.5) 0%, rgba(55,80,120,0.12) 45%, transparent 72%)",
      }}
      aria-hidden
    />
  );

  const radialTablet = (
    <div
      className="pointer-events-none absolute left-1/2 top-[12%] z-0 hidden h-[min(38vw,16rem)] w-[min(88vw,36rem)] -translate-x-1/2 rounded-full opacity-[0.055] md:block lg:hidden"
      style={{
        background:
          "radial-gradient(circle, rgba(212,175,55,0.42) 0%, rgba(55,80,120,0.1) 48%, transparent 70%)",
      }}
      aria-hidden
    />
  );

  return (
    <div className={`ctkp-tuvi-chart-arena relative ${className}`}>
      <span className="ctkp-tuvi-chart-corner ctkp-tuvi-chart-corner--tl" aria-hidden />
      <span className="ctkp-tuvi-chart-corner ctkp-tuvi-chart-corner--tr" aria-hidden />
      <span className="ctkp-tuvi-chart-corner ctkp-tuvi-chart-corner--bl" aria-hidden />
      <span className="ctkp-tuvi-chart-corner ctkp-tuvi-chart-corner--br" aria-hidden />

      <div className="relative z-[1] px-3 pb-4 pt-5 md:px-4 md:pb-5 md:pt-5 lg:px-5 lg:pb-6 lg:pt-6">
        <div className="mb-4 flex flex-col gap-2 border-b border-[color:var(--tuvi-chart-border-soft)] pb-4 md:mb-4 lg:mb-5 lg:flex-row lg:items-end lg:justify-between lg:gap-6">
          <div className="min-w-0 text-center lg:text-left">
            <p className="font-ctkp-serif text-[10px] font-normal leading-normal tracking-[0.14em] text-[color:var(--tuvi-chart-orange)] md:text-[11px]">
              Thiên bàn tử vi
            </p>
            <h2
              id="tuvi-chart-board-heading"
              className="mt-1.5 font-ctkp-serif text-sm font-semibold leading-snug tracking-normal text-[color:var(--tuvi-chart-ink)] lg:text-base"
            >
              <span className="lg:hidden">Mười hai cung · chọn ô để luận</span>
              <span className="hidden lg:inline">Mười hai cung quanh trung cung</span>
            </h2>
            <p className="mx-auto mt-1 max-w-md font-sans text-[10px] leading-relaxed text-[color:var(--tuvi-chart-ink-muted)] lg:mx-0 lg:max-w-lg lg:text-[11px]">
              <span className="lg:hidden">Trên màn hình nhỏ: trung cung và lưới cung xếp dọc để đọc rõ.</span>
              <span className="hidden lg:inline">
                Lưới 4×4 cổ điển: trung cung là hồ sơ; các ô xung quanh là mười hai cung.
              </span>
            </p>
          </div>
          {arenaSubtitle ?
            <p className="max-w-lg text-center font-sans text-[11px] leading-relaxed text-[color:var(--tuvi-chart-ink-muted)] lg:text-right">
              {arenaSubtitle}
            </p>
          : null}
        </div>

        {/* Phone: < md — 2 cột */}
        <PalaceStackBlocks
          palaceNodes={palaceNodes}
          selectedPalaceKey={selectedPalaceKey}
          onSelectPalace={onSelectPalace}
          wrapperClassName="md:hidden"
          maxWidthClassName="max-w-[28rem]"
          centerMinHClassName="min-h-[13rem]"
          summaryBarClassName="[&_.rounded-md]:min-h-[3.25rem] [&_.rounded-md]:py-3"
          palaceGridClassName="grid grid-cols-2 gap-2.5"
          palaceShellClassName="flex min-h-[13.5rem] min-w-0 flex-col bg-transparent"
          radialBg={
            <>
              {radialMobile}
              {radialTablet}
            </>
          }
          centerProfileFields={centerProfileFields}
          summaryItems={summaryItems}
        />

        {/* Tablet: md .. lg − 1 */}
        <PalaceStackBlocks
          palaceNodes={palaceNodes}
          selectedPalaceKey={selectedPalaceKey}
          onSelectPalace={onSelectPalace}
          wrapperClassName="hidden md:block lg:hidden"
          maxWidthClassName="max-w-[52rem]"
          centerMinHClassName="min-h-[12rem]"
          summaryBarClassName="[&_.rounded-md]:min-h-[3rem] [&_.rounded-md]:py-2.5"
          palaceGridClassName="grid grid-cols-3 gap-2"
          palaceShellClassName="flex min-h-[12.75rem] min-w-0 flex-col bg-transparent"
          radialBg={
            <>
              {radialMobile}
              {radialTablet}
            </>
          }
          centerProfileFields={centerProfileFields}
          summaryItems={summaryItems}
        />

        {/* Canonical chart UI: large screens use the printed 4x4 Nam Phái board. */}
        <section className="hidden lg:block" aria-labelledby="tuvi-chart-board-heading">
          <div className="ctkp-tuvi-chart-board-scroll w-full max-w-full min-w-0 pb-1">
            <div className="ctkp-tuvi-board-print-wrap relative mx-auto w-full max-w-full min-w-0">
              <div
                className="ctkp-tuvi-board-4x4 relative z-[1] mx-auto w-full grid border border-[rgba(72,50,28,0.62)] bg-[color:var(--tuvi-chart-paper)] shadow-none"
                style={BOARD_GRID_STYLE}
              >
                {TUVI_BRANCH_GRID_SLOT_INDICES.map((branchIndex) => {
                  const p = palaceByBranchIndex.get(branchIndex);
                  const area = tuViBranchGridAreaFromIndex(branchIndex);
                  if (!p || !area) return null;
                  const idx = palaceOrderIndex.get(p.key) ?? 0;
                  return (
                    <div
                      key={`${branchIndex}-${p.key}`}
                      className="ctkp-tuvi-board-cell flex min-h-0 min-w-0 flex-col items-stretch bg-transparent"
                      style={{ gridArea: area }}
                    >
                      <TuViPalaceCard
                        palace={p}
                        indexOneBased={idx}
                        tier={tierForPalaceView(p)}
                        selected={selectedPalaceKey === p.key}
                        onSelect={onSelectPalace ? () => onSelectPalace(p.key) : undefined}
                        className="box-border h-full min-h-0 w-full max-w-full min-w-0 flex-1 self-stretch"
                      />
                    </div>
                  );
                })}

                <ChartCenterCell
                  profile={centerProfileFields}
                  className="self-stretch h-full min-h-0"
                  style={{ gridArea: TUVI_CHART_BOARD_LAYOUT.centerArea }}
                />
              </div>
            </div>
          </div>
        </section>

        {footnote ?
          <p className="ctkp-tuvi-text-muted relative z-[1] mt-4 pt-4 font-sans text-[11px] leading-relaxed">
            {footnote}
          </p>
        : null}
      </div>
    </div>
  );
}
