"use client";

import { useEffect, useState } from "react";

import { AiInterpretPanel } from "@/components/AiInterpretPanel";
import { CtkpResultPageNav } from "@/components/CtkpResultPageNav";
import { CtkpCompactLoading, CtkpUnavailableResult } from "@/components/CtkpPublicStates";
import { HexagramBlock } from "../HexagramBlock";
import {
  changingLinePositions,
  ensureGieoQueResultStruct,
  ensureStandardQueResult,
  haoLabel,
  isGieoQueV2,
  type FortuneStoredPayload,
  type GieoQuePayloadV2,
  type QueHexagramClassicalText,
  type QueReadingStructuredV1,
} from "@/lib/gieo-que";
import { FORTUNE_RESULT_KEY, type FortuneResponse } from "@/lib/fortune";

function isValidFortuneStored(x: unknown): x is FortuneStoredPayload {
  if (!x || typeof x !== "object") return false;
  const o = x as Record<string, unknown>;
  if (o.v === 2) {
    return (
      typeof o.receivedAt === "string" &&
      Array.isArray(o.mainLines) &&
      o.mainLines.length === 6 &&
      Array.isArray(o.derivedLines) &&
      o.derivedLines.length === 6 &&
      o.reading !== null &&
      typeof o.reading === "object"
    );
  }
  if (typeof o.id !== "string" || typeof o.receivedAt !== "string") return false;
  if (!o.subject || typeof o.subject !== "object") return false;
  const s = o.subject as Record<string, unknown>;
  if (typeof s.name !== "string" || typeof s.birthDate !== "string" || typeof s.birthTime !== "string") return false;
  if (!o.reading || typeof o.reading !== "object") return false;
  const r = o.reading as Record<string, unknown>;
  return typeof r.title === "string" && typeof r.opening === "string" && Array.isArray(r.verses);
}

const genderLabel: Record<string, string> = {
  male: "Nam",
  female: "Nữ",
  other: "Khác",
};

type FortuneResultViewState =
  | { kind: "loading" }
  | { kind: "missing" }
  | { kind: "invalid" }
  | { kind: "ready"; data: FortuneStoredPayload };

const manuscriptProse =
  "font-ctkp-serif text-[1.0625rem] sm:text-[1.125rem] leading-[1.85] text-stone-400/95 tracking-[0.01em]";

/** Khung trích kinh / luận — cùng hệ chữ, viền mờ như lề sách. */
const manuscriptInset =
  "rounded-sm border border-stone-700/22 bg-stone-950/[0.28] px-5 py-6 shadow-[inset_0_1px_0_0_rgba(255,255,255,0.03)] sm:px-7 sm:py-7";

const manuscriptInsetLabel =
  "font-ctkp-display text-[0.65rem] font-normal uppercase tracking-[0.16em] text-stone-500 sm:text-[11px]";

export default function FortuneResultPage() {
  const [state, setState] = useState<FortuneResultViewState>({ kind: "loading" });

  useEffect(() => {
    queueMicrotask(() => {
      try {
        const raw = sessionStorage.getItem(FORTUNE_RESULT_KEY);
        if (!raw) {
          setState({ kind: "missing" });
          return;
        }
        const parsed: unknown = JSON.parse(raw);
        if (!isValidFortuneStored(parsed)) {
          setState({ kind: "invalid" });
          return;
        }
        setState({ kind: "ready", data: parsed });
      } catch {
        setState({ kind: "invalid" });
      }
    });
  }, []);

  if (state.kind === "loading") {
    return (
      <main className="ctkp-result-canvas min-h-[100dvh]">
        <CtkpCompactLoading embedded title="Đang dỡ quẻ ra xem…" subtitle="Lấy lại quẻ đã gieo trên trình duyệt này." />
      </main>
    );
  }

  if (state.kind === "missing") {
    return (
      <main className="ctkp-result-canvas min-h-[100dvh]">
        <div className="mx-auto max-w-[760px] px-5 py-16 sm:px-8 sm:py-20">
          <CtkpUnavailableResult
            embedded
            title="Chưa có quẻ để mở"
            body="Trang này đọc kết quả từ phiên gieo gần nhất. Nếu bạn chưa gieo, hoặc đã xóa dữ liệu trình duyệt, hãy gieo lại từ đầu."
            primaryHref="/fortune"
            primaryLabel="Về gieo quẻ"
            secondaryHref="/fortune/history"
            secondaryLabel="Nhật ký"
          />
        </div>
      </main>
    );
  }

  if (state.kind === "invalid") {
    return (
      <main className="ctkp-result-canvas min-h-[100dvh]">
        <div className="mx-auto max-w-[760px] px-5 py-16 sm:px-8 sm:py-20">
          <CtkpUnavailableResult
            embedded
            title="Không đọc được kết quả"
            body="Dấu quẻ trong trình duyệt không đủ hoặc từ bản cũ. Thử mở lại từ nhật ký nếu đã lưu, hoặc gieo một quẻ mới."
            primaryHref="/fortune"
            primaryLabel="Gieo quẻ mới"
            secondaryHref="/fortune/history"
            secondaryLabel="Nhật ký"
          />
        </div>
      </main>
    );
  }

  const { data } = state;
  if (isGieoQueV2(data)) {
    return <GieoQueResultView payload={data} />;
  }

  return <LegacyFortuneResultView data={data as FortuneResponse} />;
}

