// ebooks.jsx — หน้ารายการ ebook และรายละเอียดหนังสือ
const { useEffect: useEffectE } = React;

// ---------- โหลดข้อมูลหนังสือจาก ebooks/<slug>/book.json ----------
// ค้นพบ slug ผ่าน ebooks/index.json (เรียงตามลำดับในไฟล์ — ตัวแรก = เล่มแนะนำบนหน้าแรก)
async function fetchBook(slug) {
  const res = await fetch(`ebooks/${slug}/book.json`, { cache: "no-cache" });
  if (!res.ok) throw new Error(`fetch failed: ebooks/${slug}/book.json ${res.status}`);
  const b = await res.json();
  return {
    ...b,
    id: slug,
    image: b.cover ? `ebooks/${slug}/${b.cover}` : null,
    sampleUrl: b.sample ? `ebooks/${slug}/${b.sample}` : undefined,
  };
}

async function loadEbooks() {
  const res = await fetch("ebooks/index.json", { cache: "no-cache" });
  if (!res.ok) throw new Error(`fetch failed: ebooks/index.json ${res.status}`);
  const slugs = await res.json();
  // คงลำดับตาม manifest (อย่า sort) — index 0 คือเล่มแนะนำ
  const books = await Promise.all(slugs.map((s) => fetchBook(s).catch((e) => {
    console.warn(`[ebooks] skip ${s}:`, e);
    return null;
  })));
  return books.filter(Boolean);
}

// ---------- การ์ด ebook แบบปก ----------
function EbookCardCover({ book, go }) {
  const clickable = book.available;
  return (
    <div className={`ebcard${clickable ? "" : " is-soon"}`}
      onClick={() => clickable && go({ page: "ebook", id: book.id })}
      role={clickable ? "button" : undefined}>
      <div className="ebcard-cover">
        <BookCover book={book} size="md" />
        {!book.available && <span className="ebcard-soon">เร็ว ๆ นี้</span>}
      </div>
      <div className="ebcard-info">
        <h3 className="ebcard-title">{book.title}</h3>
        <p className="ebcard-desc">{book.shortDesc}</p>
        <div className="ebcard-foot">
          {book.available
            ? <><span className="ebcard-price">{book.price} <small>{book.currency}</small></span>
                <span className="ebcard-go">รายละเอียด <Icon name="arrow" size={15} /></span></>
            : <span className="ebcard-comingsoon">กำลังจัดทำ</span>}
        </div>
      </div>
    </div>
  );
}

// ---------- การ์ด ebook แบบแถวแนวนอน ----------
function EbookRow({ book, go }) {
  const clickable = book.available;
  return (
    <div className={`ebrow${clickable ? "" : " is-soon"}`}
      onClick={() => clickable && go({ page: "ebook", id: book.id })}
      role={clickable ? "button" : undefined}>
      <div className="ebrow-cover"><BookCover book={book} size="sm" /></div>
      <div className="ebrow-main">
        <div className="ebrow-head">
          <h3 className="ebrow-title">{book.title}</h3>
          {!book.available && <span className="ebcard-soon">เร็ว ๆ นี้</span>}
        </div>
        <p className="ebrow-tag">{book.tagline}</p>
        <p className="ebrow-desc">{book.shortDesc}</p>
      </div>
      <div className="ebrow-side">
        {book.available
          ? <><span className="ebcard-price">{book.price} <small>{book.currency}</small></span>
              <Button size="sm" iconRight="arrow" onClick={(e) => { e.stopPropagation(); go({ page: "ebook", id: book.id }); }}>รายละเอียด</Button></>
          : <span className="ebcard-comingsoon">กำลังจัดทำ</span>}
      </div>
    </div>
  );
}

