// HyperBook — main React app
// Mobile-first book reading experience with magical TOC → summary unfold.

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

const TWEAKS = /*EDITMODE-BEGIN*/{
  "transition": "unfold",
  "paperTone": "cream",
  "typeSize": 17,
  "lampMode": false,
  "showPullQuote": true
}/*EDITMODE-END*/;

// ─────────────────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────────────────

// Flatten all chapters with part metadata for indexed navigation.
function flattenChapters(book) {
  const out = [];
  book.parts.forEach((p) => {
    p.chapters.forEach((ch) => {
      out.push({ ...ch, partTitle: p.title, partRoman: p.part });
    });
  });
  return out;
}

// VT323 / chrome label
const Chrome = ({ children, style }) => (
  <span style={{
    fontFamily: 'var(--font-mono)',
    fontSize: 13,
    letterSpacing: '.18em',
    textTransform: 'uppercase',
    color: 'var(--ink)',
    whiteSpace: 'nowrap',
    ...style,
  }}>{children}</span>
);

// ─────────────────────────────────────────────────────────────────────────
// Page chrome header — printed-book style
// ─────────────────────────────────────────────────────────────────────────

function PageHeader({ chapter, totalPages, onContents, lampMode }) {
  const fg = lampMode ? 'var(--paper)' : 'var(--ink)';
  const sub = lampMode ? 'rgba(246,241,229,0.55)' : 'var(--ink-mute)';
  const bg = lampMode ? '#15110F' : 'var(--paper)';
  const border = lampMode ? 'rgba(246,241,229,0.18)' : 'var(--ink)';
  return (
    <header style={{
      position: 'sticky', top: 0, zIndex: 30,
      background: bg, borderBottom: `1px solid ${border}`,
      padding: '10px 18px 8px',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        gap: 10,
      }}>
        <button onClick={onContents} aria-label="Open contents"
                style={{
                  appearance: 'none', background: 'transparent',
                  border: `1px solid ${border}`, color: fg,
                  padding: '6px 10px', cursor: 'pointer',
                  fontFamily: 'var(--font-mono)', fontSize: 12,
                  letterSpacing: '.18em', textTransform: 'uppercase',
                  display: 'flex', alignItems: 'center', gap: 8,
                }}>
          <svg width="13" height="11" viewBox="0 0 13 11" fill="none" aria-hidden>
            <path d="M1 1.5h11M1 5.5h11M1 9.5h7" stroke="currentColor" strokeWidth="1.4" strokeLinecap="square"/>
          </svg>
          Contents
        </button>

        <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 1 }}>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 13, letterSpacing: '.22em',
            color: fg, textTransform: 'uppercase',
          }}>{`p. ${chapter.page}`}</span>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.22em',
            color: sub, textTransform: 'uppercase',
          }}>{`of ${totalPages}`}</span>
        </div>

        <div style={{
          display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 1,
        }}>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 13, letterSpacing: '.22em',
            color: fg, textTransform: 'uppercase',
          }}>{`ch. ${chapter.n}`}</span>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.22em',
            color: sub, textTransform: 'uppercase',
          }}>{`pt. ${chapter.partRoman}`}</span>
        </div>
      </div>
    </header>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Reading view
// ─────────────────────────────────────────────────────────────────────────

