// Deck shell — scaling, navigation, presentation mode, analytics.
// Sessions are upserted to the server via PUT /api/deck-views/:id so admin
// gets a live view of who is reading the roadmap.
function persistDeckSession(session) {
  // Fire-and-forget: never disrupt the deck experience on a network blip.
  try {
    window.api.put("/api/deck-views/" + encodeURIComponent(session.id), {
      startedAt: session.startedAt,
      endedAt: session.endedAt || Date.now(),
      slides: session.slides,
      maxIndex: session.maxIndex,
      reachedEnd: !!session.reachedEnd,
    }).catch(() => {});
  } catch {}
}

function DeckRunner({ user, onLeave, onLogout }) {
  const slides = window.DECK_SLIDES;
  const [idx, setIdx] = useState(0);
  const [presenting, setPresenting] = useState(false);
  const [scale, setScale] = useState(1);
  const stageRef = useRef(null);
  const wrapRef = useRef(null);
  const sessionRef = useRef(null);
  const slideEnterRef = useRef(null);

  // Init session record + flush dwell time on slide change/unmount.
  useEffect(() => {
    sessionRef.current = {
      id: "v_" + Date.now() + "_" + Math.random().toString(36).slice(2, 7),
      user: { name: user.name },
      startedAt: Date.now(),
      endedAt: null,
      slides: slides.map(s => ({ id: s.id, title: s.title || s.eyebrow || s.kind, dwellMs: 0 })),
      maxIndex: 0,
      reachedEnd: false
    };
    slideEnterRef.current = Date.now();
    persistDeckSession(sessionRef.current);
    return () => {
      flushSlide(idxRef.current);
      sessionRef.current.endedAt = Date.now();
      persistDeckSession(sessionRef.current);
    };
    // eslint-disable-next-line
  }, []);

  // Mirror idx in a ref so cleanup gets the latest value
  const idxRef = useRef(idx);
  useEffect(() => { idxRef.current = idx; }, [idx]);

  function flushSlide(slideIdx) {
    if (!sessionRef.current) return;
    if (slideIdx == null || slideIdx < 0 || slideIdx >= sessionRef.current.slides.length) return;
    const dwell = Date.now() - (slideEnterRef.current || Date.now());
    sessionRef.current.slides[slideIdx].dwellMs += dwell;
    if (slideIdx > sessionRef.current.maxIndex) sessionRef.current.maxIndex = slideIdx;
    if (slideIdx === sessionRef.current.slides.length - 1) sessionRef.current.reachedEnd = true;
    persistDeckSession(sessionRef.current);
  }

  function go(next) {
    flushSlide(idx);
    slideEnterRef.current = Date.now();
    setIdx(Math.max(0, Math.min(slides.length - 1, next)));
  }

  // Keyboard nav
  useEffect(() => {
    function onKey(e) {
      if (e.target && (e.target.tagName === "INPUT" || e.target.tagName === "TEXTAREA")) return;
      if (e.key === "ArrowRight" || e.key === " " || e.key === "PageDown") { e.preventDefault(); go(idx + 1); }
      else if (e.key === "ArrowLeft" || e.key === "PageUp") { e.preventDefault(); go(idx - 1); }
      else if (e.key === "Home") { go(0); }
      else if (e.key === "End") { go(slides.length - 1); }
      else if (e.key === "Escape") { if (presenting) togglePresent(false); }
      else if (e.key.toLowerCase() === "p") { togglePresent(); }
    }
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [idx, presenting]);

  // Scaling — fit 1920x1080 into available area
  useEffect(() => {
    function fit() {
      const wrap = wrapRef.current;
      if (!wrap) return;
      const rect = wrap.getBoundingClientRect();
      const padX = presenting ? 0 : 48;
      const padY = presenting ? 0 : 48;
      const availW = rect.width - padX;
      const availH = rect.height - padY;
      const s = Math.min(availW / 1920, availH / 1080, 1);
      setScale(s);
    }
    fit();
    const ro = new ResizeObserver(fit);
    if (wrapRef.current) ro.observe(wrapRef.current);
    window.addEventListener("resize", fit);
    return () => { ro.disconnect(); window.removeEventListener("resize", fit); };
  }, [presenting]);

  function togglePresent(forceVal) {
    const next = forceVal === undefined ? !presenting : forceVal;
    setPresenting(next);
    if (next) {
      const el = document.documentElement;
      if (el.requestFullscreen) el.requestFullscreen().catch(()=>{});
    } else {
      if (document.fullscreenElement && document.exitFullscreen) document.exitFullscreen().catch(()=>{});
    }
  }

  return (
    <div className={"deck-root " + (presenting ? "presenting" : "")}>
      {!presenting && (
        <div className="deck-topbar">
          <div className="deck-topbar-l">
            <button className="btn ghost" onClick={onLeave}>← Home</button>
            <div className="deck-title-mini">
              <div className="t1">AI Transformation Roadmap</div>
              <div className="t2">The Wellbeing Outfit · Confidential</div>
            </div>
          </div>
          <div className="deck-topbar-r">
            <button className="btn ghost" onClick={() => togglePresent(true)}>▶ Present</button>
            {onLogout && <button className="btn ghost" onClick={onLogout} style={{marginLeft:8}}>Sign out</button>}
          </div>
        </div>
      )}

      <div className="deck-stage-wrap" ref={wrapRef}>
        <div
          className="deck-stage"
          ref={stageRef}
          style={{ transform: `translate(-50%, -50%) scale(${scale})` }}
        >
          {slides.map((s, i) => (
            <div key={s.id} className={"deck-slide-frame " + (i === idx ? "active" : i < idx ? "past" : "future")}>
              <DeckSlide slide={s} active={i === idx} />
            </div>
          ))}
        </div>

        {/* Slide counter (visible in both modes) */}
        <div className="deck-counter">
          {String(idx+1).padStart(2,"0")} <span>/ {String(slides.length).padStart(2,"0")}</span>
        </div>

        {/* Nav arrows */}
        <button className="deck-nav prev" onClick={() => go(idx-1)} disabled={idx===0} aria-label="Previous slide">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M15 6l-6 6 6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>
        <button className="deck-nav next" onClick={() => go(idx+1)} disabled={idx===slides.length-1} aria-label="Next slide">
          <svg width="20" height="20" viewBox="0 0 24 24" fill="none"><path d="M9 6l6 6-6 6" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
        </button>

        {/* Bottom progress bar */}
        <div className="deck-progress" onClick={(e) => {
          const r = e.currentTarget.getBoundingClientRect();
          const p = (e.clientX - r.left) / r.width;
          go(Math.floor(p * slides.length));
        }}>
          <div className="deck-progress-fill" style={{ width: ((idx+1)/slides.length*100) + "%" }} />
          <div className="deck-progress-dots">
            {slides.map((s, i) => (
              <div key={s.id} className={"deck-dot " + (i === idx ? "on" : i < idx ? "past" : "")} onClick={(e) => { e.stopPropagation(); go(i); }} title={s.title || s.eyebrow || s.kind}/>
            ))}
          </div>
        </div>

        {presenting && (
          <button className="deck-exit-present" onClick={() => togglePresent(false)} title="Exit presentation (Esc)">
            <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round"/></svg>
          </button>
        )}
      </div>
    </div>
  );
}

window.DeckRunner = DeckRunner;