// ---------- หน้ารายการ ebook ----------
function EbooksPage({ go, t, ebooks }) {
  const all = ebooks || [];
  const cats = orderedCategories(all); // ลำดับหมวดร่วม (ดู ui.jsx) — ตรงกับหน้าบทความ
  const [cat, setCat] = React.useState("ทั้งหมด");
  const list = cat === "ทั้งหมด" ? all : all.filter((b) => b.category === cat);
  return (
    <main className="page-pad">
      <div className="container">
        <div className="pagehead">
          <span className="sechead-kicker">อีบุ๊ก</span>
          <h1 className="pagehead-title">คู่มือสาย AI ที่อ่านจบแล้วทำได้จริง</h1>
          <p className="pagehead-lead">หนังสือแนวคู่มือเชิงวิชาการที่เขียนให้เข้าใจง่าย เหมาะกับการเริ่มต้นและต่อยอดสายงาน AI</p>
        </div>
        <div className="filterbar">
          {cats.map((c) => (
            <button key={c} className={`filterchip${cat === c ? " is-active" : ""}`} onClick={() => setCat(c)}>{c}</button>
          ))}
        </div>
        {t.ebookStyle === "list" ? (
          <div className="eb-list">
            {list.map((b) => <EbookRow key={b.id} book={b} go={go} />)}
          </div>
        ) : (
          <div className="eb-grid">
            {list.map((b) => <EbookCardCover key={b.id} book={b} go={go} />)}
          </div>
        )}
      </div>
    </main>
  );
}