function ClassicalHexPanel({
  id,
  title,
  lead,
  hex,
}: {
  id: string;
  title: string;
  lead: string;
  hex: QueHexagramClassicalText;
}) {
  const hasJudgment = hex.judgment_vi.trim().length > 0;
  const hasImage = hex.image_vi.trim().length > 0;
  if (!hasJudgment && !hasImage) {
    return (
      <section className="mt-14 sm:mt-16" aria-labelledby={id}>
        <h2
          id={id}
          className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
        >
          {title}
        </h2>
        <p className={`${manuscriptProse} mt-5 text-stone-600`}>
          Chưa có trích thoán / tượng cho quẻ này trong kho hiện tại.
        </p>
        <hr className="ctkp-result-section-divider mt-12 sm:mt-14" aria-hidden />
      </section>
    );
  }
  return (
    <section className="mt-14 sm:mt-16" aria-labelledby={id}>
      <h2
        id={id}
        className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
      >
        {title}
      </h2>
      <p className={`${manuscriptProse} mt-5 text-stone-600`}>{lead}</p>
      <div className={`${manuscriptInset} mt-8`}>
        <p className="font-ctkp-serif text-[12px] text-stone-500">
          «{hex.name_han}» · {hex.name_vi}
          <span className="tabular-nums text-stone-600"> · Văn Vương {hex.king_wen_number}</span>
        </p>
        <div className="mt-8 space-y-8">
          {hasJudgment ? (
            <div>
              <h3 className={manuscriptInsetLabel}>Thoán</h3>
              <p className={`${manuscriptProse} mt-3 text-stone-400/95`}>{hex.judgment_vi}</p>
            </div>
          ) : null}
          {hasImage ? (
            <div>
              <h3 className={manuscriptInsetLabel}>Tượng</h3>
              <p className={`${manuscriptProse} mt-3 text-stone-500`}>{hex.image_vi}</p>
            </div>
          ) : null}
        </div>
      </div>
      <hr className="ctkp-result-section-divider mt-12 sm:mt-14" aria-hidden />
    </section>
  );
}

function QueStructuredInterpretSection({
  structured,
  textSource,
}: {
  structured: QueReadingStructuredV1;
  textSource?: string;
}) {
  const rows: { k: keyof QueReadingStructuredV1; label: string }[] = [
    { k: "y_chinh", label: "Ý chính" },
    { k: "xu_huong", label: "Xu hướng" },
    { k: "nen_lam", label: "Điều nên làm" },
    { k: "nen_tranh", label: "Điều nên tránh" },
  ];
  return (
    <section className="mt-14 sm:mt-16" aria-labelledby="que-structured-heading">
      <h2
        id="que-structured-heading"
        className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
      >
        Luận theo quy tắc
      </h2>
      <p className={`${manuscriptProse} mt-5 text-stone-600`}>
        Bốn hướng dẫn được tính cố định từ hình quẻ, kinh văn đã trích và tỉ lệ âm–dương (không dùng mô hình ngôn ngữ).
        {textSource ? (
          <span className="mt-2 block font-ctkp-serif text-[12px] text-stone-500">Phiên bản luận: {textSource}</span>
        ) : null}
      </p>
      <div className={`${manuscriptInset} mt-8`}>
        <dl className="space-y-10">
          {rows.map(({ k, label }) => (
            <div key={k} className="border-t border-stone-700/15 pt-8 first:border-t-0 first:pt-0">
              <dt className="font-ctkp-display text-[0.8rem] font-normal tracking-wide text-stone-500 sm:text-sm">
                {label}
              </dt>
              <dd className={`${manuscriptProse} mt-3 text-stone-400/95`}>{structured[k]}</dd>
            </div>
          ))}
        </dl>
      </div>
      <hr className="ctkp-result-section-divider mt-12 sm:mt-14" aria-hidden />
    </section>
  );
}

