"use client";

import { memo, useCallback, useEffect, useMemo, useRef, useState } from "react";

import type { AiInterpretation, FortuneInterpretKind } from "@/lib/fortune-interpret";
import { mapInterpretApiError, postFortuneInterpret } from "@/lib/fortune-interpret";
import { getApiBaseUrl } from "@/lib/api";
import {
  readTuViAiInterpretSession,
  tuViStoredSnapshotResultId,
  writeTuViAiInterpretSession,
} from "@/lib/tuvi-ai-interpret-session";

const SECTIONS: { key: keyof AiInterpretation; title: string }[] = [
  { key: "overview", title: "Tổng quan" },
  { key: "strengths", title: "Điểm sáng" },
  { key: "risks", title: "Điều cần cẩn trọng" },
  { key: "advice", title: "Lời khuyên" },
];

type AiInterpretPanelProps = {
  kind: FortuneInterpretKind;
  /** JSON gửi lên POST /fortune/interpret (trường result). */
  resultPayload: unknown;
  /**
   * Tu vi: đặt phần AI như phụ lục — viền nhạt, nhãn rõ “không thay luận chính”.
   * Gieo quẻ giữ mặc định (không truyền).
   */
  appendixMode?: boolean;
};

function AiInterpretPanelInner({ kind, resultPayload, appendixMode = false }: AiInterpretPanelProps) {
  const [interpretation, setInterpretation] = useState<AiInterpretation | null>(null);
  const [meta, setMeta] = useState<{ model: string; generatedAt: string } | null>(null);
  const [restoredFromSession, setRestoredFromSession] = useState(false);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const requestInFlight = useRef(false);
  const generation = useRef(0);
  const hasApi = Boolean(getApiBaseUrl());
  const resultKey = useMemo(() => {
    try {
      return JSON.stringify(resultPayload);
    } catch (e) {
      console.error("[AiInterpretPanel] resultKey stringify failed", e);
      return `fallback:${typeof resultPayload}`;
    }
  }, [resultPayload]);
  const appendix = appendixMode && kind === "tuvi";

  useEffect(() => {
    generation.current += 1;
    requestInFlight.current = false;
    setError(null);
    setLoading(false);

    if (appendix) {
      const rid = tuViStoredSnapshotResultId(resultPayload);
      if (rid) {
        const cached = readTuViAiInterpretSession(rid);
        if (cached && SECTIONS.some((s) => cached.interpretation[s.key]?.trim())) {
          setInterpretation(cached.interpretation);
          setMeta({ model: cached.model, generatedAt: cached.generatedAt });
          setRestoredFromSession(true);
          return;
        }
      }
    }

    setRestoredFromSession(false);
    setInterpretation(null);
    setMeta(null);
  }, [kind, resultKey, appendix, resultPayload]);

  const runInterpret = useCallback(async () => {
    if (!hasApi || requestInFlight.current) return;
    requestInFlight.current = true;
    const ticket = generation.current;
    setLoading(true);
    setError(null);
    try {
      const r = await postFortuneInterpret(kind, resultPayload);
      if (ticket !== generation.current) return;
      setInterpretation(r.interpretation);
      setMeta({ model: r.model, generatedAt: r.generatedAt });
      setRestoredFromSession(false);
      if (appendix) {
        const rid = tuViStoredSnapshotResultId(resultPayload);
        if (rid) writeTuViAiInterpretSession(rid, r);
      }
    } catch (e: unknown) {
      if (ticket !== generation.current) return;
      const raw = e instanceof Error ? e.message : "Chưa gọi được lời soi thêm.";
      setError(mapInterpretApiError(raw));
    } finally {
      if (ticket === generation.current) {
        requestInFlight.current = false;
        setLoading(false);
      }
    }
  }, [hasApi, kind, resultPayload, appendix]);

  const proseClass =
    "font-ctkp-serif text-[0.98rem] sm:text-[1.02rem] leading-[1.82] text-stone-400/95 tracking-[0.01em]";
  const sectionClass = appendix
    ? "mt-16 border-t border-dashed border-stone-700/45 pt-14 sm:mt-20 sm:pt-16"
    : "mt-12 sm:mt-14";
  const panelBoxClass = appendix
    ? "rounded-lg border border-stone-800/50 bg-[#05060c]/25 px-4 py-8 sm:px-6 sm:py-9"
    : "";

  if (!hasApi) {
    return (
      <section className={sectionClass} aria-label="Bình luận thêm (AI)">
        {appendix ? (
          <p className="mb-3 font-ctkp-display text-[10px] font-normal uppercase tracking-[0.26em] text-stone-600">
            Phụ lục · tùy chọn
          </p>
        ) : null}
        <h2
          className={`font-ctkp-display font-normal tracking-wide text-stone-400 ${appendix ? "text-[0.98rem]" : "text-[1.05rem]"}`}
        >
          {appendix ? "Bình luận sâu hơn (AI)" : "Chú thích (AI)"}
        </h2>
        <p className={`${proseClass} mt-4 ${appendix ? "text-stone-500/95" : ""}`}>
          Cần nối ứng dụng tới dịch vụ dữ liệu và bật luận AI trên máy chủ để mở bốn mục luận giải phụ.
        </p>
      </section>
    );
  }

  const buttonLabel = error
    ? "Thử lại"
    : interpretation
      ? appendix
        ? "Gọi lại bình luận AI"
        : "Soi lại"
      : appendix
        ? "Bật bình luận AI (một lần)"
        : "Mời soi thêm (AI)";

  return (
    <section className={sectionClass} aria-label="Bình luận thêm (AI)" aria-busy={loading}>
      {appendix ? (
        <p className="mb-2 font-ctkp-display text-[10px] font-normal uppercase tracking-[0.26em] text-stone-600">
          Phụ lục · không thay nội dung chính
        </p>
      ) : null}
      <h2
        className={`font-ctkp-display font-normal tracking-wide text-stone-400 ${appendix ? "text-[0.98rem]" : "text-[1.05rem]"}`}
      >
        {appendix ? "Bình luận sâu hơn (AI)" : "Chú thích (AI)"}
      </h2>
      <p className={`${proseClass} mt-4 ${appendix ? "text-stone-500/95" : ""}`}>
        {appendix ? (
          <>
            Lớp này chỉ là <span className="text-stone-400">lời nhận xét thêm</span> từ mô hình ngôn ngữ — có thể khác
            mỗi lần gọi, không làm chuẩn cho lá số hay luận phía trên.
          </>
        ) : (
          <>
            Gợi ý chiêm nghiệm — không thay lời thầy hay chuyên môn. Chỉ gọi khi bạn chủ động nhấn; có thể{" "}
            <span className="text-stone-500">Thử lại</span> nếu lần trước chưa ổn.
          </>
        )}
      </p>
      {kind === "tuvi" ? (
        <p className={`${proseClass} mt-3 ${appendix ? "text-stone-500/95" : ""}`}>
          <span className="text-stone-500">Tử vi:</span> khung cung và năm mục luận đã hiển thị là nguồn cố định từ engine +
          tra cứu + quy tắc. AI chỉ được bấm thủ công; nó{" "}
          <span className="text-stone-500">không thêm sao hay đổi cung</span>, chỉ diễn đạt lại / soi ở góc thơ.
        </p>
      ) : null}

      <p className={`${appendix ? "mt-7" : "mt-6"}`}>
        <button
          type="button"
          onClick={() => void runInterpret()}
          disabled={loading}
          aria-busy={loading}
          className={
            appendix
              ? "rounded border border-stone-700/55 bg-stone-950/40 px-3 py-2 font-ctkp-serif text-[13px] text-stone-400 transition-colors hover:border-stone-600/55 hover:bg-stone-950/55 hover:text-stone-300 disabled:cursor-not-allowed disabled:opacity-50"
              : "font-ctkp-serif text-sm text-stone-500 underline-offset-[5px] transition-colors hover:text-stone-400 hover:underline disabled:cursor-not-allowed disabled:opacity-50"
          }
        >
          {loading ? (
            <span className="inline-flex items-center gap-2">
              <span
                className="size-3 shrink-0 rounded-full border border-stone-600/50 border-t-stone-400/70 motion-safe:animate-spin"
                aria-hidden
              />
              Đang soạn lời luận…
            </span>
          ) : (
            buttonLabel
          )}
        </button>
      </p>

      <div className={`relative ${appendix ? "mt-8" : "mt-10"} min-h-[min(18rem,45vh)] ${panelBoxClass}`}>
        {loading && !interpretation ? (
          <div className="ctkp-fade-in space-y-8" role="status" aria-live="polite">
            <p className={`${proseClass} text-stone-500`}>
              {appendix ? "Đang soạn bình luận AI — thường vài giây đến một phút." : "Đang chuẩn bị luận giải — thường vài giây đến một phút."}
            </p>
            <div className="space-y-8 pt-2">
              {SECTIONS.map(({ key, title }, i) => {
                const base = i * 110;
                return (
                  <div
                    key={key}
                    className="ctkp-fade-in space-y-3"
                    style={{ animationDelay: `${80 + i * 70}ms` }}
                  >
                    <div className="flex items-center gap-2">
                      <span
                        className="h-2 w-24 max-sm:w-20 rounded-sm ctkp-skeleton-breathe"
                        style={{ animationDelay: `${base}ms` }}
                        aria-hidden
                      />
                      <span className="sr-only">{title}</span>
                    </div>
                    <div className="space-y-2">
                      <div
                        className="h-[0.65em] max-w-prose rounded-sm ctkp-skeleton-breathe"
                        style={{ width: "100%", animationDelay: `${base}ms` }}
                      />
                      <div
                        className="h-[0.65em] max-w-prose rounded-sm ctkp-skeleton-breathe"
                        style={{ width: "93%", animationDelay: `${base + 85}ms` }}
                      />
                      <div
                        className="h-[0.65em] max-w-prose rounded-sm ctkp-skeleton-breathe"
                        style={{ width: "78%", animationDelay: `${base + 170}ms` }}
                      />
                    </div>
                  </div>
                );
              })}
            </div>
          </div>
        ) : error ? (
          <div className="ctkp-fade-in" role="alert">
            <p className="font-ctkp-serif text-sm text-stone-500">
              {appendix ? "Chưa gọi được bình luận AI" : "Chưa thể luận giải"}
            </p>
            <p className={`${proseClass} mt-3 text-red-200/75`}>{error}</p>
            <p className={`${proseClass} mt-3 text-stone-600`}>
              Nhấn <span className="text-stone-500">{appendix ? "Gọi lại bình luận AI" : "Thử lại"}</span> phía trên để thử
              lại.
            </p>
          </div>
        ) : interpretation ? (
          <div className="ctkp-fade-in">
            {loading ? (
              <p
                className={`${proseClass} mb-8 flex items-center gap-2 text-stone-500`}
                role="status"
                aria-live="polite"
              >
                <span
                  className="size-2.5 shrink-0 rounded-full border border-stone-600/45 border-t-stone-400/65 motion-safe:animate-spin"
                  aria-hidden
                />
                {appendix
                  ? "Đang gọi lại AI — đoạn dưới vẫn là bình luận lần trước."
                  : "Đang soi lại — bên dưới vẫn là lần trước."}
              </p>
            ) : null}

            <div
              className={`space-y-9 sm:space-y-10 ${loading ? "motion-safe:opacity-[0.45] motion-safe:transition-opacity motion-safe:duration-500 motion-safe:ease-out" : ""}`}
            >
              {SECTIONS.some((s) => interpretation[s.key]?.trim()) ? (
                SECTIONS.map(({ key, title }) => {
                  const text = interpretation[key]?.trim();
                  if (!text) return null;
                  return (
                    <div key={key}>
                      <p
                        className={`font-ctkp-display text-[11px] font-normal uppercase tracking-[0.22em] ${appendix ? "text-stone-600/85" : "text-stone-600"}`}
                      >
                        {title}
                        {appendix ? (
                          <span className="ml-2 font-ctkp-serif text-[10px] font-normal normal-case tracking-normal text-stone-700">
                            (AI)
                          </span>
                        ) : null}
                      </p>
                      <p
                        className={`${proseClass} mt-3 whitespace-pre-line ${appendix ? "text-stone-500/95" : ""}`}
                      >
                        {text}
                      </p>
                    </div>
                  );
                })
              ) : (
                <p className={proseClass}>
                  Lần trả lời chưa đủ các mục — nhấn{" "}
                  <span className="text-stone-500">{appendix ? "Gọi lại bình luận AI" : "Soi lại"}</span> hoặc{" "}
                  <span className="text-stone-500">Thử lại</span>.
                </p>
              )}
            </div>

            {meta ? (
              <p className="mt-10 border-t border-stone-700/25 pt-6 font-ctkp-serif text-[11px] leading-relaxed text-stone-600">
                <span className="text-stone-600">{meta.model}</span>
                <span className="mx-2 text-stone-700">·</span>
                {new Date(meta.generatedAt).toLocaleString("vi-VN")}
                {appendix ? (
                  <>
                    <span className="mt-2 block text-stone-700">Phản hồi mô hình — không ghi vào bản chính lá số.</span>
                    {restoredFromSession ? (
                      <span className="mt-1.5 block text-stone-600">
                        Đã khôi phục bình luận từ phiên trình duyệt — nhấn nút để tải lại từ máy chủ (có thể trả ngay từ bộ
                        nhớ đệm).
                      </span>
                    ) : null}
                  </>
                ) : null}
              </p>
            ) : null}
          </div>
        ) : null}
      </div>
    </section>
  );
}

export const AiInterpretPanel = memo(AiInterpretPanelInner);