// ---------- หน้ารายละเอียดหนังสือ ----------
// ---------- PDF reader modal (PDF.js) ----------
function PdfModal({ book, onClose }) {
  const pagesRef = React.useRef(null);
  const [status, setStatus] = React.useState("loading"); // loading | ready | error
  const [pageInfo, setPageInfo] = React.useState({ total: 0 });

  React.useEffect(() => {
    const onKey = (e) => { if (e.key === "Escape") onClose(); };
    document.addEventListener("keydown", onKey);
    document.body.style.overflow = "hidden";
    return () => { document.removeEventListener("keydown", onKey); document.body.style.overflow = ""; };
  }, []);

  React.useEffect(() => {
    let cancelled = false;
    let pdfDoc = null;
    let readyShown = false;
    let io = null;
    async function run() {
      const lib = window.pdfjsLib;
      const container = pagesRef.current;
      if (!lib || !container) { setStatus("error"); return; }
      try {
        if (window.__pdfReady) await window.__pdfReady;
        if (cancelled) return;
        pdfDoc = await lib.getDocument(book.sampleUrl).promise;
        if (cancelled) return;
        setPageInfo({ total: pdfDoc.numPages });
        container.innerHTML = "";

        // เรนเดอร์ 1:1 ตามความกว้างแสดงผล (ไม่ขยายภาพ → คมชัด ไม่เบลอ) คุมต้นทุนด้วยเพดานความกว้าง
        const displayW = Math.min(container.clientWidth - 32, 680);

        // เรนเดอร์หนึ่งหน้า พร้อม timeout กันค้าง
        const renderOne = (page, canvas, ms) => new Promise((resolve, reject) => {
          const base = page.getViewport({ scale: 1 });
          const ratio = base.height / base.width;
          const vp = page.getViewport({ scale: displayW / base.width });
          canvas.width = Math.floor(vp.width);
          canvas.height = Math.floor(vp.height);
          canvas.style.width = displayW + "px";
          canvas.style.height = Math.round(displayW * ratio) + "px";
          const task = page.render({ canvasContext: canvas.getContext("2d"), viewport: vp });
          const timer = setTimeout(() => { try { task.cancel(); } catch (e) {} reject(new Error("render-timeout")); }, ms);
          task.promise.then(() => { clearTimeout(timer); resolve(); }, (e) => { clearTimeout(timer); reject(e); });
        });

        // สร้าง placeholder ทุกหน้า (สำรองความสูง กันหน้ากระโดด)
        const reservedH = Math.round(displayW * 1.3);
        const canvases = [];
        for (let n = 1; n <= pdfDoc.numPages; n++) {
          const cv = document.createElement("canvas");
          cv.className = "pdfpage";
          cv.style.width = displayW + "px";
          cv.style.height = reservedH + "px";
          container.appendChild(cv);
          canvases.push(cv);
        }

        // คิวเรนเดอร์ทีละหน้า (กัน worker คอขวด)
        const queue = [];
        let working = false;
        const tryRender = async (n, cv, attempts) => {
          for (let a = 0; a < attempts; a++) {
            if (cancelled) return false;
            try {
              const pg = await pdfDoc.getPage(n);
              if (cancelled) return false;
              await renderOne(pg, cv, 30000);
              return true;
            } catch (e) { /* ลองใหม่ */ }
          }
          return false;
        };
        const pump = async () => {
          if (working || cancelled) return;
          working = true;
          while (queue.length && !cancelled) {
            const n = queue.shift();
            const cv = canvases[n - 1];
            if (!cv || cv.dataset.done) continue;
            cv.dataset.done = "1";
            // หน้าแรกลองได้ถึง 3 ครั้ง (กัน worker สะดุด) ก่อนยอมโชว์ error
            const ok = await tryRender(n, cv, n === 1 ? 3 : 1);
            if (cancelled) break;
            if (ok) {
              if (n === 1 && !readyShown) { readyShown = true; setStatus("ready"); }
            } else {
              delete cv.dataset.done; // ให้ลองใหม่ได้ถ้าเลื่อนกลับมา
              if (n === 1 && !readyShown) setStatus("error");
            }
          }
          working = false;
        };
        const enqueue = (n) => { if (!queue.includes(n)) queue.push(n); pump(); };

        // หน้าแรกก่อนเสมอ
        enqueue(1);

        // หน้าที่เหลือ: เรนเดอร์เมื่อเลื่อนเข้าใกล้ (lazy) — คมชัดเฉพาะหน้าที่ดูจริง
        io = new IntersectionObserver((entries) => {
          entries.forEach((ent) => {
            if (ent.isIntersecting) {
              const n = canvases.indexOf(ent.target) + 1;
              if (n >= 1) enqueue(n);
            }
          });
        }, { root: container.parentElement, rootMargin: "1000px 0px" });
        canvases.forEach((cv) => io.observe(cv));
      } catch (err) {
        if (!cancelled && !readyShown) setStatus("error");
      }
    }
    run();
    return () => { cancelled = true; if (io) io.disconnect(); if (pdfDoc) { try { pdfDoc.destroy(); } catch (e) {} } };
  }, [book.id]);

  return (
    <div className="pdfmodal" onClick={onClose}>
      <div className="pdfmodal-panel" onClick={(e) => e.stopPropagation()}>
        <div className="pdfmodal-bar">
          <div className="pdfmodal-head">
            <span className="pdfmodal-kicker">อ่านตัวอย่าง{pageInfo.total ? ` · ${pageInfo.total} หน้า` : ""}</span>
            <span className="pdfmodal-title">{book.title}</span>
          </div>
          <div className="pdfmodal-actions">
            <a className="pdfmodal-open" href={book.sampleUrl} target="_blank" rel="noreferrer">เปิดแท็บใหม่</a>
            <button className="pdfmodal-close" onClick={onClose} aria-label="ปิด">
              <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"><path d="M6 6l12 12M18 6L6 18" /></svg>
            </button>
          </div>
        </div>
        <div className="pdfmodal-frame">
          <div className="pdfmodal-pages" ref={pagesRef} />
          {status === "loading" && (
            <div className="pdfmodal-state">
              <span className="pdfmodal-spinner" />
              <span>กำลังโหลดตัวอย่าง…</span>
            </div>
          )}
          {status === "error" && (
            <div className="pdfmodal-state">
              <span>ไม่สามารถแสดงตัวอย่างในหน้านี้ได้</span>
              <a className="btn btn-solid btn-sm" href={book.sampleUrl} target="_blank" rel="noreferrer">
                <Icon name="book" size={16} /><span>เปิด PDF ในแท็บใหม่</span>
              </a>
            </div>
          )}
        </div>
        <div className="pdfmodal-foot">
          <span>ตัวอย่างบทที่ 1 — เนื้อหาเต็มมีในเล่ม</span>
          <a className="btn btn-solid btn-sm" href={book.buyUrl} target="_blank" rel="noreferrer">
            <Icon name="cart" size={16} /><span>ซื้อเล่มเต็มที่ mebmarket</span>
          </a>
        </div>
      </div>
    </div>
  );
}

