"use client";

import { useEffect, useRef } from "react";
import {
  groupWindowTransitions,
  rectificationBoardPeekCopy,
  workingRectificationTime,
  type RectificationBoardDiff,
} from "@/lib/rectification-board-model";
import {
  workingRectificationHouseTable,
  type RectificationCandidateResult,
} from "@/lib/rectification-candidate-result";
import {
  windowScanLayerLabel,
  type WindowScanLayer,
} from "@/lib/rectification-agentic/v9/refinement-packet";
import { RectificationHouseTableView } from "./rectification-house-table";
import { ConfirmationGateDisclosure, TechniqueAuditDisclosure } from "./technique-audit-disclosure";

function LayerChips({ layers }: Readonly<{ layers: readonly WindowScanLayer[] }>) {
  if (layers.length === 0) return null;
  return (
    <ul className="rectification-board__chips">
      {layers.map((layer) => (
        <li key={layer}>
          <span className="rectification-board__chip">{windowScanLayerLabel(layer)}</span>
        </li>
      ))}
    </ul>
  );
}

function RectificationBoardBody({
  result,
  savedStatus,
  diff,
  compact,
  titleId,
  onClose,
}: Readonly<{
  result: RectificationCandidateResult | null;
  savedStatus: "accepted" | "confirmed" | null;
  diff: RectificationBoardDiff;
  compact: boolean;
  titleId: string;
  onClose: () => void;
}>) {
  const table = result ? workingRectificationHouseTable(result) : null;
  const workingTime = workingRectificationTime(result);
  const grouped = result ? groupWindowTransitions(result.windowTransitions) : [];
  const scoringMinutes = grouped.filter((row) => row.scoringLayers.length > 0);
  const displayMinutes = grouped.filter((row) => row.displayLayers.length > 0);
  const changedHouses = new Set(diff.houseNumbers);
  const changedMinutes = new Set(diff.transitionMinutes);
  const stage = result?.precisionStage?.user_meaning
    ?? result?.natalRecast?.user_meaning
    ?? null;
  const ledger = result?.eventDashaLedger ?? [];
  const contrast = result?.lagnaContrast ?? null;
  const agreement = result?.dashaAgreement ?? null;
  const nakshatra = result?.nakshatraBoundary ?? null;

  return (
    <>
      <header className="rectification-board__header">
        <div className="rectification-board__title-row">
          <h2 id={titleId}>当前盘面</h2>
          {workingTime ? <span className="rectification-board__clock">{workingTime}</span> : null}
          {compact && (
            <button
              className="rectification-board__close"
              type="button"
              onClick={onClose}
            >
              关闭盘面
            </button>
          )}
        </div>
        {stage ? <p className="rectification-board__stage">{stage}</p> : null}
      </header>
      <div className="rectification-board__body">
        <p className="sr-only" role="status" aria-live="polite" aria-atomic="true">{diff.liveMessage}</p>
        {!table && (
          <p className="rectification-board__empty">
            补充经历后，这里会显示当前本命宫位和换升时刻。
          </p>
        )}
        {table && (
          <div className="rectification-snapshot">
            <RectificationHouseTableView
              table={table}
              changedHouses={changedHouses}
              lagnaChanged={diff.lagnaChanged}
            />
            {result && <ConfirmationGateDisclosure gate={result.confirmationGate} />}
            {savedStatus === "accepted" && result && result.techniqueAudit.length > 0 && (
              <TechniqueAuditDisclosure rows={result.techniqueAudit} />
            )}
          </div>
        )}
        {(scoringMinutes.length > 0 || displayMinutes.length > 0) && (
          <section className="rectification-board__section" aria-label="换升时刻">
            <h3>换升时刻</h3>
            {scoringMinutes.length > 0 && (
            <ol className="rectification-board__minutes">
              {scoringMinutes.map((row) => {
                const changed = changedMinutes.has(row.at);
                const working = row.at === workingTime;
                return (
                  <li
                    key={row.at}
                    className={[
                      "rectification-board__minute",
                      changed ? "is-changed" : "",
                      working ? "is-working" : "",
                    ].filter(Boolean).join(" ")}
                  >
                    <time dateTime={row.at}>{row.at}</time>
                    {working ? <span className="rectification-board__minute-note">当前时间</span> : null}
                    {changed ? <span className="rectification-board__minute-note">已更新</span> : null}
                    <LayerChips layers={row.scoringLayers} />
                  </li>
                );
              })}
            </ol>
            )}
            {displayMinutes.length > 0 && (
              <details className="technique-audit">
                <summary>
                  显示层
                  <small>{displayMinutes.length} 个时刻</small>
                </summary>
                <ol className="rectification-board__minutes">
                  {displayMinutes.map((row) => (
                    <li
                      key={`display-${row.at}`}
                      className={changedMinutes.has(row.at) ? "rectification-board__minute is-changed" : "rectification-board__minute"}
                    >
                      <time dateTime={row.at}>{row.at}</time>
                      {changedMinutes.has(row.at) ? <span className="rectification-board__minute-note">已更新</span> : null}
                      <LayerChips layers={row.displayLayers} />
                    </li>
                  ))}
                </ol>
              </details>
            )}
          </section>
        )}
        {contrast && (
          <details className="technique-audit">
            <summary>两段本命上升</summary>
            <div className="rectification-board__disclosure">
              <p>{contrast.user_meaning}</p>
              <ul>
                {contrast.intervals.map((interval) => (
                  <li key={`${interval.start}-${interval.end}`}>
                    {interval.start}-{interval.end}：{interval.lagna}
                    {interval.lords.l1 ? `；一/四/七/十宫主 ${[interval.lords.l1, interval.lords.l4, interval.lords.l7, interval.lords.l10].filter(Boolean).join("、")}` : ""}
                  </li>
                ))}
              </ul>
            </div>
          </details>
        )}
        {ledger.length > 0 && (
          <details className="technique-audit">
            <summary>
              经历与大运对照
              <small>{ledger.length} 项</small>
            </summary>
            <ul className="rectification-board__disclosure">
              {ledger.map((item) => (
                <li key={item.summary}>{item.user_meaning}</li>
              ))}
            </ul>
            {agreement ? <p className="rectification-board__disclosure">{agreement.user_meaning}</p> : null}
          </details>
        )}
        {nakshatra?.near_boundary && nakshatra.user_meaning && (
          <details className="technique-audit">
            <summary>交界节奏</summary>
            <p className="rectification-board__disclosure">{nakshatra.user_meaning}</p>
          </details>
        )}
      </div>
    </>
  );
}

