/* global React */
const { useState, useEffect, useMemo, useRef } = React;

const fmtDate = (s) => {
  const d = new Date(s + 'T00:00:00');
  return d.toLocaleDateString('en-GB', { day: '2-digit', month: 'short', year: 'numeric' });
};
const fmtDateLong = (s) => {
  const d = new Date(s + 'T00:00:00');
  return d.toLocaleDateString('en-GB', { weekday: 'long', day: 'numeric', month: 'long', year: 'numeric' });
};
const fmtN = (n) => n.toLocaleString('en-US');

/* ---------- Masthead / nav ---------- */
function Masthead({ route, nav }) {
  const tabs = [
    ['home',     'Home'],
    ['mps',      'MPs'],
    ['topics',   'Topics'],
    ['sittings', 'Sittings'],
    ['heatmap',  'Pulse'],
    ['search',   'Search'],
  ];
  return (
    <header className="masthead">
      <div className="shell">
        <div className="masthead-inner">
          <a href="#" onClick={(e) => { e.preventDefault(); nav('home'); }} className="wordmark serif">
            Politick<span className="dot" />
            <span className="sub">Sri Lankan Parliament · Hansard Record</span>
          </a>
          <nav className="nav">
            {tabs.map(([k, label]) => (
              <a
                key={k}
                href="#"
                onClick={(e) => { e.preventDefault(); nav(k); }}
                className={route.page === k ? 'active' : ''}
              >{label}</a>
            ))}
          </nav>
          <div className="mast-tools">
            <span className="live">Parliament sitting 20 Mar</span>
          </div>
        </div>
      </div>
    </header>
  );
}

/* ---------- Footer ---------- */
function Colophon() {
  return (
    <footer style={{ borderTop: '2px solid var(--ink)', marginTop: 80, padding: '28px 0 40px', fontSize: 12, color: 'var(--ink-3)' }}>
      <div className="shell">
        <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 24 }}>
          <div>
            <div className="kicker" style={{ marginBottom: 8 }}>Politick</div>
            A public-interest record of the 10th Parliament of Sri Lanka.
            Built on the official Hansard, searchable and centred on your representatives.
          </div>
          <div>
            <div className="kicker" style={{ marginBottom: 8 }}>Data</div>
            Hansard transcripts are sourced from parliament.lk and updated within 48 hours of each sitting.
            Summaries and topic tags are AI-generated and flagged as such.
          </div>
          <div>
            <div className="kicker" style={{ marginBottom: 8 }}>Colophon</div>
            Set in Source Serif 4 and Inter Tight. Text copyright to Parliament; layout and commentary by Politick, CC&nbsp;BY&nbsp;4.0.
          </div>
        </div>
        <div style={{ borderTop: '1px solid var(--rule)', marginTop: 24, paddingTop: 12, display: 'flex', justifyContent: 'space-between', fontFamily: 'var(--mono)', fontSize: 10 }}>
          <span>ISSN 0000-0000 (digital)</span>
          <span>v0.3.1 · build 2026.04</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------- Topic tag ---------- */
function TopicTag({ topic, onClick }) {
  return (
    <a className="tag-topic" href="#" onClick={(e) => { e.preventDefault(); onClick && onClick(topic); }}>
      {topic.short || topic.name}
    </a>
  );
}

function PartyChip({ party }) {
  if (!party) return null;
  return (
    <span className="sans" style={{ fontSize: 11, color: 'var(--ink-3)', display: 'inline-flex', alignItems: 'center' }}>
      <span className="party-dot" style={{ background: party.color }} />
      {party.abbr}
    </span>
  );
}

/* ---------- Speech item ---------- */
function SpeechItem({ speech, showMp = true, showDate = false, nav }) {
  return (
    <article className="card">
      <div style={{ display: 'grid', gridTemplateColumns: '160px 1fr', gap: 20 }}>
        <div style={{ fontSize: 12, color: 'var(--ink-3)', paddingTop: 2 }}>
          {showMp && speech.mp && (
            <>
              <a
                href="#"
                onClick={(e) => { e.preventDefault(); nav('mp', { id: speech.mp.id }); }}
                className="serif"
                style={{ fontSize: 16, fontWeight: 600, color: 'var(--ink)', display: 'block', lineHeight: 1.2, letterSpacing: '-0.01em' }}
              >
                {speech.mp.name}
              </a>
              <div style={{ marginTop: 2, display: 'flex', gap: 6, alignItems: 'center' }}>
                <PartyChip party={speech.mp.party} />
                <span className="hair">·</span>
                <span>{speech.mp.district}</span>
              </div>
            </>
          )}
          {showDate && (
            <div className="mono" style={{ marginTop: 6, fontSize: 11, color: 'var(--ink-4)' }}>
              {fmtDate(speech.sittingDate)} · #{speech.speechOrder}
            </div>
          )}
        </div>
        <div>
          <div style={{ fontSize: 11, color: 'var(--ink-3)', textTransform: 'uppercase', letterSpacing: '0.08em', marginBottom: 6 }}>
            {speech.debate}
          </div>
          <p className="serif" style={{ fontSize: 16, lineHeight: 1.55, margin: 0, color: 'var(--ink)', textWrap: 'pretty' }}>
            {speech.summary}
          </p>
          <div style={{ marginTop: 10, display: 'flex', gap: 6, flexWrap: 'wrap', alignItems: 'center' }}>
            {speech.topics.map(t => <TopicTag key={t.id} topic={t} onClick={(tt) => nav('topic', { slug: tt.slug })} />)}
            <span style={{ flex: 1 }} />
            <a
              href="#"
              onClick={(e) => { e.preventDefault(); nav('speech', { id: speech.id }); }}
              style={{ fontSize: 11, color: 'var(--ink-3)', fontFamily: 'var(--mono)' }}
            >
              read full text →
            </a>
          </div>
        </div>
      </div>
    </article>
  );
}

