// ─── API hooks ────────────────────────────────────────────────────────────────

function useMemos(token) {
  const [memos,   setMemos]   = React.useState([]);
  const [loading, setLoading] = React.useState(true);
  const [error,   setError]   = React.useState(null);
  React.useEffect(() => {
    let ignore = false;
    const ctrl = new AbortController();
    const headers = token ? { Authorization: 'Bearer ' + token } : {};
    fetch('/api/memos', { headers, signal: ctrl.signal })
      .then(r => r.json())
      .then(data => { if (!ignore) setMemos(Array.isArray(data) ? data : []); })
      .catch(e => { if (!ignore) setError(e.message); })
      .finally(() => { if (!ignore) setLoading(false); });
    return () => { ignore = true; ctrl.abort(); };
  }, [token]);
  return { memos, loading, error };
}

function useMemoItem(slug, token) {
  const [memo,    setMemo]    = React.useState(null);
  const [loading, setLoading] = React.useState(true);
  const [error,   setError]   = React.useState(null);
  React.useEffect(() => {
    if (!slug) return;
    let ignore = false;
    const ctrl = new AbortController();
    const headers = token ? { Authorization: 'Bearer ' + token } : {};
    fetch('/api/memos/' + slug, { headers, signal: ctrl.signal })
      .then(r => r.ok ? r.json() : null)
      .then(data => { if (!ignore) setMemo(data); })
      .catch(e => { if (!ignore) setError(e.message); })
      .finally(() => { if (!ignore) setLoading(false); });
    return () => { ignore = true; ctrl.abort(); };
  }, [slug, token]);
  return { memo, loading, error };
}

// ─── Render helpers ───────────────────────────────────────────────────────────

function renderBody(blocks, wide) {
  return blocks.map((b, i) => {
    if (b.t === 'h') return (
      <div key={i} style={{ fontFamily: TH.serif, fontSize: wide ? 22 : 18, fontWeight: 500, letterSpacing: -0.3, color: TH.ink, marginTop: 36, marginBottom: 10, borderBottom: `1px solid ${TH.rule}`, paddingBottom: 8 }}>
        {b.s}
      </div>
    );
    if (b.t === 'callout') return (
      <div key={i} style={{ borderLeft: `3px solid ${TH.accent}`, paddingLeft: 18, margin: '20px 0', color: TH.inkSoft, fontFamily: TH.serif, fontSize: wide ? 16 : 14, lineHeight: 1.65, fontStyle: 'italic' }}>
        {b.s}
      </div>
    );
    if (b.t === 'bullets') return (
      <ul key={i} style={{ margin: '16px 0 16px 0', paddingLeft: 20, color: TH.inkSoft, fontFamily: TH.serif, fontSize: wide ? 16 : 14, lineHeight: 1.75 }}>
        {b.s.map((item, j) => (
          <li key={j} style={{ marginBottom: 10 }}>{item}</li>
        ))}
      </ul>
    );
    // default: paragraph
    return (
      <p key={i} style={{ fontFamily: TH.serif, fontSize: wide ? 17 : 15, lineHeight: 1.8, color: TH.inkSoft, margin: '16px 0' }}>
        {b.s}
      </p>
    );
  });
}

// ─── MemoReader ───────────────────────────────────────────────────────────────

