// app/screens-reader.jsx — scripture reading view + full audio player.
// Real read-aloud via the Web Speech API, with live verse highlighting,
// a verse-based scrubber, ±skip, playback speed, and a sleep timer.
const { useState: useStateR, useEffect: useEffectR, useRef: useRefR, useMemo: useMemoR } = React;

// Flatten a day's portion into an ordered verse list across its chapters.
function buildVerseList(day) {
  if (!day || day.rest) return [];
  const out = [];
  const CH = window.CHAPTERS;
  for (let ci = day.startCh; ci <= day.endCh; ci++) {
    const ch = CH[ci];
    const rows = window.versesForChapter(ch);
    rows.forEach(r => out.push({
      chIdx: ci, ch: ch.chapter, bookName: ch.bookName, abbr: ch.abbr,
      n: r.n, text: r.text, real: window.hasRealText(ch),
      headOfChapter: r.n === 1,
    }));
  }
  return out;
}

function fmtClock(s) {
  s = Math.max(0, Math.round(s));
  const m = Math.floor(s / 60), ss = s % 60;
  return `${m}:${String(ss).padStart(2, '0')}`;
}

function ReaderScreen({ t, accent, font, fontScale = 1, plan, dayIdx, startAudio, completed, voice, rate: initialRate, onClose, onComplete }) {
  const day = plan.days[dayIdx];
  const verses = useMemoR(() => buildVerseList(day), [dayIdx]);
  const isDone = !!(day && completed[day.date]);

  const [showPlayer, setShowPlayer] = useStateR(!!startAudio);
  const [playing, setPlaying] = useStateR(false);
  const [cur, setCur] = useStateR(0);            // current verse index
  const [rate, setRate] = useStateR(initialRate || 1);
  const [sleepMin, setSleepMin] = useStateR(0);  // 0 = off
  const [sleepLeft, setSleepLeft] = useStateR(0);
  const [scale, setScale] = useStateR(fontScale);
  const [readPct, setReadPct] = useStateR(0);    // how far through the day's reading (scroll-based)

  function onReadScroll(e) {
    const el = e.currentTarget;
    const max = el.scrollHeight - el.clientHeight;
    setReadPct(max > 0 ? Math.max(0, Math.min(100, (el.scrollTop / max) * 100)) : 0);
  }

  const scrollRef = useRefR(null);
  const verseRefs = useRefR({});
  const playingRef = useRefR(false);
  const curRef = useRefR(0);
  const rateRef = useRefR(rate);
  rateRef.current = rate;
  curRef.current = cur;

  const avgSecPerVerse = 9; // estimate for scrubber when not speaking

  // ── speak a verse via the BomAudio engine (cloud-natural → device fallback) ─
  function speakFrom(idx) {
    if (idx >= verses.length) { stopAll(true); return; }
    window.BomAudio.speak(verses[idx].text, {
      voice: voice, rate: rateRef.current,
      onEnd: () => {
        if (!playingRef.current) return;
        const next = curRef.current + 1;
        if (next < verses.length) { setCur(next); curRef.current = next; speakFrom(next); }
        else { stopAll(true); }
      },
    });
  }

  function play() {
    if (!verses.length) return;
    setShowPlayer(true);
    setPlaying(true); playingRef.current = true;
    speakFrom(curRef.current);
  }
  function pause() {
    setPlaying(false); playingRef.current = false;
    window.BomAudio.stop();
  }
  function stopAll(finished) {
    setPlaying(false); playingRef.current = false;
    window.BomAudio.stop();
    if (finished) { setCur(0); curRef.current = 0; }
  }
  function jump(delta) {
    const ni = Math.max(0, Math.min(verses.length - 1, curRef.current + delta));
    setCur(ni); curRef.current = ni;
    if (playingRef.current) speakFrom(ni);
  }
  function seekTo(idx) {
    const ni = Math.max(0, Math.min(verses.length - 1, idx));
    setCur(ni); curRef.current = ni;
    if (playingRef.current) speakFrom(ni);
  }

  // cleanup on unmount
  useEffectR(() => () => { window.BomAudio.stop(); }, []);

  // auto-start if opened via Listen
  useEffectR(() => { if (startAudio) { const id = setTimeout(play, 250); return () => clearTimeout(id); } }, []);

  // keep current verse in view while playing
  useEffectR(() => {
    if (!playing) return;
    const el = verseRefs.current[cur];
    const sc = scrollRef.current;
    if (el && sc) {
      const top = el.offsetTop - sc.clientHeight * 0.38;
      sc.scrollTo({ top, behavior: 'smooth' });
    }
  }, [cur, playing]);

  // sleep timer
  useEffectR(() => {
    if (!sleepMin) { setSleepLeft(0); return; }
    setSleepLeft(sleepMin * 60);
    const id = setInterval(() => {
      setSleepLeft(s => {
        if (s <= 1) { clearInterval(id); pause(); setSleepMin(0); return 0; }
        return s - 1;
      });
    }, 1000);
    return () => clearInterval(id);
  }, [sleepMin]);

  if (!day || day.rest) {
    return (
      <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: t.reader }}>
        <ReaderTopBar t={t} accent={accent} font={font} title="Review & reflect" onClose={onClose} scale={scale} setScale={setScale} isDone={isDone} onComplete={() => onComplete(day.date)} />
        <div style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 14, padding: 40, textAlign: 'center' }}>
          <span style={{ color: accent.base }}><Icon name="bookmark" size={40} stroke={1.4} /></span>
          <div style={{ fontFamily: font, fontSize: 22, color: t.readerInk }}>A day to rest and reflect</div>
          <div style={{ fontSize: 14.5, color: t.ink2, lineHeight: 1.5, maxWidth: 260 }}>Revisit a passage that spoke to you this week, or simply rest. The plan continues tomorrow.</div>
        </div>
      </div>
    );
  }

  const pct = verses.length ? (cur / (verses.length - 1)) * 100 : 0;
  const totalSec = verses.length * avgSecPerVerse / rate;
  const elapsedSec = cur * avgSecPerVerse / rate;

  return (
    <div style={{ height: '100%', display: 'flex', flexDirection: 'column', background: t.reader }}>
      <ReaderTopBar t={t} accent={accent} font={font} title={day.ref} onClose={onClose} scale={scale} setScale={setScale} isDone={isDone} onComplete={() => onComplete(day.date)} />

      {/* reading progress — fills as you scroll (and as audio auto-scrolls) */}
      <div style={{ height: 3, background: t.line, position: 'relative', zIndex: 4, flexShrink: 0 }}>
        <div style={{ height: '100%', width: `${readPct}%`, background: accent.base, borderRadius: '0 2px 2px 0', transition: 'width 0.12s linear' }} />
      </div>

      {/* scripture */}
      <div ref={scrollRef} onScroll={onReadScroll} className="bom-scroll" style={{ flex: 1, overflowY: 'auto', padding: `8px 26px ${showPlayer ? 200 : 120}px` }}>
        {verses.map((v, i) => {
          const active = showPlayer && i === cur && playing;
          return (
            <React.Fragment key={i}>
              {v.headOfChapter && (
                <div style={{ margin: i === 0 ? '8px 0 14px' : '34px 0 14px', textAlign: 'center' }}>
                  <div style={{ fontSize: 11, letterSpacing: '0.22em', textTransform: 'uppercase', color: accent.base, fontWeight: 700 }}>{v.bookName}</div>
                  <div style={{ fontFamily: font, fontSize: 30, color: t.readerInk, fontWeight: 600, marginTop: 4 }}>Chapter {v.ch}</div>
                  <div style={{ width: 38, height: 2, background: accent.base, opacity: 0.5, margin: '12px auto 0' }} />
                </div>
              )}
              <p ref={el => verseRefs.current[i] = el}
                onClick={() => showPlayer && seekTo(i)}
                style={{
                  fontFamily: font, fontSize: 18.5 * scale, lineHeight: 1.62,
                  color: t.readerInk, margin: '0 0 4px', textIndent: 0,
                  display: 'block', padding: '3px 8px', borderRadius: 8,
                  background: active ? accent.soft : 'transparent',
                  transition: 'background 0.25s', cursor: showPlayer ? 'pointer' : 'default',
                  opacity: showPlayer && !active && playing ? 0.5 : 1,
                }}>
                <sup style={{ fontFamily: "'Inter', sans-serif", fontSize: 10.5 * scale, fontWeight: 700, color: accent.base, marginRight: 6, verticalAlign: 'baseline', lineHeight: 0 }}>{v.n}</sup>
                {v.text}
              </p>
            </React.Fragment>
          );
        })}

        {/* end-of-reading mark complete */}
        <div style={{ marginTop: 30, paddingTop: 22, borderTop: `1px solid ${t.line}`, textAlign: 'center' }}>
          <button onClick={() => onComplete(day.date)} disabled={isDone} className="bom-press" style={{
            width: '100%', height: 52, borderRadius: 15, border: 'none', cursor: isDone ? 'default' : 'pointer',
            background: isDone ? 'transparent' : accent.base, color: isDone ? accent.base : accent.ink,
            border: isDone ? `1.5px solid ${accent.base}` : 'none',
            fontWeight: 700, fontSize: 16, fontFamily: 'inherit', display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 8,
          }}>
            <Icon name={isDone ? 'check-circle' : 'check'} size={20} stroke={2.2} />
            {isDone ? 'Completed — well done' : 'Mark today complete'}
          </button>
          <div style={{ marginTop: 12, fontSize: 12.5, color: t.ink3, fontStyle: 'italic', fontFamily: font }}>
            “{day.verses} verses, finished in faith.”
          </div>
        </div>
      </div>

      {/* audio player */}
      {showPlayer && (
        <AudioPlayer t={t} accent={accent} font={font} verses={verses} cur={cur}
          playing={playing} onPlay={play} onPause={pause} onJumpV={jump} onSeek={seekTo}
          rate={rate} setRate={setRate} sleepMin={sleepMin} setSleepMin={setSleepMin} sleepLeft={sleepLeft}
          elapsedSec={elapsedSec} totalSec={totalSec} pct={pct} onHide={() => { pause(); setShowPlayer(false); }} />
      )}

      {/* floating Listen button when player hidden */}
      {!showPlayer && (
        <button onClick={play} className="bom-press" style={{
          position: 'absolute', right: 18, bottom: 30, width: 58, height: 58, borderRadius: 999,
          background: accent.base, color: accent.ink, border: 'none', cursor: 'pointer', zIndex: 30,
          boxShadow: '0 8px 22px rgba(0,0,0,0.28)', display: 'flex', alignItems: 'center', justifyContent: 'center',
        }}>
          <Icon name="headphones" size={26} stroke={1.9} />
        </button>
      )}
    </div>
  );
}

