"use client";

import { useCallback, useState } from "react";
import { Sparkles, Loader2, RefreshCw, Download, Crown } from "lucide-react";
import Link from "next/link";
import { cn } from "@/lib/utils";
import type { ChartInput } from "@/lib/tuvi/engine";

type SectionKey = "menh" | "tai-bach" | "quan-loc" | "phu-the" | "tu-tuc" | "dai-van";

type SectionMeta = {
  key: SectionKey;
  title: string;
  description: string;
};

const SECTIONS: SectionMeta[] = [
  {
    key: "menh",
    title: "Mệnh & Thân",
    description: "Tính cách cốt lõi, ưu nhược điểm bẩm sinh",
  },
  {
    key: "tai-bach",
    title: "Tài Bạch & Phúc Đức",
    description: "Tài chính, phúc khí gia đạo",
  },
  {
    key: "quan-loc",
    title: "Quan Lộc & Thiên Di",
    description: "Sự nghiệp, công danh, di chuyển",
  },
  {
    key: "phu-the",
    title: "Phu Thê",
    description: "Hôn nhân, tình cảm",
  },
  {
    key: "tu-tuc",
    title: "Tử Tức & Phụ Mẫu",
    description: "Con cái, cha mẹ",
  },
  {
    key: "dai-van",
    title: "Đại Vận hiện tại",
    description: "Vận trình 10 năm + lưu niên",
  },
];

type SectionState = {
  text: string;
  loading: boolean;
  error: string | null;
  provider: string | null;
  done: boolean;
};

const EMPTY: SectionState = { text: "", loading: false, error: null, provider: null, done: false };

/**
 * Section-by-section deep reading. Each section streams independently —
 * user clicks a tab, the panel fetches /api/ai/section for that section
 * only. Results cache in component state so re-clicking a tab doesn't
 * refetch.
 *
 * Streaming uses Server-Sent Events from the route, parsed with a small
 * line-level reader (no external deps).
 */