/* ---------- Sparkline ---------- */
function Sparkline({ values, width = 120, height = 28, color = 'var(--ink)' }) {
  if (!values || !values.length) return null;
  const max = Math.max(...values, 1);
  const step = width / (values.length - 1 || 1);
  const points = values.map((v, i) => `${(i * step).toFixed(1)},${(height - (v / max) * height).toFixed(1)}`).join(' ');
  const bars = values.map((v, i) => {
    const h = (v / max) * height;
    return <rect key={i} x={i * (width / values.length) + 1} y={height - h} width={Math.max(2, width / values.length - 2)} height={h} fill={color} />;
  });
  return (
    <svg width={width} height={height} style={{ display: 'block' }}>
      {bars}
    </svg>
  );
}

/* ---------- Horizontal bar (for topic breakdown) ---------- */
function HBar({ items, max, labelKey = 'label', valueKey = 'value', colorKey, onClick }) {
  const m = max ?? Math.max(...items.map(i => i[valueKey]), 1);
  return (
    <div style={{ display: 'grid', gap: 8 }}>
      {items.map((it, i) => {
        const pct = (it[valueKey] / m) * 100;
        return (
          <div key={i} onClick={onClick ? () => onClick(it) : undefined} style={{ cursor: onClick ? 'pointer' : 'default' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 12, marginBottom: 4 }}>
              <span>{it[labelKey]}</span>
              <span className="mono hair">{it[valueKey]}</span>
            </div>
            <div style={{ height: 6, background: 'var(--paper-3)', position: 'relative' }}>
              <div style={{ position: 'absolute', left: 0, top: 0, bottom: 0, width: pct + '%', background: colorKey ? it[colorKey] : 'var(--ink)' }} />
            </div>
          </div>
        );
      })}
    </div>
  );
}

/* ---------- Tweaks panel ---------- */
function TweaksPanel({ tweaks, setTweaks, active, onClose }) {
  if (!active) return null;
  const accents = [
    { id: 'civic-red', c: 'oklch(55% 0.15 25)' },
    { id: 'ink-blue', c: 'oklch(45% 0.12 250)' },
    { id: 'forest',   c: 'oklch(45% 0.10 150)' },
    { id: 'ochre',    c: 'oklch(60% 0.14 70)' },
    { id: 'plum',     c: 'oklch(45% 0.12 350)' },
  ];
  return (
    <div className="tweaks" role="dialog">
      <h3>Tweaks <button onClick={onClose} style={{ fontSize: 14, color: 'var(--ink-3)' }}>×</button></h3>
      <div className="tweak-row">
        <span className="lbl">Accent</span>
        <div className="tweak-opts">
          {accents.map(a => (
            <button
              key={a.id}
              className="tweak-swatch"
              aria-pressed={tweaks.accent === a.c}
              style={{ background: a.c }}
              onClick={() => setTweaks({ ...tweaks, accent: a.c })}
            />
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <span className="lbl">Display</span>
        <div className="tweak-opts">
          {['humanist','grotesque','classical'].map(f => (
            <button key={f} aria-pressed={tweaks.font === f} onClick={() => setTweaks({ ...tweaks, font: f })}>
              {f === 'humanist' ? 'Serif' : f === 'grotesque' ? 'Plex' : 'Caslon'}
            </button>
          ))}
        </div>
      </div>
      <div className="tweak-row">
        <span className="lbl">Density</span>
        <div className="tweak-opts">
          <button aria-pressed={tweaks.density === 'comfortable'} onClick={() => setTweaks({ ...tweaks, density: 'comfortable' })}>Comfort</button>
          <button aria-pressed={tweaks.density === 'compact'} onClick={() => setTweaks({ ...tweaks, density: 'compact' })}>Compact</button>
        </div>
      </div>
      <div className="tweak-row">
        <span className="lbl">Theme</span>
        <div className="tweak-opts">
          <button aria-pressed={tweaks.theme === 'light'} onClick={() => setTweaks({ ...tweaks, theme: 'light' })}>Light</button>
          <button aria-pressed={tweaks.theme === 'dark'} onClick={() => setTweaks({ ...tweaks, theme: 'dark' })}>Dark</button>
        </div>
      </div>
    </div>
  );
}

Object.assign(window, {
  fmtDate, fmtDateLong, fmtN,
  Masthead, Colophon, TopicTag, PartyChip, SpeechItem,
  Sparkline, HBar, TweaksPanel,
});
