/* global React, window */
// ============================================================
// BOOK ENGINE — CSS 3D single-leaf flip + shell + cover
// ============================================================

function CoverArt({ t, variant }) {
  const { PixelTuxedoCat, PixelGirl } = window;
  const Cat = (size) => (
    <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "center", gap: 2 }}>
      <PixelGirl size={Math.round(size * 0.95)} />
      <span id="cover-cat-anchor" style={{ display: "inline-block" }}><PixelTuxedoCat size={Math.round(size * 0.82)} blink={true} /></span>
    </div>
  );
  const base = {
    position: "absolute", inset: 0, borderRadius: "4px 8px 8px 4px",
    background: "linear-gradient(135deg,#d9c9ac,#cdb893)", color: "#2a1a0c",
    boxShadow: "inset 0 0 0 1px rgba(255,255,255,.25), inset 0 0 60px rgba(90,55,30,.25)",
    overflow: "hidden", display: "flex", flexDirection: "column",
  };
  const spine = (
    <div style={{ position: "absolute", insetInlineStart: 0, top: 0, bottom: 0, width: 16,
      background: "linear-gradient(90deg,#7a4a24,#5a3318)", boxShadow: "2px 0 6px rgba(0,0,0,.3)" }} />
  );
  const grain = (
    <div className="paper" style={{ position: "absolute", inset: 0, background: "none" }} />
  );

  if (variant === "minimal") {
    return (
      <div style={{ ...base, background: "linear-gradient(135deg,#f4ead7,#e9dcc4)" }}>
        {spine}{grain}
        <div style={{ flex: 1, display: "flex", flexDirection: "column", justifyContent: "space-between", padding: "34px 28px 28px 32px" }}>
          <div style={{ fontFamily: "var(--mono)", fontSize: 10, letterSpacing: ".3em", textTransform: "uppercase", opacity: .6 }}>{t.fieldBook}</div>
          <div>
            {Cat(108)}
          </div>
          <div>
            <div style={{ fontFamily: "var(--serif-display)", fontSize: 30, lineHeight: 1, textWrap: "balance" }}>{t.name}</div>
            <div style={{ fontStyle: "italic", fontSize: 13, opacity: .7, marginTop: 6 }}>{t.role}</div>
          </div>
        </div>
      </div>
    );
  }
  if (variant === "stamp") {
    return (
      <div style={{ ...base, background: "linear-gradient(140deg,#c9663f,#a44e2c)", color: "#f6ead6" }}>
        {spine}{grain}
        <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", padding: "30px 24px 24px 32px", gap: 12 }}>
        <div style={{ borderRadius: "20px", padding: "10px 8px", display: "grid", placeItems: "center" }}>
            {Cat(118)}
          </div>
          <div style={{ fontFamily: "var(--serif-display)", fontSize: 28, lineHeight: 1, textWrap: "balance" }}>{t.name}</div>
          <div style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: ".22em", textTransform: "uppercase", opacity: .85 }}>{t.role}</div>
        </div>
      </div>
    );
  }
  // default: embossed broadsheet
  return (
    <div style={base}>
      {spine}{grain}
      <div style={{ position: "absolute", inset: "16px 16px 16px 26px", border: "2px solid rgba(90,55,30,.45)", borderRadius: 3 }} />
      <div style={{ flex: 1, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", textAlign: "center", padding: "34px 28px 28px 36px", gap: 8 }}>
        <div style={{ fontFamily: "var(--mono)", fontSize: 9.5, letterSpacing: ".34em", textTransform: "uppercase", opacity: .65 }}>{t.fieldBook}</div>
        <div style={{ width: 60, height: 1, background: "rgba(90,55,30,.5)" }} />
        {Cat(132)}
        <div style={{ fontFamily: "var(--serif-display)", fontSize: 34, lineHeight: .98, textWrap: "balance", marginTop: 4 }}>{t.name}</div>
        <div style={{ fontStyle: "italic", fontSize: 13.5, opacity: .78 }}>{t.role}</div>
        <div style={{ fontFamily: "var(--mono)", fontSize: 9, letterSpacing: ".2em", textTransform: "uppercase", opacity: .55, marginTop: 6 }}>{t.place}</div>
      </div>
    </div>
  );
}

function Face({ realm, side, children }) {
  return (
    <div className={"page " + side + " realm-" + realm}>
      <div className="page-inner">{children}</div>
    </div>
  );
}

function Book({ lang, setLang, t, turnMs, sound, coverStyle, playTurn }) {
  const { Pages, RisoPages } = window;
  const reduce = window.matchMedia && window.matchMedia("(prefers-reduced-motion: reduce)").matches;

  const SPREADS = React.useMemo(() => [
    { L: Pages.PgWelcome,     R: Pages.PgRealms,      realmL: "analog",    realmR: "analog" },
    { L: Pages.PgObjective,   R: Pages.PgExperience1, realmL: "analog",    realmR: "analog" },
    { L: Pages.PgExperience2, R: Pages.PgSkills,      realmL: "analog",    realmR: "analog" },
    { L: Pages.PgEducation,   R: RisoPages.PgRisoIntro, realmL: "analog",  realmR: "risograph" },
    { L: RisoPages.PgProjects, R: RisoPages.PgStudio, realmL: "risograph", realmR: "analog" },
    { L: RisoPages.PgContact, R: RisoPages.PgColophon, realmL: "analog",   realmR: "analog" },
  ], [Pages, RisoPages]);

  const CHAPTERS = [
    { en: "Analog · Field Notes", ar: "التناظري · ملاحظات", sp: [0, 1, 2] },
    { en: "Risograph · Print Room", ar: "الريزوغراف · المطبعة", sp: [3, 4] },
    { en: "The Studio", ar: "الاستوديو", sp: [5] },
  ];

  const [phase, setPhase] = React.useState("closed");
  const [opening, setOpening] = React.useState(false);
  const [shown, setShown] = React.useState(false);
  const [spread, setSpread] = React.useState(0);
  const [caseP, setCaseP] = React.useState(null);
  const [flip, setFlip] = React.useState(null);   // {visual:'next'|'prev', target}
  const [active, setActive] = React.useState(false);
  const [hero, setHero] = React.useState(null);    // cover→welcome cat transition
  const committed = React.useRef(false);
  const timers = React.useRef([]);

  const ctx = { t, lang, go: (key) => goRealm(key), openCase: setCaseP, onLang: setLang };
  const face = (i, side) => {
    const sp = SPREADS[i]; const C = side === "left" ? sp.L : sp.R;
    return { realm: side === "left" ? sp.realmL : sp.realmR, node: <C {...ctx} /> };
  };

  const openBook = () => {
    const fromEl = document.getElementById("cover-cat-anchor");
    const from = fromEl ? fromEl.getBoundingClientRect() : null;
    setOpening(true);
    if (!reduce && from) setHero({ from, to: null, fly: false });
    setTimeout(() => {
      setPhase("open");
      setTimeout(() => {
        setShown(true);
        if (!reduce && from) {
          setTimeout(() => {
            const toEl = document.getElementById("welcome-cat-anchor");
            const to = toEl ? toEl.getBoundingClientRect() : null;
            if (to) {
              setHero({ from, to, fly: true });
              timersHero(setTimeout(() => setHero(null), 820));
            } else { setHero(null); }
          }, 80);
        }
      }, 30);
    }, reduce ? 10 : 620);
  };
  const timersHero = (id) => { committed._h = id; };
  const closeBook = () => { setShown(false); setTimeout(() => { setPhase("closed"); setOpening(false); }, 300); };

  const commit = (target) => {
    if (committed.current) return;
    committed.current = true;
    timers.current.forEach(clearTimeout); timers.current = [];
    setSpread(target); setFlip(null); setActive(false);
  };

  const animate = (target) => {
    if (flip || target < 0 || target >= SPREADS.length || target === spread) return;
    const fwd = target > spread;
    const visual = lang === "ar" ? (fwd ? "prev" : "next") : (fwd ? "next" : "prev");
    if (sound) playTurn();
    if (reduce) { setSpread(target); return; }
    committed.current = false;
    setActive(false);
    setFlip({ visual, target });
    // kick the rotation on the next frame, then guarantee a commit
    timers.current.push(setTimeout(() => setActive(true), 30));
    timers.current.push(setTimeout(() => commit(target), turnMs + 220));
  };
  const forward = () => animate(spread + 1);
  const backward = () => animate(spread - 1);
  const goRealm = (key) => {
    const target = key === "risograph" ? 3 : key === "analog" ? 0 : 0;
    animate(target);
  };

  const onFlipEnd = (e) => {
    if (e.propertyName !== "transform" || !flip) return;
    commit(flip.target);
  };

  React.useEffect(() => {
    if (phase !== "open") return;
    const k = (e) => {
      if (caseP) return;
      if (e.key === "ArrowRight") forward();
      else if (e.key === "ArrowLeft") backward();
      else if (e.key === " ") { e.preventDefault(); forward(); }
    };
    window.addEventListener("keydown", k);
    return () => window.removeEventListener("keydown", k);
  }, [phase, spread, flip, caseP, lang]);

  // compute faces
  let underL, underR, flipSide, frontFace, backFace;
  if (flip) {
    const s = spread, target = flip.target;
    if (flip.visual === "next") {
      underL = face(s, "left"); underR = face(target, "right");
      flipSide = "next"; frontFace = face(s, "right"); backFace = face(target, "left");
    } else {
      underL = face(target, "left"); underR = face(s, "right");
      flipSide = "prev"; frontFace = face(s, "left"); backFace = face(target, "right");
    }
  } else {
    underL = face(spread, "left"); underR = face(spread, "right");
  }

  const chap = CHAPTERS.find(c => c.sp.includes(spread)) || CHAPTERS[0];
  const turnSec = (turnMs / 1000) + "s";
  const flipTransform = flipSide === "next"
    ? (active ? "rotateY(-180deg)" : "rotateY(0deg)")
    : (active ? "rotateY(180deg)" : "rotateY(0deg)");

  const fwdSideStyle = lang === "ar" ? { left: "max(18px,3vw)" } : { right: "max(18px,3vw)" };
  const backSideStyle = lang === "ar" ? { right: "max(18px,3vw)" } : { left: "max(18px,3vw)" };

  return (
    <div className={"stage" + (hero ? " hero-active" : "")}>
      {phase === "closed" && (
        <div className={"cover-scene" + (opening ? " gone" : "")}>
          <div className={"book-closed" + (opening ? " opening" : "")} onClick={openBook}>
            <CoverArt t={t} variant={coverStyle} />
          </div>
          <button className="pill" onClick={openBook} style={{ pointerEvents: "auto" }}>
            {t.openBook} · <span style={{ opacity: .6 }}>{t.openHint}</span>
          </button>
        </div>
      )}

      {phase === "open" && (
        <React.Fragment>
          <div className={"book-open" + (shown ? " shown" : "")}>
            <div className="spread">
              <Face realm={underL.realm} side="left">{underL.node}</Face>
              <Face realm={underR.realm} side="right">{underR.node}</Face>
            </div>
            {flip && (
              <div className={"flipper " + flipSide + (active ? " turning" : "")}
                style={{ transform: flipTransform, transformOrigin: flipSide === "next" ? "left center" : "right center", transition: `transform ${turnSec} cubic-bezier(.4,0,.2,1)` }}
                onTransitionEnd={onFlipEnd}>
                <div className={"flip-face front realm-" + frontFace.realm}>
                  <div className="page-inner">{frontFace.node}</div>
                </div>
                <div className={"flip-face back realm-" + backFace.realm}>
                  <div className="page-inner">{backFace.node}</div>
                </div>
              </div>
            )}
          </div>

          <button className="nav-arrow prev" style={backSideStyle} onClick={backward} disabled={spread === 0 || !!flip} aria-label="previous">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M15 5l-7 7 7 7" /></svg>
          </button>
          <button className="nav-arrow next" style={fwdSideStyle} onClick={forward} disabled={spread === SPREADS.length - 1 || !!flip} aria-label="next">
            <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><path d="M9 5l7 7-7 7" /></svg>
          </button>

          <div className="page-counter">
            <button className="pill" onClick={closeBook} style={{ padding: "5px 10px" }}>{lang === "ar" ? "الغلاف" : "cover"}</button>
            <span className="chap">{lang === "ar" ? chap.ar : chap.en}</span>
            <div className="chap-dots">
              {SPREADS.map((_, i) => (
                <button key={i} className={i === spread ? "active" : ""} onClick={() => animate(i)} aria-label={"spread " + (i + 1)} />
              ))}
            </div>
          </div>
        </React.Fragment>
      )}

      {caseP && <RisoPages.CaseStudy p={caseP} lang={lang} t={t} onClose={() => setCaseP(null)} />}

      {hero && (() => {
        const f = hero.from, to = hero.to;
        const s = hero.fly && to ? (to.width / f.width) : 1;
        const dx = hero.fly && to ? (to.left - f.left) : 0;
        const dy = hero.fly && to ? (to.top - f.top) : 0;
        return (
          <div style={{
            position: "fixed", left: f.left, top: f.top, width: f.width, height: f.height,
            zIndex: 150, pointerEvents: "none", transformOrigin: "top left",
            transform: `translate(${dx}px,${dy}px) scale(${s})`,
            opacity: 1,
            transition: hero.fly ? "transform .72s cubic-bezier(.5,0,.2,1)" : "none",
          }}>
            <window.PixelTuxedoCat size={f.width} blink={false} />
          </div>
        );
      })()}
    </div>
  );
}

window.Book = Book;