export function SectionReading({
  input,
  forDate,
  plan = "FREE",
}: {
  input: ChartInput;
  /** Pass the same `?h=` value the page server-side rendered for, so
   *  Đại Vận section reads against the same horoscope snapshot. */
  forDate?: string;
  /** Current user plan, drives PDF export visibility. */
  plan?: "FREE" | "PREMIUM" | "ANONYMOUS";
}) {
  const [active, setActive] = useState<SectionKey>("menh");
  const [states, setStates] = useState<Record<SectionKey, SectionState>>(
    () =>
      Object.fromEntries(SECTIONS.map((s) => [s.key, EMPTY])) as Record<SectionKey, SectionState>
  );

  const fetchSection = useCallback(
    async (section: SectionKey, force: boolean) => {
      setStates((prev) => {
        const cur = prev[section];
        if (!force && (cur.done || cur.loading)) return prev;
        return { ...prev, [section]: { ...EMPTY, loading: true } };
      });

      try {
        const res = await fetch("/api/ai/section", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ input, section, forDate }),
        });
        if (!res.ok || !res.body) {
          const j = await res.json().catch(() => ({ error: "Lỗi không xác định" }));
          setStates((prev) => ({
            ...prev,
            [section]: { ...EMPTY, error: j.error ?? `HTTP ${res.status}` },
          }));
          return;
        }
        const reader = res.body.getReader();
        const decoder = new TextDecoder();
        let buffer = "";
        // SSE: each event ends with \n\n; lines start with "data: ".
        const flush = (chunk: string) => {
          buffer += chunk;
          const events = buffer.split("\n\n");
          buffer = events.pop() ?? "";
          for (const evt of events) {
            for (const line of evt.split("\n")) {
              if (!line.startsWith("data:")) continue;
              const payload = line.slice(5).trim();
              if (!payload) continue;
              try {
                const data = JSON.parse(payload) as {
                  provider?: string;
                  delta?: string;
                  done?: boolean;
                  error?: string;
                };
                setStates((prev) => {
                  const cur = prev[section];
                  return {
                    ...prev,
                    [section]: {
                      ...cur,
                      text: cur.text + (data.delta ?? ""),
                      provider: data.provider ?? cur.provider,
                      done: cur.done || !!data.done,
                      error: data.error ?? cur.error,
                      loading: !data.done && !data.error,
                    },
                  };
                });
              } catch {
                // ignore malformed event
              }
            }
          }
        };

        while (true) {
          const { value, done } = await reader.read();
          if (done) break;
          flush(decoder.decode(value, { stream: true }));
        }
        // mark loading off in case server didn't emit done
        setStates((prev) => ({
          ...prev,
          [section]: { ...prev[section], loading: false },
        }));
      } catch (e) {
        setStates((prev) => ({
          ...prev,
          [section]: { ...EMPTY, error: e instanceof Error ? e.message : "Network error" },
        }));
      }
    },
    [input, forDate]
  );

  function handleSelect(section: SectionKey) {
    setActive(section);
    void fetchSection(section, false);
  }

  function handleRetry() {
    void fetchSection(active, true);
  }

  const [pdfState, setPdfState] = useState<{ loading: boolean; error: string | null }>({
    loading: false,
    error: null,
  });

  async function downloadPdf() {
    setPdfState({ loading: true, error: null });
    // Collect already-loaded sections (skip empty/error ones).
    const sections = SECTIONS.map((s) => ({
      key: s.key,
      title: s.title,
      body: states[s.key].text,
    })).filter((s) => s.body.trim().length > 0);
    if (sections.length === 0) {
      setPdfState({
        loading: false,
        error: "Hãy đọc ít nhất 1 mục trước khi xuất PDF.",
      });
      return;
    }
    try {
      const res = await fetch("/api/billing/pdf", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ input, forDate, sections }),
      });
      if (!res.ok) {
        const j = await res.json().catch(() => ({ error: `HTTP ${res.status}` }));
        setPdfState({ loading: false, error: j.error ?? `HTTP ${res.status}` });
        return;
      }
      const blob = await res.blob();
      const url = URL.createObjectURL(blob);
      const cd = res.headers.get("Content-Disposition") ?? "";
      const m = /filename="([^"]+)"/.exec(cd);
      const a = document.createElement("a");
      a.href = url;
      a.download = m?.[1] ?? "tuviso-luan-giai.pdf";
      document.body.appendChild(a);
      a.click();
      a.remove();
      setTimeout(() => URL.revokeObjectURL(url), 5000);
      setPdfState({ loading: false, error: null });
    } catch (e) {
      setPdfState({
        loading: false,
        error: e instanceof Error ? e.message : "Lỗi tải PDF",
      });
    }
  }

  const cur = states[active];

  return (
    <section className="border-stroke-subtle bg-bg-elevated/40 mx-auto mt-10 max-w-5xl rounded-2xl border p-5 lg:p-7">
      <header className="mb-4 flex flex-wrap items-baseline justify-between gap-2">
        <h2 className="font-display text-ink-primary text-xl font-semibold lg:text-2xl">
          Đọc lá số chuyên sâu (AI)
        </h2>
        <div className="text-ink-muted text-xs">
          {cur.provider === "mock" ? (
            <span className="rounded bg-amber-500/15 px-2 py-0.5 text-amber-300">chế độ mock</span>
          ) : cur.provider ? (
            <span className="text-ink-secondary">model · {cur.provider}</span>
          ) : null}
        </div>
      </header>

      {/* Tabs */}
      <div role="tablist" className="mb-5 flex flex-wrap gap-1.5">
        {SECTIONS.map((s) => {
          const st = states[s.key];
          const isActive = s.key === active;
          return (
            <button
              key={s.key}
              type="button"
              role="tab"
              aria-selected={isActive}
              onClick={() => handleSelect(s.key)}
              className={cn(
                "rounded-md border px-3 py-1.5 text-xs font-medium transition",
                isActive
                  ? "border-brand-gold bg-brand-gold/15 text-brand-gold"
                  : "border-stroke-default bg-bg-base/60 text-ink-secondary hover:border-brand-gold/40"
              )}
            >
              <span>{s.title}</span>
              {st.done ? <span className="ml-1.5 text-emerald-300">✓</span> : null}
              {st.loading ? (
                <Loader2 className="ml-1.5 inline h-3 w-3 animate-spin" aria-hidden="true" />
              ) : null}
            </button>
          );
        })}
      </div>

      {/* Active section description */}
      <p className="text-ink-muted mb-3 text-xs">
        {SECTIONS.find((s) => s.key === active)?.description}
      </p>

      {/* Body */}
      <div className="border-stroke-subtle/60 bg-bg-base/60 min-h-[180px] rounded-lg border p-4">
        {!cur.text && !cur.loading && !cur.error ? (
          <button
            type="button"
            onClick={() => void fetchSection(active, false)}
            className="from-brand-gold via-brand-gold-soft to-brand-gold text-bg-base inline-flex items-center gap-2 rounded-md bg-gradient-to-r px-4 py-2.5 text-sm font-semibold transition hover:brightness-110"
          >
            <Sparkles className="h-4 w-4" aria-hidden="true" />
            Bắt đầu đọc {SECTIONS.find((s) => s.key === active)?.title.toLowerCase()}
          </button>
        ) : null}

        {cur.error ? (
          <div className="border-brand-red/40 bg-brand-red/10 text-brand-red-light mb-3 rounded-md border px-3 py-2 text-sm">
            {cur.error}
            <button
              type="button"
              onClick={handleRetry}
              className="ml-3 inline-flex items-center gap-1 underline hover:no-underline"
            >
              <RefreshCw className="h-3 w-3" aria-hidden="true" />
              Thử lại
            </button>
          </div>
        ) : null}

        {cur.text ? (
          <div className="text-ink-primary text-sm leading-relaxed whitespace-pre-wrap">
            {cur.text}
            {cur.loading ? <span className="text-brand-gold ml-1 animate-pulse">▍</span> : null}
          </div>
        ) : cur.loading ? (
          <div className="text-ink-muted flex items-center gap-2 text-sm">
            <Loader2 className="h-4 w-4 animate-spin" aria-hidden="true" />
            Đang luận giải…
          </div>
        ) : null}

        {cur.done && cur.text ? (
          <button
            type="button"
            onClick={handleRetry}
            className="text-ink-muted hover:text-brand-gold mt-4 inline-flex items-center gap-1 text-xs underline"
          >
            <RefreshCw className="h-3 w-3" aria-hidden="true" />
            Đọc lại mục này
          </button>
        ) : null}
      </div>

      {/* PDF export — Premium-only */}
      <div className="border-stroke-subtle/60 mt-5 flex flex-wrap items-center justify-between gap-3 rounded-lg border border-dashed p-4">
        <div>
          <h3 className="text-ink-primary flex items-center gap-2 text-sm font-semibold">
            <Crown className="text-brand-gold h-4 w-4" aria-hidden="true" />
            Xuất luận giải PDF
          </h3>
          <p className="text-ink-muted mt-0.5 text-xs">
            Tải PDF gồm tất cả mục đã đọc, font tiếng Việt, có dấu, gửi/in được.
          </p>
        </div>
        {plan === "PREMIUM" ? (
          <button
            type="button"
            onClick={downloadPdf}
            disabled={pdfState.loading}
            className="bg-brand-gold text-bg-base inline-flex items-center gap-2 rounded-md px-4 py-2 text-sm font-semibold transition hover:brightness-110 disabled:opacity-60"
          >
            {pdfState.loading ? (
              <Loader2 className="h-4 w-4 animate-spin" aria-hidden="true" />
            ) : (
              <Download className="h-4 w-4" aria-hidden="true" />
            )}
            {pdfState.loading ? "Đang tạo PDF…" : "Tải PDF"}
          </button>
        ) : (
          <Link
            href="/pricing"
            className="border-brand-gold/50 text-brand-gold hover:bg-brand-gold/10 inline-flex items-center gap-2 rounded-md border px-4 py-2 text-sm font-semibold transition"
          >
            <Crown className="h-4 w-4" aria-hidden="true" />
            Nâng cấp Premium
          </Link>
        )}
      </div>
      {pdfState.error ? (
        <div className="mt-2 rounded-md border border-rose-500/30 bg-rose-500/10 p-3 text-xs text-rose-200">
          {pdfState.error}
        </div>
      ) : null}

      <p className="text-ink-muted mt-4 text-[11px] leading-relaxed">
        ⚠ Luận giải AI dựa trên lá số đã an. Đây là tham khảo — không thay thế tư vấn chuyên sâu của
        thầy có kinh nghiệm. Tránh ra quyết định lớn (ly hôn, đầu tư, sức khỏe) chỉ dựa vào AI.
      </p>
    </section>
  );
}
