/* global React */

/* ============================= MPS DIRECTORY ============================= */
function MpsPage({ nav, filter }) {
  const D = window.PT_DATA;
  const [q, setQ] = React.useState('');
  const [party, setParty] = React.useState(filter?.party || 'all');
  const [district, setDistrict] = React.useState('all');
  const [sort, setSort] = React.useState('speeches');

  const filtered = React.useMemo(() => {
    let list = [...D.MPS];
    if (q) list = list.filter(m => m.name.toLowerCase().includes(q.toLowerCase()));
    if (party !== 'all') list = list.filter(m => m.party.abbr === party);
    if (district !== 'all') list = list.filter(m => m.district === district);
    if (sort === 'speeches') list.sort((a,b) => b.speechCount - a.speechCount);
    else if (sort === 'name') list.sort((a,b) => a.name.localeCompare(b.name));
    else if (sort === 'party') list.sort((a,b) => a.party.abbr.localeCompare(b.party.abbr));
    return list;
  }, [q, party, district, sort]);

  return (
    <div className="shell">
      <header style={{ padding: '28px 0 20px', borderBottom: '2px solid var(--ink)' }}>
        <div className="kicker" style={{ marginBottom: 8 }}>Directory</div>
        <h1 className="serif" style={{ fontSize: 48, lineHeight: 1.0, fontWeight: 600, letterSpacing: '-0.025em', margin: 0 }}>
          Members of Parliament
        </h1>
        <p style={{ fontSize: 14, color: 'var(--ink-3)', marginTop: 10, maxWidth: '60ch' }}>
          All {D.STATS.totalMps} sitting members of the 10th Parliament. Filter by party or district, or search by name.
        </p>
      </header>

      <div style={{ padding: '16px 0', borderBottom: '1px solid var(--rule)', display: 'flex', gap: 20, alignItems: 'center', flexWrap: 'wrap' }}>
        <div className="search-inline" style={{ flex: '1 1 220px' }}>
          <span className="mono hair" style={{ fontSize: 11 }}>⌕</span>
          <input placeholder="Search by name..." value={q} onChange={(e) => setQ(e.target.value)} />
        </div>
        <Select label="Party" value={party} onChange={setParty} options={[['all','All parties'], ...D.PARTIES.map(p => [p.abbr, `${p.abbr} · ${p.seats}`])]} />
        <Select label="District" value={district} onChange={setDistrict} options={[['all','All districts'], ...D.DISTRICTS.map(d => [d, d])]} />
        <Select label="Sort" value={sort} onChange={setSort} options={[['speeches','Most active'],['name','A–Z'],['party','By party']]} />
        <span className="mono hair" style={{ fontSize: 11, marginLeft: 'auto' }}>{filtered.length} members</span>
      </div>

      <section style={{ padding: '12px 0' }}>
        <div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 0 }} className="mps-grid">
          {filtered.slice(0, 48).map(m => (
            <a key={m.id} href="#" onClick={(e)=>{e.preventDefault();nav('mp',{id:m.id});}}
              style={{ padding: '16px 18px 16px 0', borderBottom: '1px solid var(--rule)', borderRight: '1px solid var(--rule)', display: 'grid', gridTemplateColumns: '1fr auto', gap: 8, alignItems: 'start' }}>
              <div>
                <div className="serif" style={{ fontSize: 18, fontWeight: 600, letterSpacing: '-0.01em', lineHeight: 1.15 }}>{m.name}</div>
                <div style={{ fontSize: 11, color: 'var(--ink-3)', marginTop: 4, display: 'flex', gap: 6, alignItems: 'center' }}>
                  <PartyChip party={m.party} /> <span className="hair">·</span> {m.district}
                </div>
                <div style={{ marginTop: 10 }}>
                  <Sparkline values={m.activity} width={80} height={14} color="var(--ink-3)" />
                </div>
              </div>
              <span className="mono tnum" style={{ fontSize: 14, color: 'var(--ink-2)' }}>{m.speechCount}</span>
            </a>
          ))}
        </div>
        {filtered.length > 48 && (
          <div style={{ textAlign: 'center', padding: 20, fontSize: 12, color: 'var(--ink-3)' }} className="mono">
            Showing 48 of {filtered.length} · load more →
          </div>
        )}
      </section>
    </div>
  );
}

