// cache-bust: 1779472262873-1343ae
// =========================================================
// ep-route.jsx -- hash router for episode guided sessions.
// /build/#ep/X.Y -> mounts <EpisodeGuide /> full-viewport (any episode
//                   with beats in window.BL_SCRIPTS).
// Pro-only ep + not signed-in or no access -> paywall screen.
// No script data at all -> "Recording in progress" placeholder.
// Escape closes.
// =========================================================

(function () {
  const ROOT_ID = 'bl-ep-root';
  const HASH_PREFIX = '#ep/';

  let _root = null;

  // Look up a single episode entry in BL_DATA.modules[].episodes[]
  function findEpisode(id) {
    const data = window.BL_DATA;
    if (!data || !Array.isArray(data.modules)) return null;
    for (const m of data.modules) {
      for (const e of (m.episodes || [])) {
        if (e.n === id) return { episode: e, module: m };
      }
    }
    return null;
  }

  function hasBeats(id) {
    const s = window.BL_SCRIPTS || {};
    const ep = s[id];
    return !!(ep && Array.isArray(ep.beats) && ep.beats.length > 0);
  }

  function ComingSoon({ id }) {
    const close = () => { window.location.hash = ''; };
    return (
      <div style={{
        position: 'fixed', inset: 0,
        background: '#16110d', color: '#f4eee3',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        zIndex: 8000,
        fontFamily: 'Geist, system-ui, sans-serif',
      }}>
        <div style={{ textAlign: 'center', maxWidth: 480, padding: 20 }}>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: '#f3c3ab', letterSpacing: '.1em', marginBottom: 12 }}>
            EP {id}
          </div>
          <div style={{ fontSize: 28, fontWeight: 700, marginBottom: 14 }}>
            Recording in progress.
          </div>
          <p style={{ fontSize: 15, color: '#c9c0b1', lineHeight: 1.6, margin: '0 0 28px' }}>
            This episode is being written right now. Subscribe and you'll get
            access the moment it ships.
          </p>
          <button onClick={close} style={{
            background: '#d96846', color: '#fff', border: 'none',
            padding: '11px 22px', borderRadius: 6, cursor: 'pointer',
            fontSize: 14, fontWeight: 600,
          }}>
            back to landing
          </button>
        </div>
      </div>
    );
  }

  function Paywall({ id, episode, isLoggedIn }) {
    const close = () => { window.location.hash = ''; };
    const goToPricing = () => { window.location.hash = ''; setTimeout(() => {
      const t = document.getElementById('pricing'); if (t) t.scrollIntoView({behavior:'smooth'});
    }, 50); };
    const signIn = () => { if (window.BL_AUTH && window.BL_AUTH.openLogin) window.BL_AUTH.openLogin(); };
    return (
      <div style={{
        position: 'fixed', inset: 0,
        background: '#16110d', color: '#f4eee3',
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        zIndex: 8000,
        fontFamily: 'Geist, system-ui, sans-serif',
      }}>
        <div style={{ textAlign: 'center', maxWidth: 520, padding: 24 }}>
          <div style={{ fontFamily: 'JetBrains Mono, monospace', fontSize: 11, color: '#f3c3ab', letterSpacing: '.1em', marginBottom: 12 }}>
            EP {id} . PRO
          </div>
          <div style={{ fontSize: 30, fontWeight: 700, marginBottom: 14, lineHeight: 1.15 }}>
            {episode ? episode.title : 'Pro episode'}
          </div>
          <p style={{ fontSize: 15, color: '#c9c0b1', lineHeight: 1.6, margin: '0 0 28px' }}>
            This one's behind the paywall. Get the lab for $149/yr and unlock
            every episode -- including this one and everything that ships next.
          </p>
          <div style={{ display:'flex', gap:10, justifyContent:'center', flexWrap:'wrap' }}>
            <button onClick={goToPricing} style={{
              background: '#d96846', color: '#fff', border: 'none',
              padding: '11px 22px', borderRadius: 6, cursor: 'pointer',
              fontSize: 14, fontWeight: 600,
            }}>
              see pricing
            </button>
            {!isLoggedIn && (
              <button onClick={signIn} style={{
                background: 'transparent', color: '#f4eee3',
                border: '1px solid #2e261f',
                padding: '11px 22px', borderRadius: 6, cursor: 'pointer',
                fontSize: 14, fontWeight: 500,
              }}>
                already a member? sign in
              </button>
            )}
            <button onClick={close} style={{
              background: 'transparent', color: '#c9c0b1',
              border: 'none',
              padding: '11px 18px', borderRadius: 6, cursor: 'pointer',
              fontSize: 13,
            }}>
              back to landing
            </button>
          </div>
        </div>
      </div>
    );
  }

  function mount(id) {
    if (_root) unmount();
    let host = document.getElementById(ROOT_ID);
    if (!host) {
      host = document.createElement('div');
      host.id = ROOT_ID;
      document.body.appendChild(host);
    }
    _root = ReactDOM.createRoot(host);

    const found = findEpisode(id);
    const episode = found ? found.episode : null;
    const beatsExist = hasBeats(id);

    // No data at all -> coming soon
    if (!episode && !beatsExist) {
      _root.render(<ComingSoon id={id} />);
      return;
    }

    // Pro-only access check
    const auth = window.BL_AUTH;
    const isLoggedIn = !!(auth && auth.isLoggedIn && auth.isLoggedIn());
    const hasAccess = !!(auth && auth.hasBuildLabAccess && auth.hasBuildLabAccess());
    const isFree = episode ? !!episode.free : false;

    if (!isFree && !hasAccess) {
      _root.render(<Paywall id={id} episode={episode} isLoggedIn={isLoggedIn} />);
      return;
    }

    // Allowed -> stash id and mount the generic guide
    window.BL_EP_ID = id;
    if (typeof window.EpisodeGuide === 'function') {
      const EG = window.EpisodeGuide;
      _root.render(
        <div style={{
          position: 'fixed', inset: 0,
          zIndex: 8500, overflow: 'auto',
          background: '#f5f1ea',
        }}>
          <EG />
        </div>
      );
    } else {
      _root.render(<ComingSoon id={id} />);
    }
  }

  function unmount() {
    if (!_root) return;
    _root.unmount();
    _root = null;
    const host = document.getElementById(ROOT_ID);
    if (host) host.remove();
    window.BL_EP_ID = null;
  }

  function syncFromHash() {
    const h = window.location.hash;
    if (h.startsWith(HASH_PREFIX)) {
      const id = h.slice(HASH_PREFIX.length);
      mount(id);
    } else {
      unmount();
    }
  }

  window.addEventListener('keydown', (e) => {
    if (e.key === 'Escape' && window.location.hash.startsWith(HASH_PREFIX)) {
      window.location.hash = '';
    }
  });
  window.addEventListener('hashchange', syncFromHash);
  setTimeout(syncFromHash, 80);
})();
