/* =========================================================
   VƯƠNG QUỐC ĐỘT PHÁ — Main App
   Layout A: book spread · Layout B: long parchment scroll
   Tweaks: font preset experimenter
   ========================================================= */

const { useState, useEffect, useRef, useCallback } = React;

/* ---------- Page dispatcher ---------- */
function PageRenderer({ idx, onJump, onPreviewHover, onPreviewLeave }) {
  const page = PAGES[idx];
  if (!page) return <div style={{ padding: 40 }}>Trang trắng.</div>;
  const common = { onJump, onPreviewHover, onPreviewLeave };
  switch (page.kind) {
    case "cover-front":        return <CoverFront {...common} />;
    case "cover-back":         return <CoverBack {...common} />;
    case "toc-left":           return <TocLeft {...common} />;
    case "toc-right":          return <TocRight {...common} />;
    case "map-left":           return <MapLeft {...common} />;
    case "map-right":          return <MapRight {...common} />;
    case "prologue-1":         return <Prologue1 {...common} />;
    case "prologue-2":         return <Prologue2 {...common} />;
    case "characters-intro":   return <CharactersIntro {...common} />;
    case "character-card":     return <CharacterCard characterId={page.character} {...common} />;
    case "theory-1":           return <Theory1 {...common} />;
    case "theory-2":           return <Theory2 {...common} />;
    case "chapter-highlight":  return <ChapterHighlight chapterId={page.chapterId} {...common} />;
    case "radar-test":         return <RadarTest {...common} />;
    case "closing":            return <Closing {...common} />;
    case "fulltext-intro":     return <FulltextIntro {...common} />;
    case "chapter-full":       return <ChapterFull chapterId={page.chapterId} {...common} />;
    case "appendix-intro":     return <AppendixIntro {...common} />;
    case "appendix-full":      return <AppendixFull appendixId={page.appendixId} {...common} />;
    default: return <div style={{ padding: 40 }}>{page.title}</div>;
  }
}

/* ---------- Hover preview ---------- */
function HoverPreview({ data, position }) {
  if (!data) return null;
  return (
    <div className="preview-card" style={{ top: position.y, left: position.x }}>
      <div className="pv-name">{data.name}</div>
      <div className="pv-tag">{data.tag}</div>
      <div className="pv-hint">{data.hint}</div>
    </div>
  );
}

/* ---------- Layout A — Book spread ---------- */
function BookSpreadLayout({ leftIdx, onJump, onPreviewHover, onPreviewLeave }) {
  const rightIdx = leftIdx + 1;
  return (
    <div className="book-spread">
      <div className="paper left">
        <PageRenderer idx={leftIdx} onJump={onJump} onPreviewHover={onPreviewHover} onPreviewLeave={onPreviewLeave} />
        <div className="folio">— {leftIdx + 1} —</div>
      </div>
      <div className="paper right">
        {rightIdx < TOTAL_PAGES ? (
          <>
            <PageRenderer idx={rightIdx} onJump={onJump} onPreviewHover={onPreviewHover} onPreviewLeave={onPreviewLeave} />
            <div className="folio">— {rightIdx + 1} —</div>
          </>
        ) : (
          <div style={{ height: "100%", display: "flex", alignItems: "center", justifyContent: "center", flexDirection: "column", color: "var(--ink-faded)" }}>
            <div className="ornament" style={{ width: 200 }}>
              <span className="line"></span><span className="glyph">✦</span><span className="line"></span>
            </div>
            <div className="small">Hết Quyển I</div>
          </div>
        )}
      </div>
    </div>
  );
}

/* ============================================================
   App root
   ============================================================ */