function Select({ label, value, onChange, options }) {
  return (
    <label style={{ display: 'flex', alignItems: 'baseline', gap: 8, fontSize: 12 }}>
      <span className="kicker" style={{ fontSize: 10 }}>{label}</span>
      <select value={value} onChange={(e) => onChange(e.target.value)}
        style={{ fontFamily: 'var(--sans)', fontSize: 12, border: 0, borderBottom: '1px solid var(--ink-3)', background: 'transparent', padding: '3px 4px', color: 'var(--ink)', outline: 'none' }}>
        {options.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
      </select>
    </label>
  );
}

/* ============================= TOPICS INDEX ============================= */
function TopicsPage({ nav }) {
  const D = window.PT_DATA;
  const sorted = [...D.TOPICS].sort((a,b) => b.count - a.count);
  const max = Math.max(...D.TOPICS.map(t => t.count));
  return (
    <div className="shell">
      <header style={{ padding: '28px 0 20px', borderBottom: '2px solid var(--ink)' }}>
        <div className="kicker" style={{ marginBottom: 8 }}>Index</div>
        <h1 className="serif" style={{ fontSize: 48, lineHeight: 1.0, fontWeight: 600, letterSpacing: '-0.025em', margin: 0 }}>Policy areas</h1>
        <p style={{ fontSize: 14, color: 'var(--ink-3)', marginTop: 10, maxWidth: '64ch' }}>
          Eighteen flat categories that cover what gets debated in the chamber. Every speech is tagged by AI with one to three topics.
        </p>
      </header>
      <div style={{ padding: '16px 0' }}>
        {sorted.map((t, i) => (
          <a key={t.slug} href="#" onClick={(e)=>{e.preventDefault();nav('topic',{slug:t.slug});}}
            style={{ display: 'grid', gridTemplateColumns: '40px 1fr 260px 60px', gap: 18, padding: '16px 0', borderTop: '1px solid var(--rule)', alignItems: 'center' }}>
            <span className="mono hair" style={{ fontSize: 12 }}>{String(i+1).padStart(2,'0')}</span>
            <div className="serif" style={{ fontSize: 22, fontWeight: 600, letterSpacing: '-0.01em' }}>{t.name}</div>
            <div style={{ height: 4, background: 'var(--paper-3)', position: 'relative' }}>
              <div style={{ position: 'absolute', inset: 0, width: (t.count / max * 100) + '%', background: 'var(--ink)' }} />
            </div>
            <span className="mono tnum" style={{ fontSize: 14, textAlign: 'right' }}>{t.count}</span>
          </a>
        ))}
      </div>
    </div>
  );
}

/* ============================= SITTINGS INDEX ============================= */
function SittingsPage({ nav }) {
  const D = window.PT_DATA;
  return (
    <div className="shell">
      <header style={{ padding: '28px 0 20px', borderBottom: '2px solid var(--ink)' }}>
        <div className="kicker" style={{ marginBottom: 8 }}>Archive</div>
        <h1 className="serif" style={{ fontSize: 48, lineHeight: 1.0, fontWeight: 600, letterSpacing: '-0.025em', margin: 0 }}>Sittings</h1>
        <p style={{ fontSize: 14, color: 'var(--ink-3)', marginTop: 10, maxWidth: '64ch' }}>
          A sitting is one day of parliament. The record below includes everything said on the floor of the House.
        </p>
      </header>
      <table className="ptable" style={{ marginTop: 12 }}>
        <thead>
          <tr>
            <th style={{ width: 60 }}>#</th>
            <th>Date</th>
            <th>Session</th>
            <th className="num">Speeches</th>
            <th>Activity</th>
          </tr>
        </thead>
        <tbody>
          {[...D.SITTINGS].reverse().map((s, i) => (
            <tr key={s.id} onClick={() => nav('sitting', { date: s.date })} style={{ cursor: 'pointer' }}>
              <td className="mono hair">{String(D.SITTINGS.length - i).padStart(2,'0')}</td>
              <td className="serif" style={{ fontSize: 16, fontWeight: 600 }}>{fmtDateLong(s.date)}</td>
              <td style={{ color: 'var(--ink-3)' }}>{s.session}</td>
              <td className="num">{s.speechCount}</td>
              <td>
                <div style={{ height: 6, width: 160, background: 'var(--paper-3)', position: 'relative' }}>
                  <div style={{ position: 'absolute', inset: 0, width: (s.speechCount / 300 * 100) + '%', background: 'var(--accent)' }} />
                </div>
              </td>
            </tr>
          ))}
        </tbody>
      </table>
    </div>
  );
}

/* ============================= SEARCH ============================= */
function SearchPage({ initialQ = '', nav }) {
  const D = window.PT_DATA;
  const [q, setQ] = React.useState(initialQ);
  const [topicFilter, setTopicFilter] = React.useState('all');
  const [partyFilter, setPartyFilter] = React.useState('all');

  const results = React.useMemo(() => {
    if (!q) return [];
    const ql = q.toLowerCase();
    return D.SPEECHES.filter(s => {
      const txt = `${s.summary} ${s.mp.name}`.toLowerCase();
      if (!txt.includes(ql)) return false;
      if (topicFilter !== 'all' && !s.topics.some(t => t.slug === topicFilter)) return false;
      if (partyFilter !== 'all' && s.mp.party.abbr !== partyFilter) return false;
      return true;
    });
  }, [q, topicFilter, partyFilter]);

  const suggestions = ['fertiliser', 'IMF', 'Wilpattu', 'fuel', 'hospital', 'corruption', 'Mullaitivu'];

  return (
    <div className="shell">
      <header style={{ padding: '28px 0 14px', borderBottom: '2px solid var(--ink)' }}>
        <div className="kicker" style={{ marginBottom: 8 }}>Search the record</div>
        <div className="search-inline" style={{ borderBottom: '2px solid var(--ink)', padding: '10px 0' }}>
          <span className="mono hair" style={{ fontSize: 14 }}>⌕</span>
          <input value={q} onChange={(e) => setQ(e.target.value)} placeholder="Search 2,018 speeches…"
            style={{ fontSize: 22, fontFamily: 'var(--serif)' }} autoFocus />
        </div>
        {!q && (
          <div style={{ display: 'flex', gap: 8, marginTop: 14, flexWrap: 'wrap', alignItems: 'center' }}>
            <span className="kicker" style={{ marginRight: 4 }}>Try</span>
            {suggestions.map(s => (
              <button key={s} className="chip" onClick={() => setQ(s)}>{s}</button>
            ))}
          </div>
        )}
      </header>

      {q && (
        <>
          <div style={{ padding: '14px 0', display: 'flex', gap: 20, alignItems: 'baseline', borderBottom: '1px solid var(--rule)', flexWrap: 'wrap' }}>
            <span className="mono" style={{ fontSize: 12 }}>{results.length} results for <strong>"{q}"</strong></span>
            <Select label="Topic" value={topicFilter} onChange={setTopicFilter} options={[['all','All'], ...D.TOPICS.map(t => [t.slug, t.short])]} />
            <Select label="Party" value={partyFilter} onChange={setPartyFilter} options={[['all','All'], ...D.PARTIES.map(p => [p.abbr, p.abbr])]} />
          </div>
          <div>
            {results.slice(0, 20).map(s => (
              <SpeechItem key={s.id} speech={s} showDate={true} nav={nav} />
            ))}
            {results.length === 0 && (
              <div style={{ padding: 40, textAlign: 'center', color: 'var(--ink-3)' }} className="serif">
                No speeches match <em>"{q}"</em> with the current filters.
              </div>
            )}
          </div>
        </>
      )}
    </div>
  );
}

/* ============================= HEATMAP (novel) ============================= */
function HeatmapPage({ nav }) {
  const D = window.PT_DATA;
  const [mode, setMode] = React.useState('share'); // share or absolute
  const visibleParties = D.PARTIES.filter(p => p.seats >= 1).sort((a,b) => b.seats - a.seats);
  // values: share (%) or absolute count per cell
  function cellValue(topic, abbr) {
    const row = D.TOPIC_PARTY_MATRIX.find(r => r.topic === topic.slug);
    const share = row.values[abbr] || 0;
    if (mode === 'share') return share;
    return Math.round(share * topic.count);
  }
  function cellColor(topic, abbr) {
    const row = D.TOPIC_PARTY_MATRIX.find(r => r.topic === topic.slug);
    const share = row.values[abbr] || 0;
    // intensity relative to max share in this row
    const maxInRow = Math.max(...visibleParties.map(p => row.values[p.abbr] || 0));
    const t = maxInRow > 0 ? share / maxInRow : 0;
    if (t < 0.05) return 'var(--hm-0)';
    if (t < 0.15) return 'var(--hm-1)';
    if (t < 0.35) return 'var(--hm-2)';
    if (t < 0.6)  return 'var(--hm-3)';
    if (t < 0.85) return 'var(--hm-4)';
    return 'var(--hm-5)';
  }

  const [hover, setHover] = React.useState(null);

  return (
    <div className="shell">
      <header style={{ padding: '28px 0 14px', borderBottom: '2px solid var(--ink)' }}>
        <div className="kicker" style={{ marginBottom: 8 }}>Novel view</div>
        <h1 className="serif" style={{ fontSize: 48, lineHeight: 1.0, fontWeight: 600, letterSpacing: '-0.025em', margin: 0 }}>
          Who talks about what?
        </h1>
        <p style={{ fontSize: 15, color: 'var(--ink-2)', marginTop: 12, maxWidth: '68ch', lineHeight: 1.5 }} className="serif">
          A party-by-topic heatmap. Each cell shows the share of speeches tagged with that topic that came from MPs of a given party — so you can see who owns each issue.
        </p>
      </header>

      <div style={{ padding: '14px 0', display: 'flex', gap: 16, alignItems: 'center', borderBottom: '1px solid var(--rule)', flexWrap: 'wrap' }}>
        <div className="tweak-opts">
          <button aria-pressed={mode === 'share'} onClick={() => setMode('share')}>Share</button>
          <button aria-pressed={mode === 'absolute'} onClick={() => setMode('absolute')}>Absolute</button>
        </div>
        <span className="mono hair" style={{ fontSize: 11 }}>Intensity is relative per topic row · darker = disproportionate focus</span>
        <span style={{ marginLeft: 'auto', fontSize: 11, color: hover ? 'var(--ink)' : 'var(--ink-3)' }} className="mono">
          {hover ? `${hover.topic.name} × ${hover.party.name} · ${(hover.share * 100).toFixed(0)}% share, ${Math.round(hover.share * hover.topic.count)} speeches` : 'hover any cell'}
        </span>
      </div>

      <div style={{ padding: '20px 0', overflowX: 'auto' }}>
        <table className="ptable" style={{ borderSpacing: 0, borderCollapse: 'separate', minWidth: 800 }}>
          <thead>
            <tr>
              <th style={{ width: 200, position: 'sticky', left: 0, background: 'var(--paper)' }}>Topic</th>
              {visibleParties.map(p => (
                <th key={p.abbr} style={{ textAlign: 'center', minWidth: 48 }}>
                  <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 3 }}>
                    <span className="party-dot" style={{ background: p.color, width: 8, height: 8 }} />
                    <span className="mono" style={{ fontSize: 10 }}>{p.abbr}</span>
                  </div>
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {D.TOPICS.map(topic => {
              const row = D.TOPIC_PARTY_MATRIX.find(r => r.topic === topic.slug);
              return (
                <tr key={topic.slug}>
                  <td style={{ position: 'sticky', left: 0, background: 'var(--paper)', borderRight: '1px solid var(--rule)' }}>
                    <a href="#" onClick={(e)=>{e.preventDefault();nav('topic',{slug:topic.slug});}} className="serif" style={{ fontSize: 14, fontWeight: 600 }}>
                      {topic.short}
                    </a>
                    <div className="mono hair" style={{ fontSize: 10, marginTop: 2 }}>{topic.count}</div>
                  </td>
                  {visibleParties.map(p => {
                    const share = row.values[p.abbr] || 0;
                    const v = cellValue(topic, p.abbr);
                    return (
                      <td key={p.abbr} style={{ padding: 2, border: 0 }}
                        onMouseEnter={() => setHover({ topic, party: p, share })}
                        onMouseLeave={() => setHover(null)}>
                        <div className="hm-cell" style={{ background: cellColor(topic, p.abbr), aspectRatio: 'unset', height: 36 }}>
                          {mode === 'share' ? (share > 0.05 ? (share * 100).toFixed(0) : '') : (v > 2 ? v : '')}
                        </div>
                      </td>
                    );
                  })}
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>

      <div style={{ padding: '8px 0 24px', fontSize: 12, color: 'var(--ink-3)', display: 'flex', alignItems: 'center', gap: 10 }}>
        <span className="kicker">Scale</span>
        {['hm-0','hm-1','hm-2','hm-3','hm-4','hm-5'].map((c, i) => (
          <span key={c} style={{ display: 'inline-flex', alignItems: 'center', gap: 4 }}>
            <span style={{ width: 16, height: 12, background: `var(--${c})`, border: '1px solid var(--rule)' }} />
            <span className="mono" style={{ fontSize: 10 }}>{i === 0 ? '0' : i === 5 ? 'max' : ''}</span>
          </span>
        ))}
      </div>
    </div>
  );
}

Object.assign(window, { MpsPage, TopicsPage, SittingsPage, SearchPage, HeatmapPage });
