// HyperBook — Contents drawer with magical summary unfold
// This is the "magical but functional" centerpiece.

const { useState: useStateToc, useEffect: useEffectToc, useRef: useRefToc, useLayoutEffect } = React;

// ─────────────────────────────────────────────────────────────────────────
// Animated height container — for "unfold" transition
// Renders children inside a measured wrapper, animates max-height + opacity
// when the children change. Interruptible.
// ─────────────────────────────────────────────────────────────────────────

function MagicReveal({ chapterKey, transition, lampMode, children }) {
  const [phase, setPhase] = useStateToc('in');        // 'out' → 'in'
  const [renderedKey, setRenderedKey] = useStateToc(chapterKey);
  const [renderedChildren, setRenderedChildren] = useStateToc(children);
  const innerRef = useRefToc(null);
  const wrapRef = useRefToc(null);

  // When chapterKey changes, play out → swap → in
  useEffectToc(() => {
    if (chapterKey === renderedKey) {
      // Just refresh children if same chapter (e.g. rerender)
      setRenderedChildren(children);
      return;
    }
    setPhase('out');
    const t = setTimeout(() => {
      setRenderedKey(chapterKey);
      setRenderedChildren(children);
      // next frame: phase 'in'
      requestAnimationFrame(() => {
        requestAnimationFrame(() => setPhase('in'));
      });
    }, 140);
    return () => clearTimeout(t);
  }, [chapterKey, children, renderedKey]);

  // Each transition variant — pure CSS state, very short durations
  const styles = transitionStyles(transition, phase, lampMode);

  return (
    <div ref={wrapRef} style={{
      overflow: 'hidden',
      transition: 'max-height 180ms linear',
      maxHeight: styles.wrap.maxHeight,
    }}>
      <div ref={innerRef} style={styles.inner}>
        {renderedChildren}
      </div>
    </div>
  );
}

// transitions: unfold | fold | fade | marginalia | bleed
function transitionStyles(kind, phase, lampMode) {
  const out = phase === 'out';
  const base = {
    transition: 'opacity 140ms linear, transform 160ms linear, clip-path 200ms linear, filter 140ms linear',
    transformOrigin: 'top left',
  };
  // The wrapper height — we let it auto-collapse via max-height when 'out'
  // We rely on the inner being measured via flex; max:none when 'in'.
  const wrap = { maxHeight: out ? 0 : '1400px' };
  if (kind === 'unfold') {
    return {
      wrap,
      inner: { ...base, opacity: out ? 0 : 1, transform: `translateY(${out ? -6 : 0}px)` },
    };
  }
  if (kind === 'fold') {
    return {
      wrap,
      inner: {
        ...base,
        opacity: out ? 0 : 1,
        transform: `perspective(900px) rotateX(${out ? -78 : 0}deg)`,
        transformOrigin: 'top center',
        transition: 'opacity 160ms linear, transform 200ms cubic-bezier(.2,.6,.2,1)',
      },
    };
  }
  if (kind === 'fade') {
    return {
      wrap,
      inner: { ...base, opacity: out ? 0 : 1, transform: `translateY(${out ? 8 : 0}px)` },
    };
  }
  if (kind === 'marginalia') {
    return {
      wrap,
      inner: {
        ...base,
        opacity: out ? 0 : 1,
        transform: `translateX(${out ? -22 : 0}px)`,
        transition: 'opacity 140ms linear, transform 200ms cubic-bezier(.2,.6,.25,1)',
      },
    };
  }
  if (kind === 'bleed') {
    // Ink bleed wipe: clip-path inset shrinks/grows.
    return {
      wrap,
      inner: {
        ...base,
        opacity: out ? 0 : 1,
        clipPath: out ? 'inset(0 0 100% 0)' : 'inset(0 0 0% 0)',
        filter: out ? 'blur(2px)' : 'blur(0)',
        transition: 'opacity 160ms linear, clip-path 240ms cubic-bezier(.4,0,.2,1), filter 200ms linear',
      },
    };
  }
  return { wrap, inner: base };
}

// ─────────────────────────────────────────────────────────────────────────
// Summary card — the unfolded thing
// ─────────────────────────────────────────────────────────────────────────