function ReadingView({ chapter, all, onNavigate, lampMode, typeSize, showPullQuote }) {
  const idx = all.findIndex((c) => c.n === chapter.n);
  const prev = idx > 0 ? all[idx - 1] : null;
  const next = idx < all.length - 1 ? all[idx + 1] : null;

  const fg = lampMode ? 'var(--paper)' : 'var(--ink)';
  const fg2 = lampMode ? 'rgba(246,241,229,0.78)' : 'var(--ink-soft)';
  const fg3 = lampMode ? 'rgba(246,241,229,0.5)' : 'var(--ink-mute)';
  const accent = lampMode ? '#E89260' : 'var(--flame)';

  return (
    <article style={{ padding: '24px 22px 96px' }}>

      {/* eyebrow */}
      <div style={{ display: 'flex', alignItems: 'baseline', gap: 10, marginBottom: 14 }}>
        <Chrome style={{ color: accent, fontSize: 12 }}>
          {`Part ${chapter.partRoman} · ${chapter.partTitle}`}
        </Chrome>
        <span style={{
          flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.3)' : 'var(--ink)',
          opacity: 0.4, marginBottom: 2,
        }} />
        <Chrome style={{ color: fg3, fontSize: 11 }}>{`${chapter.readMin} min`}</Chrome>
      </div>

      {/* chapter number — restrained, like a printed book */}
      <div style={{
        fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.3em',
        color: fg3, textTransform: 'uppercase', marginBottom: 8,
      }}>{`Chapter ${chapter.n}`}</div>

      {/* chapter title — editorial, not hero */}
      <h1 style={{
        fontFamily: 'var(--font-serif)', fontWeight: 500, fontStyle: 'normal',
        fontSize: 28, lineHeight: 1.12, letterSpacing: '-0.01em',
        color: fg, margin: '0 0 28px',
        textWrap: 'balance',
      }}>{chapter.title}</h1>

      {/* body — markdown-rendered. First paragraph gets drop cap; pull quote
          is injected after the 2nd paragraph. */}
      {(() => {
        const md = Array.isArray(chapter.body) ? chapter.body.join('\n\n') : chapter.body;
        const theme = buildTheme({
          lampMode, typeSize, accent, fg, fg2, fg3, scale: 'mobile',
        });
        const pqEl = showPullQuote && chapter.pullQuote
          ? <PullQuote text={chapter.pullQuote} lampMode={lampMode} accent={accent} fg={fg} />
          : null;
        return (
          <Markdown
            text={md}
            theme={theme}
            dropCap={true}
            pullQuoteAfter={2}
            pullQuoteEl={pqEl}
          />
        );
      })()}

      {/* tail ornament */}
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        margin: '36px 0 28px', gap: 12,
      }}>
        <span style={{ width: 28, height: 1, background: lampMode ? 'rgba(246,241,229,0.3)' : 'var(--ink)' }} />
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 13, letterSpacing: '.3em',
          color: fg3,
        }}>§</span>
        <span style={{ width: 28, height: 1, background: lampMode ? 'rgba(246,241,229,0.3)' : 'var(--ink)' }} />
      </div>

      {/* prev / next footer */}
      <nav style={{
        display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 10,
        marginTop: 24,
      }}>
        {prev ? (
          <ChapterLink dir="prev" chapter={prev} onClick={() => onNavigate(prev.n)} lampMode={lampMode} />
        ) : <div />}
        {next ? (
          <ChapterLink dir="next" chapter={next} onClick={() => onNavigate(next.n)} lampMode={lampMode} />
        ) : <div />}
      </nav>
    </article>
  );
}

function PullQuote({ text, lampMode, accent, fg }) {
  const border = lampMode ? 'rgba(246,241,229,0.35)' : 'var(--ink)';
  return (
    <aside style={{
      margin: '24px -4px 24px',
      padding: '18px 18px 18px 20px',
      borderTop: `1.5px solid ${border}`,
      borderBottom: `1.5px solid ${border}`,
      position: 'relative',
    }}>
      <div style={{
        position: 'absolute', top: -12, left: 16,
        background: lampMode ? '#15110F' : 'var(--paper)',
        padding: '0 8px',
        fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.22em',
        color: accent, textTransform: 'uppercase',
      }}>« quote</div>
      <p style={{
        fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontWeight: 500,
        fontSize: 20, lineHeight: 1.28, color: fg,
        margin: 0, textWrap: 'balance',
      }}>{text}</p>
    </aside>
  );
}

function ChapterLink({ dir, chapter, onClick, lampMode }) {
  const isPrev = dir === 'prev';
  const fg = lampMode ? 'var(--paper)' : 'var(--ink)';
  const fg3 = lampMode ? 'rgba(246,241,229,0.5)' : 'var(--ink-mute)';
  const border = lampMode ? 'rgba(246,241,229,0.3)' : 'var(--ink)';
  return (
    <button onClick={onClick} style={{
      appearance: 'none', background: 'transparent',
      border: `1px solid ${border}`,
      padding: '12px 12px 12px',
      cursor: 'pointer',
      textAlign: isPrev ? 'left' : 'right',
      display: 'flex', flexDirection: 'column', gap: 4,
    }}>
      <span style={{
        fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.22em',
        color: fg3, textTransform: 'uppercase',
      }}>{isPrev ? `← ch. ${chapter.n}` : `ch. ${chapter.n} →`}</span>
      <span style={{
        fontFamily: 'var(--font-serif)', fontWeight: 500, fontSize: 14,
        color: fg, lineHeight: 1.2, textWrap: 'balance',
      }}>{chapter.title}</span>
    </button>
  );
}

window.PageHeader = PageHeader;
window.ReadingView = ReadingView;
window.flattenChapters = flattenChapters;
window.Chrome = Chrome;