function MemoReader({ id, go, user, plan, token }) {
  const wide = useWide();
  const { memo, loading } = useMemoItem(id, token);
  if (loading) return <div style={{ background: TH.bg, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: TH.mono, fontSize: 12, color: TH.muted }}>Loading…</div>;

  if (!memo) return (
    <div style={{ background: TH.bg, color: TH.ink, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: TH.mono, fontSize: 13, color: TH.muted }}>
      Memo not found. <span onClick={() => go('memos')} style={{ color: TH.accent, marginLeft: 8, cursor: 'pointer' }}>← Back</span>
    </div>
  );

  const locked = !memo.free && !plan && user?.role !== 'admin';
  const cutoffBlock = 4; // show first N blocks before paywall

  return (
    <div style={{ background: TH.bg, color: TH.ink, fontFamily: TH.serif, minHeight: '100vh' }}>
      {/* Top nav */}
      <div style={{ borderBottom: `1px solid ${TH.rule}`, padding: wide ? '14px 32px' : '12px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
        <span onClick={() => go(plan ? 'memos' : 'memos')} style={{ fontFamily: TH.mono, fontSize: 11, color: TH.accent, letterSpacing: 1.5, cursor: 'pointer' }}>
          ← MEMOS
        </span>
        <span style={{ fontFamily: TH.mono, fontSize: 11, color: TH.muted, letterSpacing: 1.5 }}>
          MEMO №{memo.id}
        </span>
      </div>

      {/* Article */}
      <div style={{ maxWidth: 740, margin: '0 auto', padding: wide ? '52px 32px 80px' : '32px 20px 64px' }}>
        {/* Header */}
        <div style={{ fontFamily: TH.mono, fontSize: 10, color: TH.accent, letterSpacing: 2, marginBottom: 14 }}>
          {memo.category} · {memo.date}
        </div>
        <h1 style={{ fontFamily: TH.serif, fontSize: wide ? 44 : 30, fontWeight: 400, lineHeight: 1.1, letterSpacing: -1.2, margin: '0 0 20px', color: TH.ink }}>
          {memo.title}
        </h1>
        <div style={{ fontFamily: TH.serif, fontSize: wide ? 19 : 16, color: TH.inkSoft, lineHeight: 1.55, marginBottom: 28, fontStyle: 'italic' }}>
          {memo.summary}
        </div>
        <div style={{ display: 'flex', gap: 16, fontFamily: TH.mono, fontSize: 10, color: TH.muted, letterSpacing: 1.5, marginBottom: 36, paddingBottom: 24, borderBottom: `1px solid ${TH.rule}` }}>
          <span>{memo.readMin} MIN READ</span>
          {memo.free && <span style={{ color: TH.green }}>· FREE</span>}
          {!memo.free && !plan && <span>· MEMBERS ONLY</span>}
        </div>

        {/* Body */}
        {locked ? (
          <div style={{ position: 'relative' }}>
            {/* Show partial content */}
            <div style={{ overflow: 'hidden', maxHeight: 380, pointerEvents: 'none' }}>
              {renderBody(memo.body.slice(0, cutoffBlock), wide)}
            </div>
            {/* Fade overlay */}
            <div style={{ position: 'absolute', bottom: 0, left: 0, right: 0, height: 200, background: `linear-gradient(to bottom, transparent, ${TH.bg})` }}/>
            {/* CTA */}
            <div style={{ marginTop: 32, padding: wide ? 36 : 24, border: `1px solid ${TH.accent}`, background: TH.panel, textAlign: 'center' }}>
              <div style={{ fontFamily: TH.mono, fontSize: 10, color: TH.accent, letterSpacing: 2, marginBottom: 12 }}>⚿ MEMBERS ONLY</div>
              <div style={{ fontFamily: TH.serif, fontSize: wide ? 24 : 20, marginBottom: 12, letterSpacing: -0.4 }}>
                Continue reading Memo №{memo.id}
              </div>
              <div style={{ fontFamily: TH.serif, fontSize: 15, color: TH.inkSoft, lineHeight: 1.55, marginBottom: 24, maxWidth: 480, margin: '0 auto 24px' }}>
                This memo is part of the Walkforward membership. Join to read the full archive — {memo.readMin - 2} more minutes of this piece, plus 141 back issues.
              </div>
              <div style={{ display: 'flex', gap: 10, justifyContent: 'center', flexWrap: 'wrap' }}>
                <Btn primary onClick={() => go('pricing')}>See membership →</Btn>
                {!user && <Btn ghost onClick={() => go('signup')}>Free account</Btn>}
              </div>
            </div>
          </div>
        ) : (
          renderBody(memo.body, wide)
        )}
      </div>
      <Footer/>
    </div>
  );
}

// ─── MemoList ─────────────────────────────────────────────────────────────────

function MemoList({ go, user, plan, token }) {
  const wide = useWide();
  const { memos, loading } = useMemos(token);
  if (loading) return <div style={{ background: TH.bg, minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', fontFamily: TH.mono, fontSize: 12, color: TH.muted }}>Loading…</div>;
  return (
    <div style={{ background: TH.bg, color: TH.ink, fontFamily: TH.serif, minHeight: '100vh' }}>
      <div style={{ maxWidth: 900, margin: '0 auto', padding: wide ? '48px 32px' : '28px 20px' }}>
        <div style={{ fontFamily: TH.mono, fontSize: 11, color: TH.accent, letterSpacing: 2, marginBottom: 10 }}>§ MEMO ARCHIVE</div>
        <div style={{ fontSize: wide ? 42 : 28, letterSpacing: -1.2, marginBottom: 10 }}>
          142 memos. <span style={{ fontStyle: 'italic', color: TH.accent }}>No filler.</span>
        </div>
        <div style={{ fontFamily: TH.serif, fontSize: 16, color: TH.inkSoft, lineHeight: 1.55, marginBottom: 40, maxWidth: 600 }}>
          Every Sunday, a short research dispatch on regime, funding, and cross-asset signals.
          Written to be read, not sold.
        </div>

        <div style={{ display: 'flex', flexDirection: 'column', gap: 0, border: `1px solid ${TH.rule}`, background: TH.panel }}>
          {memos.map((m, i) => (
            <div
              key={m.id}
              onClick={() => go(`memo/${m.slug}`)}
              style={{
                padding: wide ? '28px 28px' : '20px 18px',
                borderBottom: i < memos.length - 1 ? `1px solid ${TH.rule}` : 'none',
                cursor: 'pointer',
                transition: 'background 0.1s',
              }}
              onMouseEnter={e => e.currentTarget.style.background = TH.panelHi}
              onMouseLeave={e => e.currentTarget.style.background = 'transparent'}
            >
              <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 12 }}>
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', gap: 12, alignItems: 'center', marginBottom: 8, flexWrap: 'wrap' }}>
                    <span style={{ fontFamily: TH.mono, fontSize: 10, color: TH.accent, letterSpacing: 1.5 }}>MEMO №{m.id}</span>
                    <span style={{ fontFamily: TH.mono, fontSize: 10, color: TH.muted, letterSpacing: 1 }}>{m.category}</span>
                    {m.free && <span style={{ fontFamily: TH.mono, fontSize: 10, color: TH.green, letterSpacing: 1 }}>FREE</span>}
                  </div>
                  <div style={{ fontFamily: TH.serif, fontSize: wide ? 22 : 18, letterSpacing: -0.4, lineHeight: 1.2, marginBottom: 10, color: TH.ink }}>
                    {m.title}
                  </div>
                  <div style={{ fontFamily: TH.serif, fontSize: 14, color: TH.inkSoft, lineHeight: 1.55 }}>
                    {m.summary}
                  </div>
                </div>
                <div style={{ fontFamily: TH.mono, fontSize: 10, color: TH.muted, letterSpacing: 1, whiteSpace: 'nowrap', textAlign: 'right', marginTop: 2 }}>
                  <div>{m.date.toUpperCase()}</div>
                  <div style={{ marginTop: 4 }}>{m.readMin} MIN</div>
                </div>
              </div>
            </div>
          ))}
        </div>

        {!plan && (
          <div style={{ marginTop: 24, padding: wide ? 32 : 20, border: `1px solid ${TH.rule}`, background: TH.panel, textAlign: 'center' }}>
            <div style={{ fontFamily: TH.serif, fontSize: wide ? 20 : 17, marginBottom: 10 }}>139 more memos in the archive</div>
            <div style={{ fontFamily: TH.serif, fontSize: 14, color: TH.inkSoft, marginBottom: 20 }}>Members get the full archive dating back to 2021, plus a new memo every Sunday.</div>
            <Btn primary onClick={() => go('pricing')}>See membership →</Btn>
          </div>
        )}
      </div>
      <Footer/>
    </div>
  );
}

Object.assign(window, { MemoList, MemoReader });