function SummaryCard({ chapter, lampMode, onRead }) {
  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.55)' : 'var(--ink-mute)';
  const accent = lampMode ? '#E89260' : 'var(--flame)';
  const surface = lampMode ? '#1B1714' : 'var(--surface)';
  const border = lampMode ? 'rgba(246,241,229,0.22)' : 'var(--ink)';

  // Pick a varying secondary accent based on chapter number, for visual rhythm
  const palette = ['var(--mustard)', 'var(--mauve)', 'var(--sage)', 'var(--slate)', 'var(--peach)'];
  const swatch = palette[parseInt(chapter.n) % palette.length];

  return (
    <div style={{
      margin: '6px 14px 18px',
      background: surface,
      border: `1.5px solid ${border}`,
      boxShadow: `4px 4px 0 ${lampMode ? 'rgba(217,107,39,0.35)' : 'var(--flame)'}`,
      position: 'relative',
    }}>
      {/* card top: AI chip + swatch */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 8,
        padding: '10px 12px',
        borderBottom: `1px solid ${border}`,
      }}>
        <span style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          background: accent, color: 'var(--paper)',
          padding: '3px 8px 2px',
          fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.2em',
          textTransform: 'uppercase', whiteSpace: 'nowrap', flexShrink: 0,
          border: `1px solid ${lampMode ? 'rgba(0,0,0,0.3)' : 'var(--ink)'}`,
        }}>
          <span style={{ width: 5, height: 5, borderRadius: '50%', background: 'var(--paper)' }} />
          Side-note
        </span>
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 11, letterSpacing: '.18em',
          color: fg3, textTransform: 'uppercase', whiteSpace: 'nowrap',
          overflow: 'hidden', textOverflow: 'ellipsis', minWidth: 0, flex: 1,
        }}>·  generated</span>
        <button onClick={onRead} style={{
          appearance: 'none', cursor: 'pointer',
          background: accent, color: 'var(--paper)',
          border: `1.5px solid ${lampMode ? 'rgba(0,0,0,0.4)' : 'var(--ink)'}`,
          padding: '7px 10px 6px',
          fontFamily: 'var(--font-sans)', fontWeight: 700,
          fontSize: 11, letterSpacing: '.08em', textTransform: 'uppercase',
          boxShadow: `2px 2px 0 ${lampMode ? 'rgba(246,241,229,0.25)' : 'var(--ink)'}`,
          display: 'inline-flex', alignItems: 'center', gap: 6,
          whiteSpace: 'nowrap', flexShrink: 0,
        }}>
          Read
          <svg width="12" height="9" viewBox="0 0 12 9" fill="none" aria-hidden>
            <path d="M1 4.5h10M7.5 1L11 4.5L7.5 8" stroke="currentColor" strokeWidth="1.6" strokeLinecap="square"/>
          </svg>
        </button>
      </div>

      {/* card body */}
      <div style={{ padding: '14px 16px 16px' }}>
        {/* chapter promise — italic serif */}
        <p style={{
          fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontWeight: 500,
          fontSize: 18, lineHeight: 1.32, color: fg,
          margin: '0 0 14px', textWrap: 'pretty',
        }}>{chapter.promise}</p>

        {/* divider */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8, margin: '0 0 12px',
        }}>
          <span style={{ flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.22)' : 'var(--ink)', minWidth: 8 }} />
          <Chrome style={{ color: fg3, fontSize: 10, flexShrink: 0 }}>summary</Chrome>
          <span style={{ flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.22)' : 'var(--ink)', minWidth: 8 }} />
        </div>

        {/* short explanation */}
        <p style={{
          fontFamily: 'var(--font-serif)', fontWeight: 400,
          fontSize: 14.5, lineHeight: 1.55, color: fg2,
          margin: '0 0 16px', textWrap: 'pretty',
        }}>{chapter.summary}</p>

        {/* takeaways */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 8, margin: '0 0 10px',
        }}>
          <span style={{ flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.22)' : 'var(--ink)', minWidth: 8 }} />
          <Chrome style={{ color: fg3, fontSize: 10, flexShrink: 0 }}>key takeaways</Chrome>
          <span style={{ flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.22)' : 'var(--ink)', minWidth: 8 }} />
        </div>
        <ol style={{
          margin: 0, padding: 0, listStyle: 'none',
          display: 'flex', flexDirection: 'column', gap: 8,
        }}>
          {chapter.takeaways.map((t, i) => (
            <li key={i} style={{
              display: 'grid', gridTemplateColumns: '22px 1fr', gap: 8,
              alignItems: 'baseline',
            }}>
              <span style={{
                fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '.1em',
                color: accent, textAlign: 'right',
              }}>{`0${i + 1}`}</span>
              <span style={{
                fontFamily: 'var(--font-serif)', fontWeight: 400,
                fontSize: 14, lineHeight: 1.42, color: fg2,
                textWrap: 'pretty',
              }}>{t}</span>
            </li>
          ))}
        </ol>

        {/* footer row: read time + CTA */}
        <div style={{
          display: 'flex', alignItems: 'center', gap: 10,
          marginTop: 18, paddingTop: 14,
          borderTop: `1px dashed ${lampMode ? 'rgba(246,241,229,0.25)' : 'var(--ink)'}`,
        }}>
          <Chrome style={{ color: fg3, fontSize: 11, flexShrink: 0 }}>{`${chapter.readMin} min · p.${chapter.page}`}</Chrome>
          <span style={{ flex: 1, height: 1, background: lampMode ? 'rgba(246,241,229,0.18)' : 'var(--ink)', opacity: 0.28 }} />
          <Chrome style={{ color: accent, fontSize: 10, flexShrink: 0 }}>read from top</Chrome>
        </div>
      </div>
    </div>
  );
}

// ─────────────────────────────────────────────────────────────────────────
// Contents drawer — sidebar w/ inline summary unfold
// ─────────────────────────────────────────────────────────────────────────

function ContentsDrawer({ book, isOpen, onClose, expandedN, setExpandedN,
                         currentN, transition, lampMode, onReadChapter }) {

  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)';
  const bg = lampMode ? '#15110F' : 'var(--paper)';
  const border = lampMode ? 'rgba(246,241,229,0.18)' : 'var(--ink)';

  // Drawer slides in from left.
  return (
    <>
      {/* scrim */}
      <div
        onClick={onClose}
        style={{
          position: 'absolute', inset: 0, zIndex: 40,
          background: 'rgba(31,26,24,0.32)',
          opacity: isOpen ? 1 : 0,
          pointerEvents: isOpen ? 'auto' : 'none',
          transition: 'opacity 140ms linear',
          backdropFilter: 'blur(1px)',
          WebkitBackdropFilter: 'blur(1px)',
        }}
      />
      <aside style={{
        position: 'absolute', top: 0, bottom: 0, left: 0, zIndex: 45,
        width: '88%', maxWidth: 360,
        background: bg,
        borderRight: `1.5px solid ${border}`,
        boxShadow: isOpen ? '6px 0 0 rgba(31,26,24,0.06)' : 'none',
        transform: `translateX(${isOpen ? '0' : '-102%'})`,
        transition: 'transform 220ms cubic-bezier(.25,.6,.2,1)',
        display: 'flex', flexDirection: 'column',
        overflow: 'hidden',
      }}>

        {/* drawer chrome header */}
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '12px 14px 10px',
          borderBottom: `1.5px solid ${border}`,
          background: lampMode ? '#0F0C0B' : 'var(--surface)',
        }}>
          <Chrome style={{ color: fg }}>Contents</Chrome>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
            <Chrome style={{ color: fg3, fontSize: 11 }}>{`${flattenChapters(book).length} lessons`}</Chrome>
            <button onClick={onClose} aria-label="Close contents" style={{
              appearance: 'none', background: 'transparent',
              border: `1px solid ${border}`, color: fg, cursor: 'pointer',
              width: 26, height: 26, display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontFamily: 'var(--font-mono)', fontSize: 13,
            }}>×</button>
          </div>
        </div>

        {/* book masthead */}
        <div style={{
          padding: '16px 14px 12px',
          borderBottom: `1px solid ${border}`,
          background: lampMode ? '#0F0C0B' : 'var(--surface)',
        }}>
          <Chrome style={{ color: accent, fontSize: 10 }}>field guide · 2025</Chrome>
          <h2 style={{
            fontFamily: 'var(--font-serif)', fontWeight: 600, fontStyle: 'italic',
            fontSize: 24, lineHeight: 1.05, letterSpacing: '-0.01em',
            color: fg, margin: '4px 0 4px', textWrap: 'balance',
          }}>{book.title}</h2>
          <p style={{
            fontFamily: 'var(--font-serif)', fontWeight: 400, fontStyle: 'italic',
            fontSize: 12.5, lineHeight: 1.32, color: fg2,
            margin: '0 0 8px',
          }}>{book.subtitle}</p>
          <Chrome style={{ color: fg3, fontSize: 10 }}>
            {`${book.author}  ·  ${book.publisher}`}
          </Chrome>
        </div>

        {/* TOC scroll area */}
        <div style={{
          flex: 1, overflowY: 'auto', overflowX: 'hidden',
          padding: '6px 0 60px',
        }}>
          {book.parts.map((part) => (
            <PartSection
              key={part.part}
              part={part}
              currentN={currentN}
              expandedN={expandedN}
              setExpandedN={setExpandedN}
              transition={transition}
              lampMode={lampMode}
              onReadChapter={onReadChapter}
            />
          ))}

          {/* end-of-book chip */}
          <div style={{
            display: 'flex', alignItems: 'center', gap: 8,
            padding: '14px 16px 0', marginTop: 6,
          }}>
            <span style={{ flex: 1, height: 1, background: border, opacity: 0.55 }} />
            <Chrome style={{ color: fg3, fontSize: 10 }}>· end ·</Chrome>
            <span style={{ flex: 1, height: 1, background: border, opacity: 0.55 }} />
          </div>
        </div>
      </aside>
    </>
  );
}