function EbookDetail({ id, go, ebooks }) {
  const all = ebooks || [];
  const book = all.find((b) => b.id === id);
  const [showPdf, setShowPdf] = React.useState(false);
  useEffectE(() => { window.scrollTo(0, 0); }, [id]);
  // เล่มที่ยังไม่พร้อมขาย / ไม่พบ — เด้งกลับหน้ารวม
  useEffectE(() => {
    if (!book || !book.available) go({ page: "ebooks" });
  }, [id]);
  if (!book || !book.available) return null;
  const others = all.filter((b) => b.id !== book.id);
  return (
    <main className="page-pad">
      <div className="container">
        <button className="backlink" onClick={() => go({ page: "ebooks" })}><Icon name="arrowLeft" size={16} /> กลับไปอีบุ๊ก</button>
      </div>

      <section className="ebdetail">
        <div className="container ebdetail-grid">
          {/* ซ้าย: ปก + กล่องซื้อ (sticky) */}
          <aside className="ebdetail-side">
            <div className="ebdetail-cover"><BookCover book={book} size="lg" /></div>
            <div className="buybox">
              <div className="buybox-price">
                <span className="buybox-num">{book.price}</span>
                <span className="buybox-cur">{book.currency}</span>
              </div>
              <Button full size="lg" icon="cart" href={book.buyUrl}>ซื้อที่ mebmarket</Button>
              {book.sampleUrl && (
                <Button full variant="ghost" icon="book" onClick={() => setShowPdf(true)}>อ่านตัวอย่าง</Button>
              )}
              <ul className="buybox-meta">
                <li><span>รูปแบบ</span><strong>{book.format}</strong></li>
                <li><span>จำนวนหน้า</span><strong>{book.pages} หน้า</strong></li>
                <li><span>ระดับ</span><strong>{book.level}</strong></li>
              </ul>
              <p className="buybox-note">จำหน่ายผ่าน mebmarket.com — อ่านได้ทุกอุปกรณ์</p>
            </div>
          </aside>

          {/* ขวา: เนื้อหา */}
          <div className="ebdetail-main">
            <Pill tone="warm">หนังสือแนะนำ</Pill>
            <h1 className="ebdetail-title">{book.title}</h1>
            <p className="ebdetail-tagline">{book.tagline}</p>

            <div className="ebdetail-section">
              <h2 className="ebdetail-h2">เกี่ยวกับหนังสือเล่มนี้</h2>
              {(book.longDesc || []).map((p, i) => <p key={i} className="ebdetail-p">{p}</p>)}
            </div>

            <div className="ebdetail-section">
              <h2 className="ebdetail-h2">เหมาะกับใคร</h2>
              <ul className="ebdetail-forwhom">
                {(book.forWhom || []).map((w, i) => <li key={i}><Icon name="check" size={18} /> {w}</li>)}
              </ul>
            </div>

            <div className="ebdetail-section">
              <h2 className="ebdetail-h2">สารบัญโดยสังเขป</h2>
              <div className="toc">
                {(book.toc || []).map((part, i) => (
                  <div key={i} className="toc-part">
                    <div className="toc-part-head"><span className="toc-num">{String(i + 1).padStart(2, "0")}</span>{part.part}</div>
                    <ul className="toc-items">
                      {part.items.map((it, j) => <li key={j}>{it}</li>)}
                    </ul>
                  </div>
                ))}
              </div>
            </div>

            <div className="ebdetail-buy-cta">
              <div>
                <span className="ebdetail-buy-label">พร้อมเริ่มต้นแล้วใช่ไหม</span>
                <span className="ebdetail-buy-price">{book.price} {book.currency}</span>
              </div>
              <div className="ebdetail-buy-btns">
                {book.sampleUrl && (
                  <Button size="lg" variant="ghost" icon="book" onClick={() => setShowPdf(true)}>อ่านตัวอย่าง</Button>
                )}
                <Button size="lg" icon="cart" href={book.buyUrl}>สั่งซื้อที่ mebmarket</Button>
              </div>
            </div>
          </div>
        </div>
      </section>

      {others.length > 0 && (
        <section className="section section-tight">
          <div className="container">
            <SectionHead title="เล่มอื่น ๆ" />
            <div className="eb-grid">
              {others.map((b) => <EbookCardCover key={b.id} book={b} go={go} />)}
            </div>
          </div>
        </section>
      )}

      {showPdf && <PdfModal book={book} onClose={() => setShowPdf(false)} />}
    </main>
  );
}

Object.assign(window, { EbooksPage, EbookDetail, loadEbooks });