function App() {
  const [variant, setVariant] = useState("A");
  const [pageIdx, setPageIdx] = useState(0);           // A: left page idx · B: currently-visible section
  const [bookmark, setBookmark] = useState(null);
  const [preview, setPreview] = useState({ data: null, position: { x: 0, y: 0 } });
  const [fontPreset, setFontPreset] = useState("elodie");
  const [showTweaks, setShowTweaks] = useState(false);

  const scrollRef = useRef(null);

  /* ----- restore + persist ----- */
  useEffect(() => {
    try {
      const raw = localStorage.getItem("vqdp:state");
      if (raw) {
        const s = JSON.parse(raw);
        if (typeof s.pageIdx === "number") setPageIdx(s.pageIdx);
        if (s.variant) setVariant(s.variant);
        if (typeof s.bookmark === "number") setBookmark(s.bookmark);
        if (s.fontPreset) setFontPreset(s.fontPreset);
      }
    } catch (e) {}
  }, []);

  useEffect(() => {
    try {
      localStorage.setItem("vqdp:state", JSON.stringify({ pageIdx, variant, bookmark, fontPreset }));
    } catch (e) {}
  }, [pageIdx, variant, bookmark, fontPreset]);

  /* ----- apply font preset ----- */
  useEffect(() => {
    if (window.applyFontPreset) window.applyFontPreset(fontPreset);
  }, [fontPreset]);

  /* ----- scroll helper for variant B ----- */
  const scrollToSection = useCallback((idx) => {
    if (!scrollRef.current) return;
    const wrap = scrollRef.current;
    const target = wrap.querySelector(`[data-idx="${idx}"]`);
    if (!target) return;
    wrap.scrollTo({ top: target.offsetTop - 16, behavior: "smooth" });
  }, []);

  /* ----- track which section is visible in variant B ----- */
  useEffect(() => {
    if (variant !== "B" || !scrollRef.current) return;
    const wrap = scrollRef.current;
    let raf = null;
    const onScroll = () => {
      if (raf) return;
      raf = requestAnimationFrame(() => {
        raf = null;
        const sections = wrap.querySelectorAll("[data-idx]");
        const wrapTop = wrap.scrollTop;
        const probe = wrapTop + wrap.clientHeight * 0.25;
        let best = 0;
        sections.forEach(s => {
          if (s.offsetTop <= probe) best = parseInt(s.dataset.idx, 10);
        });
        setPageIdx(best);
      });
    };
    wrap.addEventListener("scroll", onScroll, { passive: true });
    // initial sync
    onScroll();
    return () => wrap.removeEventListener("scroll", onScroll);
  }, [variant]);

  /* ----- Restore scroll position when switching to B ----- */
  useEffect(() => {
    if (variant === "B") {
      // wait a tick for the DOM to render
      const t = setTimeout(() => scrollToSection(pageIdx), 50);
      return () => clearTimeout(t);
    }
  }, [variant]);

  /* ----- jump helper ----- */
  const goTo = useCallback((idx) => {
    if (typeof idx !== "number" || idx < 0 || idx >= TOTAL_PAGES) return;
    if (variant === "A") {
      setPageIdx(idx - (idx % 2));
    } else {
      setPageIdx(idx);
      scrollToSection(idx);
    }
  }, [variant, scrollToSection]);

  /* ----- next/prev (only for A) ----- */
  const next = useCallback(() => {
    if (variant === "A" && pageIdx + 2 < TOTAL_PAGES) setPageIdx(pageIdx + 2);
  }, [variant, pageIdx]);
  const prev = useCallback(() => {
    if (variant === "A" && pageIdx - 2 >= 0) setPageIdx(pageIdx - 2);
  }, [variant, pageIdx]);

  /* ----- keyboard nav ----- */
  useEffect(() => {
    const onKey = (e) => {
      if (variant !== "A") return;
      if (e.key === "ArrowRight") next();
      if (e.key === "ArrowLeft") prev();
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [variant, next, prev]);

  useEffect(() => {
    if (variant === "A" && pageIdx % 2 !== 0) setPageIdx(pageIdx - 1);
  }, [variant]);

  /* ----- hover preview ----- */
  const handlePreviewHover = useCallback((id, e) => {
    const data = PREVIEWS[id];
    if (!data) return;
    const rect = e.currentTarget.getBoundingClientRect();
    let x = rect.right + 12;
    let y = rect.top - 10;
    if (x + 260 > window.innerWidth) x = rect.left - 260;
    if (y + 220 > window.innerHeight) y = window.innerHeight - 230;
    if (y < 60) y = 60;
    setPreview({ data, position: { x, y } });
  }, []);

  const handlePreviewLeave = useCallback(() => {
    setPreview({ data: null, position: { x: 0, y: 0 } });
  }, []);

  /* ----- bookmark ----- */
  const toggleBookmark = () => {
    if (bookmark === pageIdx) setBookmark(null);
    else setBookmark(pageIdx);
  };
  const jumpToBookmark = () => { if (bookmark !== null) goTo(bookmark); };
  const isBookmarkedHere = bookmark === pageIdx;

  const currentPage = PAGES[pageIdx];
  const preset = FONT_PRESETS[fontPreset];

  return (
    <div className="app">
      {/* Top bar */}
      <div className="toggle-bar">
        <a
          className="x5-home-link"
          href="https://www.hocvienx5.com"
          title="Về Học Viện X5"
          aria-label="Về Học Viện X5">
          <img src="/icon.png" alt="X5" />
        </a>
        <div className="brand">
          <span className="glyph">ᛟ</span>
          Thách Thức Lục Địa Mới · Bản blog
          <span className="glyph" style={{ marginLeft: 8 }}>ᚦ</span>
        </div>

        <div className="variation-toggle">
          <button className={variant === "A" ? "active" : ""} onClick={() => setVariant("A")}>
            Layout A · Cuốn Sử Thi
          </button>
          <button className={variant === "B" ? "active" : ""} onClick={() => setVariant("B")}>
            Layout B · Cuộn Giấy
          </button>
        </div>

        <div className="toolbar-right">
          <button className="tool-btn" onClick={() => setShowTweaks(s => !s)}>
            {showTweaks ? "✕ Font" : "Aa Font"}
          </button>
          {bookmark !== null && bookmark !== pageIdx && (
            <button className="tool-btn" onClick={jumpToBookmark}>
              ↪ tr. {bookmark + 1}
            </button>
          )}
          <button
            className={"tool-btn " + (isBookmarkedHere ? "bookmarked" : "")}
            onClick={toggleBookmark}
            title="Đánh dấu trang này">
            {isBookmarkedHere ? "✦ Đã đánh dấu" : "Đánh dấu"}
          </button>
        </div>
      </div>

      {/* Font tweaks panel */}
      {showTweaks && (
        <div className="font-panel">
          <div className="font-panel-head">
            <span>Thử nghiệm font</span>
            <button className="tool-btn" style={{ padding: "4px 8px" }} onClick={() => setShowTweaks(false)}>✕</button>
          </div>
          <div className="font-panel-body">
            {FONT_PRESET_KEYS.map(key => {
              const p = FONT_PRESETS[key];
              const active = fontPreset === key;
              return (
                <button
                  key={key}
                  className={"font-option" + (active ? " active" : "")}
                  onClick={() => setFontPreset(key)}>
                  <span className="font-option-preview" style={{ fontFamily: p.display, fontWeight: p.displayWeight }}>
                    Vương Quốc
                  </span>
                  <span className="font-option-meta">
                    <span className="font-option-label">
                      {p.label}
                      {p.vnLimited && <span className="vn-warn" title="Font không hỗ trợ đầy đủ dấu tiếng Việt — sẽ fallback sang Cinzel cho các ký tự thiếu">⚠ VN</span>}
                    </span>
                    <span className="font-option-note">{p.note}</span>
                  </span>
                </button>
              );
            })}
          </div>
        </div>
      )}

      {/* Stage */}
      <div className="stage">
        {variant === "A" && (
          <button className="nav-arrow prev" onClick={prev} disabled={pageIdx === 0} title="Trang trước (←)">‹</button>
        )}

        {variant === "A" ? (
          <BookSpreadLayout
            leftIdx={pageIdx}
            onJump={goTo}
            onPreviewHover={handlePreviewHover}
            onPreviewLeave={handlePreviewLeave}
          />
        ) : (
          <LongScrollLayout
            scrollRef={scrollRef}
            activeIdx={pageIdx}
            onJump={goTo}
            onPreviewHover={handlePreviewHover}
            onPreviewLeave={handlePreviewLeave}
          />
        )}

        {variant === "A" && (
          <button
            className="nav-arrow next"
            onClick={next}
            disabled={pageIdx + 2 >= TOTAL_PAGES}
            title="Trang sau (→)">›</button>
        )}

        <div className="page-counter">
          {variant === "A"
            ? `Trang ${pageIdx + 1}–${Math.min(pageIdx + 2, TOTAL_PAGES)} / ${TOTAL_PAGES}`
            : `Cuộn · trang ${pageIdx + 1} / ${TOTAL_PAGES}`
          }
          {currentPage?.title ? `  ·  ${currentPage.title}` : ""}
          {"  ·  "}
          <span style={{ color: "var(--parchment)", opacity: 0.7 }}>
            font: {preset.label}
          </span>
        </div>
      </div>

      <HoverPreview data={preview.data} position={preview.position} />
    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