function PartSection({ part, currentN, expandedN, setExpandedN, transition, lampMode, onReadChapter }) {
  const fg3 = lampMode ? 'rgba(246,241,229,0.5)' : 'var(--ink-mute)';
  const border = lampMode ? 'rgba(246,241,229,0.18)' : 'var(--ink)';
  const fg = lampMode ? 'var(--paper)' : 'var(--ink)';

  return (
    <section style={{ padding: '14px 0 6px' }}>
      {/* part header */}
      <div style={{
        display: 'flex', alignItems: 'baseline', gap: 10,
        padding: '4px 16px 8px',
      }}>
        <Chrome style={{ color: fg, fontSize: 11, flexShrink: 0 }}>{`Part ${part.part}`}</Chrome>
        <span style={{ flex: 1, height: 1, background: border, opacity: 0.4, minWidth: 8 }} />
        <span style={{
          fontFamily: 'var(--font-serif)', fontStyle: 'italic', fontWeight: 500,
          fontSize: 14, color: fg3, flexShrink: 0, whiteSpace: 'nowrap',
        }}>{part.title}</span>
      </div>

      {/* chapter rows */}
      <ol style={{ margin: 0, padding: 0, listStyle: 'none' }}>
        {part.chapters.map((ch) => (
          <ChapterRow
            key={ch.n}
            chapter={ch}
            isExpanded={ch.n === expandedN}
            isCurrent={ch.n === currentN}
            onClick={() => setExpandedN(ch.n === expandedN ? null : ch.n)}
            transition={transition}
            lampMode={lampMode}
            onRead={() => onReadChapter(ch.n)}
          />
        ))}
      </ol>
    </section>
  );
}