function GieoQueResultView({ payload }: { payload: GieoQuePayloadV2 }) {
  const rs = ensureGieoQueResultStruct(payload);
  const que = ensureStandardQueResult(payload);
  const positions = changingLinePositions(payload.mainLines);
  const motionViByPosition = new Map<number, string>();
  for (const c of que.changing_lines) {
    if (c.motion_vi) motionViByPosition.set(c.position, c.motion_vi);
  }
  const haoTuByPosition = new Map(que.line_texts.map((lt) => [lt.position, lt.hao_tu_vi]));
  const sameKingWen = rs.main.kingWenNumber === rs.derived.kingWenNumber;
  const receivedLabel = new Date(payload.receivedAt).toLocaleString("vi-VN", {
    day: "numeric",
    month: "long",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
  const prep = payload.ctkp_interpret_prep as { summary_short?: string } | undefined;

  return (
    <main className="ctkp-result-canvas min-h-[100dvh]">
      <div className="mx-auto max-w-[760px] px-5 py-16 pb-28 sm:px-8 sm:py-20 sm:pb-32">
        <CtkpResultPageNav backHref="/fortune" backLabel="← quay lại" />

        <header className="mt-10 sm:mt-12">
          <p className="font-ctkp-serif text-[11px] uppercase tracking-[0.12em] text-stone-500">Kết quả gieo quẻ</p>
          <h1 className="mt-2 font-ctkp-display text-pretty text-[clamp(1.25rem,3.8vw,1.7rem)] font-normal leading-snug tracking-wide text-stone-200">
            Quẻ {rs.main.kingWenNumber} — {rs.main.nameHan}
          </h1>
          <p className="mt-1 font-ctkp-serif text-sm text-stone-500">{rs.main.nameVi}</p>
          <p className="mt-4 font-ctkp-serif text-sm text-stone-600">{receivedLabel}</p>
          <p className={`${manuscriptProse} mt-5 text-stone-600`}>
            <span className="text-stone-500">Cách gieo.</span> {payload.methodLabel}. Hào động chỉ đánh dấu trên{" "}
            <span className="text-stone-500">quẻ chính</span>; cột kế là <span className="text-stone-500">quẻ biến</span>{" "}
            sau khi đảo các hào đó.
          </p>
          {prep?.summary_short ? (
            <p className={`${manuscriptProse} mt-5 border-l border-stone-600/25 pl-4 text-stone-500`}>{prep.summary_short}</p>
          ) : null}
          <hr className="ctkp-result-section-divider mt-10 opacity-90" aria-hidden />
        </header>

        <section className="mt-14 sm:mt-16" aria-labelledby="hex-pair-heading">
          <h2
            id="hex-pair-heading"
            className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
          >
            Hai hình — chủ và biến
          </h2>
          <p className={`${manuscriptProse} mt-5 text-stone-600`}>
            Trái: hình vừa gieo. Phải: hình sau khi các hào động đổi âm–dương. Một dòng thời, hai tầng ý — đối chiếu
            trước khi đọc kinh văn.
          </p>
          <p className={`${manuscriptProse} mt-5 text-stone-500`}>{que.relation_summary_vi}</p>
          <div className="mt-10 grid gap-12 lg:grid-cols-2 lg:items-start lg:gap-14">
            <HexagramBlock
              variant="primary"
              title={rs.main.nameHan}
              subtitle={`Số ${rs.main.kingWenNumber} · ${rs.main.nameVi} — từ sơ hào lên thượng hào`}
              lines={payload.mainLines}
            />
            <HexagramBlock
              variant="derived"
              title={rs.derived.nameHan}
              subtitle={`Số ${rs.derived.kingWenNumber} · ${rs.derived.nameVi} — sau khi đảo các hào động`}
              lines={payload.derivedLines}
            />
          </div>
          <hr className="ctkp-result-section-divider mt-14 sm:mt-16" aria-hidden />
        </section>

        <ClassicalHexPanel
          id="classical-main-heading"
          title="Kinh quẻ chính"
          lead="Thoán và tượng gắn với hình chủ — trích trong ứng dụng (cùng nguồn Kinh Dịch / bản dịch đã chọn cho CTKP)."
          hex={que.hexagram_text}
        />

        <section className="mt-14 sm:mt-16" aria-labelledby="changing-heading">
          <h2
            id="changing-heading"
            className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
          >
            Hào động và hào từ
          </h2>
          <p className={`${manuscriptProse} mt-5 text-stone-600`}>
            Ba đồng quyết định hào nào động. Dưới đây là chiều âm–dương chuyển và trích hào từ (khi có trong kho) cho
            từng hào đang động.
          </p>
          {positions.length === 0 ? (
            <p className={`${manuscriptProse} mt-8 text-stone-600`}>
              Lần này không có hào động — toàn bộ ý nằm trong quẻ chính; quẻ biến trùng hình. Không trích hào từ riêng
              lẻ.
            </p>
          ) : (
            <ul className="mt-8 list-none space-y-10">
              {positions.map((p) => {
                const haoTu = (haoTuByPosition.get(p) ?? "").trim();
                return (
                  <li key={p} className={manuscriptInset}>
                    <div className="flex flex-col gap-1 sm:flex-row sm:items-baseline sm:justify-between sm:gap-4">
                      <span className="font-ctkp-display text-base font-normal text-stone-300">
                        {haoLabel(p)}{" "}
                        <span className="font-ctkp-serif text-sm font-normal text-stone-600"> · vị {p}</span>
                      </span>
                      <span className="font-ctkp-serif text-[11px] uppercase tracking-wide text-stone-500">động</span>
                    </div>
                    {motionViByPosition.get(p) ? (
                      <p className={`${manuscriptProse} mt-4 text-stone-500`}>{motionViByPosition.get(p)}</p>
                    ) : null}
                    {haoTu ? (
                      <div className="mt-5 border-t border-stone-700/15 pt-5">
                        <h3 className={manuscriptInsetLabel}>Hào từ (trích)</h3>
                        <p className={`${manuscriptProse} mt-3 text-stone-400/95`}>{haoTu}</p>
                      </div>
                    ) : (
                      <p className="mt-5 font-ctkp-serif text-sm text-stone-600">Chưa có trích hào từ cho vị này.</p>
                    )}
                  </li>
                );
              })}
            </ul>
          )}
          <hr className="ctkp-result-section-divider mt-12 sm:mt-14" aria-hidden />
        </section>

        {sameKingWen ? (
          <section className="mt-14 sm:mt-16" aria-labelledby="classical-trans-heading">
            <h2
              id="classical-trans-heading"
              className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
            >
              Kinh quẻ biến
            </h2>
            <p className={`${manuscriptProse} mt-5 text-stone-600`}>
              Quẻ biến trùng số Văn Vương với quẻ chính — thoán và tượng giống mục «Kinh quẻ chính»; không lặp lại để
              tránh nhồi trang.
            </p>
            <hr className="ctkp-result-section-divider mt-12 sm:mt-14" aria-hidden />
          </section>
        ) : (
          <ClassicalHexPanel
            id="classical-trans-heading"
            title="Kinh quẻ biến"
            lead="Thoán và tượng của hình sau biến — đọc song song với quẻ chính để thấy phần giữ và phần chuyển."
            hex={que.transformed_hexagram_text}
          />
        )}

        {payload.reading.structured ? (
          <QueStructuredInterpretSection structured={payload.reading.structured} textSource={payload.reading.text_source} />
        ) : null}

        <aside
          className="mt-14 sm:mt-16 border-t border-stone-700/15 pt-10"
          aria-label="Tóm tắt kỹ thuật từ hình quẻ"
        >
          <h2 className="font-ctkp-display text-[1rem] font-normal tracking-wide text-stone-500 sm:text-[1.05rem]">
            Tóm tắt máy đọc quẻ
          </h2>
          <p className="mt-2 font-ctkp-serif text-[12px] leading-relaxed text-stone-600">
            Đoạn dưới do engine ghép từ hình và nhãn — không thay cho thoán / tượng; có ích khi cần một khung nhanh.
          </p>
          <p className={`${manuscriptProse} mt-6 text-stone-600`}>{que.short_meaning}</p>
          <p className={`${manuscriptProse} mt-5 text-stone-600`}>
            <span className="text-stone-500">Chất quẻ chủ.</span> {que.main_trait_vi}
          </p>
          <p className={`${manuscriptProse} mt-4 text-stone-600`}>
            <span className="text-stone-500">Chất quẻ biến.</span> {que.transformed_trait_vi}
          </p>
        </aside>

        <section className="mt-14 sm:mt-16" aria-labelledby="draft-reading-heading">
          <h2
            id="draft-reading-heading"
            className="font-ctkp-display text-[1.15rem] font-normal tracking-wide text-stone-300 sm:text-[1.2rem]"
          >
            Lời gợi (nháp)
          </h2>
          <p className={`${manuscriptProse} mt-5 text-stone-600`}>
            Khung cố định trong app — đặt cạnh kinh văn và luận quy tắc; phần Bình luận bên dưới (nếu bật) là lớp riêng.
          </p>
          <article className="mt-8">
            <h3 className="font-ctkp-display text-[1.05rem] font-normal text-stone-400">{payload.reading.title}</h3>
            <p className={`${manuscriptProse} mt-6`}>{payload.reading.opening}</p>
            <ol className="mt-10 list-none space-y-6 sm:space-y-7">
              {payload.reading.verses.map((line, i) => (
                <li key={i} className="flex gap-4">
                  <span
                    className="font-ctkp-display w-6 shrink-0 pt-0.5 text-right text-sm tabular-nums text-stone-600"
                    aria-hidden
                  >
                    {i + 1}
                  </span>
                  <span className={manuscriptProse}>{line}</span>
                </li>
              ))}
            </ol>
          </article>
          <hr className="ctkp-result-section-divider mt-14 sm:mt-16" aria-hidden />
        </section>

        <AiInterpretPanel kind="que" resultPayload={payload} />

        <footer className="mt-16 sm:mt-20" aria-label="Lưu ý">
          <p className="font-ctkp-serif text-center text-xs leading-[1.85] text-stone-600">
            Quẻ là gương chiêm, không thay bạn chọn bước. Cổ Thư Kỳ Phổ không thay lời chuyên môn y tế hay pháp lý.
          </p>
        </footer>
      </div>
    </main>
  );
}

function LegacyFortuneResultView({ data }: { data: FortuneResponse }) {
  const { subject, reading, receivedAt } = data;
  return (
    <main className="ctkp-result-canvas min-h-[100dvh]">
      <div className="mx-auto max-w-[760px] px-5 py-16 pb-28 sm:px-8 sm:py-20 sm:pb-32">
        <CtkpResultPageNav backHref="/fortune" backLabel="← quay lại" />
        <p className={`${manuscriptProse} mt-10 text-stone-600`}>
          Đây là kết quả định dạng cũ (sinh nhật). Gieo lại để dùng quẻ theo số / thời điểm.
        </p>
        <hr className="ctkp-result-section-divider mt-12 opacity-90" aria-hidden />
        <header className="mt-12">
          <h1 className="font-ctkp-display text-pretty text-[clamp(1.2rem,3.5vw,1.55rem)] font-normal tracking-wide text-stone-200">
            {reading.title}
          </h1>
          <p className="mt-3 font-ctkp-serif text-sm text-stone-600">{new Date(receivedAt).toLocaleString("vi-VN")}</p>
        </header>
        <dl className="mt-10 grid gap-8 font-ctkp-serif text-sm sm:grid-cols-2">
          <div>
            <dt className="text-stone-600">Họ tên</dt>
            <dd className="mt-2 text-stone-400">{subject.name}</dd>
          </div>
          <div>
            <dt className="text-stone-600">Sinh ngày</dt>
            <dd className="mt-2 text-stone-400">{subject.birthDate}</dd>
          </div>
          <div>
            <dt className="text-stone-600">Giờ sinh</dt>
            <dd className="mt-2 text-stone-400">{subject.birthTime}</dd>
          </div>
          <div>
            <dt className="text-stone-600">Giới tính</dt>
            <dd className="mt-2 text-stone-400">{genderLabel[subject.gender] ?? subject.gender}</dd>
          </div>
        </dl>
        <hr className="ctkp-result-section-divider mt-14" aria-hidden />
        <article className="mt-12">
          <p className={manuscriptProse}>{reading.opening}</p>
          <ol className="mt-10 list-none space-y-6">
            {reading.verses.map((line, i) => (
              <li key={i} className="flex gap-4">
                <span
                  className="font-ctkp-display w-6 shrink-0 pt-0.5 text-right text-sm tabular-nums text-stone-600"
                  aria-hidden
                >
                  {i + 1}
                </span>
                <span className={manuscriptProse}>{line}</span>
              </li>
            ))}
          </ol>
        </article>
        <hr className="ctkp-result-section-divider mt-14 sm:mt-16" aria-hidden />
        <AiInterpretPanel kind="que" resultPayload={data} />
      </div>
    </main>
  );
}