// ── Top bar ────────────────────────────────────────────────────────────────
function ReaderTopBar({ t, accent, font, title, onClose, scale, setScale, isDone, onComplete }) {
  return (
    <div style={{ paddingTop: 50, paddingBottom: 12, paddingLeft: 14, paddingRight: 14, background: t.reader, borderBottom: `1px solid ${t.line}`, display: 'flex', alignItems: 'center', gap: 8, position: 'relative', zIndex: 5 }}>
      <button onClick={onClose} className="bom-press" aria-label="Close" style={{ width: 38, height: 38, borderRadius: 11, border: 'none', background: 'transparent', color: t.readerInk, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <Icon name="chevron" size={24} stroke={2.1} style={{ transform: 'rotate(180deg)' }} />
      </button>
      <div style={{ flex: 1, textAlign: 'center' }}>
        <div style={{ fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: t.ink3, fontWeight: 700 }}>Today’s reading</div>
        <div style={{ fontFamily: font, fontSize: 18, color: t.readerInk, fontWeight: 600, marginTop: 1 }}>{title}</div>
      </div>
      <button onClick={() => setScale(s => s >= 1.3 ? 0.9 : Math.round((s + 0.1) * 10) / 10)} className="bom-press" aria-label="Text size" style={{ width: 38, height: 38, borderRadius: 11, border: 'none', background: 'transparent', color: t.readerInk, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' }}>
        <Icon name="text" size={21} stroke={1.9} />
      </button>
    </div>
  );
}

// ── Audio player ─────────────────────────────────────────────────────────────
const RATES = [0.75, 1, 1.25, 1.5];
const SLEEPS = [0, 5, 15, 30];

function AudioPlayer({ t, accent, font, verses, cur, playing, onPlay, onPause, onJumpV, onSeek, rate, setRate, sleepMin, setSleepMin, sleepLeft, elapsedSec, totalSec, pct, onHide }) {
  const cv = verses[cur] || {};
  const barRef = useRefR(null);
  function onScrub(e) {
    const r = barRef.current.getBoundingClientRect();
    const p = Math.max(0, Math.min(1, (e.clientX - r.left) / r.width));
    onSeek(Math.round(p * (verses.length - 1)));
  }
  return (
    <div style={{ position: 'absolute', left: 0, right: 0, bottom: 0, zIndex: 35, background: t.hero, borderTopLeftRadius: 24, borderTopRightRadius: 24, padding: '16px 20px 30px', boxShadow: '0 -10px 30px rgba(0,0,0,0.3)' }}>
      {/* now reading */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 12 }}>
        <div style={{ flex: 1, minWidth: 0, marginRight: 10 }}>
          <div style={{ fontSize: 10, letterSpacing: '0.16em', textTransform: 'uppercase', color: accent.base, fontWeight: 700 }}>Now reading</div>
          <div style={{ fontFamily: font, fontSize: 17, color: t.heroInk, fontWeight: 600, marginTop: 2, whiteSpace: 'nowrap', overflow: 'hidden', textOverflow: 'ellipsis' }}>
            {cv.bookName} {cv.ch}:{cv.n}
          </div>
        </div>
        <button onClick={onHide} className="bom-press" aria-label="Hide player" style={{ width: 34, height: 34, borderRadius: 10, border: 'none', background: 'rgba(255,255,255,0.12)', color: t.heroInk, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
          <Icon name="chevron" size={20} stroke={2.2} style={{ transform: 'rotate(90deg)' }} />
        </button>
      </div>

      {/* scrubber */}
      <div ref={barRef} onClick={onScrub} style={{ height: 18, display: 'flex', alignItems: 'center', cursor: 'pointer' }}>
        <div style={{ position: 'relative', width: '100%', height: 5, borderRadius: 999, background: 'rgba(255,255,255,0.16)' }}>
          <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: `${pct}%`, background: accent.base, borderRadius: 999 }} />
          <div style={{ position: 'absolute', left: `calc(${pct}% - 7px)`, top: '50%', transform: 'translateY(-50%)', width: 14, height: 14, borderRadius: 999, background: accent.base, boxShadow: '0 1px 4px rgba(0,0,0,0.4)' }} />
        </div>
      </div>
      <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 11, color: t.heroSub, fontWeight: 600, marginTop: 5, fontVariantNumeric: 'tabular-nums' }}>
        <span>{fmtClock(elapsedSec)}</span>
        <span>verse {cur + 1} of {verses.length}</span>
        <span>-{fmtClock(totalSec - elapsedSec)}</span>
      </div>

      {/* transport */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 22, margin: '10px 0 12px' }}>
        <button onClick={() => onJumpV(-1)} className="bom-press" aria-label="Previous verse" style={transportBtn(t)}>
          <Icon name="prev" size={26} />
        </button>
        <button onClick={() => onJumpV(-5)} className="bom-press" aria-label="Back" style={transportBtn(t)}>
          <Icon name="back15" size={24} />
        </button>
        <button onClick={playing ? onPause : onPlay} className="bom-press" aria-label={playing ? 'Pause' : 'Play'} style={{ width: 64, height: 64, borderRadius: 999, border: 'none', background: accent.base, color: accent.ink, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center', boxShadow: `0 6px 18px ${accent.soft}` }}>
          <Icon name={playing ? 'pause' : 'play'} size={30} />
        </button>
        <button onClick={() => onJumpV(5)} className="bom-press" aria-label="Forward" style={transportBtn(t)}>
          <Icon name="fwd15" size={24} />
        </button>
        <button onClick={() => onJumpV(1)} className="bom-press" aria-label="Next verse" style={transportBtn(t)}>
          <Icon name="next" size={26} />
        </button>
      </div>

      {/* speed + sleep */}
      <div style={{ display: 'flex', gap: 10 }}>
        <div style={{ flex: 1, display: 'flex', alignItems: 'center', gap: 8, background: 'rgba(255,255,255,0.08)', borderRadius: 12, padding: '8px 10px' }}>
          <span style={{ fontSize: 11, color: t.heroSub, fontWeight: 700, letterSpacing: '0.04em' }}>SPEED</span>
          <div style={{ display: 'flex', gap: 4, flex: 1, justifyContent: 'flex-end' }}>
            {RATES.map(r => (
              <button key={r} onClick={() => setRate(r)} className="bom-press" style={{ border: 'none', cursor: 'pointer', borderRadius: 8, padding: '4px 8px', fontSize: 12, fontWeight: 700, fontFamily: 'inherit', background: rate === r ? accent.base : 'transparent', color: rate === r ? accent.ink : t.heroSub }}>
                {r}×
              </button>
            ))}
          </div>
        </div>
        <button onClick={() => { const i = SLEEPS.indexOf(sleepMin); setSleepMin(SLEEPS[(i + 1) % SLEEPS.length]); }} className="bom-press" style={{ display: 'flex', alignItems: 'center', gap: 6, background: sleepMin ? accent.soft : 'rgba(255,255,255,0.08)', border: 'none', borderRadius: 12, padding: '8px 12px', cursor: 'pointer', color: sleepMin ? accent.base : t.heroSub, fontWeight: 700, fontSize: 12, fontFamily: 'inherit' }}>
          <Icon name="moon" size={16} stroke={1.9} />
          {sleepMin ? fmtClock(sleepLeft) : 'Sleep'}
        </button>
      </div>
    </div>
  );
}
function transportBtn(t) {
  return { width: 44, height: 44, borderRadius: 12, border: 'none', background: 'transparent', color: t.heroInk, cursor: 'pointer', display: 'flex', alignItems: 'center', justifyContent: 'center' };
}

Object.assign(window, { ReaderScreen });