function ChapterRow({ chapter, isExpanded, isCurrent, onClick, transition, lampMode, onRead }) {
  const fg = lampMode ? 'var(--paper)' : 'var(--ink)';
  const fg3 = lampMode ? 'rgba(246,241,229,0.5)' : 'var(--ink-mute)';
  const accent = lampMode ? '#E89260' : 'var(--flame)';
  const border = lampMode ? 'rgba(246,241,229,0.15)' : 'var(--ink)';

  return (
    <li>
      <button onClick={onClick} style={{
        appearance: 'none', cursor: 'pointer',
        width: '100%', background: 'transparent',
        border: 'none',
        borderTop: `1px solid ${border}`,
        padding: '12px 16px 12px',
        display: 'grid',
        gridTemplateColumns: '28px 1fr auto',
        gap: 10, alignItems: 'baseline',
        textAlign: 'left',
        transition: 'background 100ms linear',
        background: isExpanded
          ? (lampMode ? 'rgba(232,146,96,0.08)' : 'rgba(217,107,39,0.06)')
          : 'transparent',
      }}>
        <span style={{
          fontFamily: 'var(--font-mono)', fontSize: 14, letterSpacing: '.06em',
          color: isExpanded ? accent : fg3,
        }}>{chapter.n}</span>

        <span style={{
          fontFamily: 'var(--font-serif)', fontWeight: isExpanded ? 600 : 500,
          fontStyle: isExpanded ? 'italic' : 'normal',
          fontSize: 15.5, lineHeight: 1.25, color: fg,
          textWrap: 'balance',
          display: 'flex', flexDirection: 'column', gap: 4,
        }}>
          {chapter.title}
          {isCurrent && !isExpanded && (
            <span style={{
              fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.22em',
              color: accent, textTransform: 'uppercase', fontStyle: 'normal',
              fontWeight: 400, whiteSpace: 'nowrap',
            }}>· reading now</span>
          )}
        </span>

        <span style={{
          display: 'flex', flexDirection: 'column', alignItems: 'flex-end', gap: 2,
          flexShrink: 0,
        }}>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 12, letterSpacing: '.1em',
            color: fg3, whiteSpace: 'nowrap',
          }}>{`p. ${chapter.page}`}</span>
          <span style={{
            fontFamily: 'var(--font-mono)', fontSize: 10, letterSpacing: '.18em',
            color: fg3, textTransform: 'uppercase', whiteSpace: 'nowrap',
          }}>{`${chapter.readMin}m`}</span>
        </span>
      </button>

      {/* inline summary reveal */}
      <MagicReveal
        chapterKey={isExpanded ? chapter.n : `__empty_${chapter.n}`}
        transition={transition}
        lampMode={lampMode}
      >
        {isExpanded ? (
          <SummaryCard chapter={chapter} lampMode={lampMode} onRead={onRead} />
        ) : <div style={{ height: 0 }} />}
      </MagicReveal>
    </li>
  );
}

Object.assign(window, {
  ContentsDrawer, MagicReveal, SummaryCard, PartSection, ChapterRow,
});