export function RectificationBoard({
  result,
  savedStatus,
  diff,
  compact,
  open,
  boardId,
  titleId,
  onClose,
}: Readonly<{
  result: RectificationCandidateResult | null;
  savedStatus: "accepted" | "confirmed" | null;
  diff: RectificationBoardDiff;
  compact: boolean;
  open: boolean;
  boardId: string;
  titleId: string;
  onClose: () => void;
}>) {
  const dialogRef = useRef<HTMLDialogElement>(null);
  const body = (
    <RectificationBoardBody
      result={result}
      savedStatus={savedStatus}
      diff={diff}
      compact={compact}
      titleId={titleId}
      onClose={onClose}
    />
  );

  useEffect(() => {
    const node = dialogRef.current;
    if (!compact || !node) return;
    if (open) {
      if (!node.open) node.showModal();
    } else if (node.open) {
      node.close();
    }
  }, [compact, open]);

  useEffect(() => {
    if (!compact) return;
    const node = dialogRef.current;
    if (!node) return;
    const handleClose = () => onClose();
    node.addEventListener("close", handleClose);
    return () => node.removeEventListener("close", handleClose);
  }, [compact, onClose]);

  if (compact) {
    return (
      <dialog ref={dialogRef} id={boardId} className="rectification-board" aria-labelledby={titleId}>
        {body}
      </dialog>
    );
  }

  return (
    <aside id={boardId} className="rectification-board" aria-labelledby={titleId}>
      {body}
    </aside>
  );
}

export function RectificationBoardPeek({
  result,
  expanded,
  boardId,
  onOpen,
}: Readonly<{
  result: RectificationCandidateResult | null;
  expanded: boolean;
  boardId: string;
  onOpen: () => void;
}>) {
  const peek = rectificationBoardPeekCopy(result);
  return (
    <button
      className="rectification-board-peek"
      type="button"
      aria-expanded={expanded}
      aria-controls={boardId}
      onClick={onOpen}
    >
      <strong>{peek.title}</strong>
      <span>{peek.detail}</span>
    </button>
  );
}
