/* global React, IconArrowRight */

// ─── constants ────────────────────────────────────────────────────────────────
const RP_CATEGORIES = [
  'OPEN','EWS','OBC-NCL','SC','ST',
  'OPEN (PwD)','EWS (PwD)','OBC-NCL (PwD)','SC (PwD)','ST (PwD)',
];
const RP_YEARS      = ['2025','2024','2023','2022','2021','2020','2019','2018'];
const RP_TREND_YEARS = [2018,2019,2020,2021,2022,2023,2024,2025];
const RP_INST_TYPES = ['All','IIT','NIT','IIIT','GFTI'];
const RP_QUOTAS     = [
  { value:'AI', label:'All India (AI)' },
  { value:'OS', label:'Other State (OS)' },
  { value:'HS', label:'Home State (HS)' },
];
const PAGE_SIZE = 50;

// ─── styles (all use CSS vars — dark-mode safe) ───────────────────────────────
const labelSt = {
  display:'block', fontFamily:'var(--font-sans)', fontSize:12,
  fontWeight:600, color:'var(--color-body)', marginBottom:4,
};
const inputSt = {
  width:'100%', padding:'9px 11px', borderRadius:8,
  border:'1px solid var(--color-hairline)',
  background:'var(--color-canvas)', color:'var(--color-ink)',
  fontFamily:'var(--font-sans)', fontSize:13, boxSizing:'border-box',
};
const thSt = (align) => ({
  textAlign: align || 'left', padding:'8px 10px',
  color:'var(--color-muted)', fontWeight:600, fontSize:11,
  letterSpacing:'0.06em', textTransform:'uppercase', whiteSpace:'nowrap',
  borderBottom:'2px solid var(--color-hairline)', background:'var(--color-surface-soft)',
});
const tdSt = (extra) => ({
  padding:'7px 10px', fontFamily:'var(--font-sans)', fontSize:13,
  borderBottom:'1px solid var(--color-hairline)', ...extra,
});

// ─── rank-cell background (rgba works in light + dark) ────────────────────────
// closing >= rank × 1.5  → safe   (green)
// closing >= rank        → target (amber)
// closing >= rank / 2    → reach  (red)
// outside those bands    → no colour
const rankCellBg = (closing, rank) => {
  if (closing == null)        return 'transparent';
  if (closing >= rank * 1.5)  return 'rgba(79,124,90,0.18)';
  if (closing >= rank)        return 'rgba(201,154,63,0.18)';
  if (closing >= rank / 2)    return 'rgba(184,71,71,0.18)';
  return 'transparent'; // too far — no emphasis
};

// ─── type badge ───────────────────────────────────────────────────────────────
const TypeBadge = ({ type }) => {
  const colors = {
    IIT:  'rgba(184,84,26,0.18)',
    NIT:  'rgba(26,94,122,0.18)',
    IIIT: 'rgba(106,42,122,0.18)',
    GFTI: 'rgba(58,90,26,0.18)',
  };
  return (
    <span style={{
      display:'inline-block', padding:'2px 8px', borderRadius:100, fontSize:10,
      fontWeight:700, fontFamily:'var(--font-sans)', letterSpacing:'0.05em',
      background: colors[type] || colors.GFTI, color:'var(--color-ink)',
    }}>{type}</span>
  );
};

// ─── pagination bar ───────────────────────────────────────────────────────────
const Pager = ({ page, total, onPage }) => {
  const pages = Math.ceil(total / PAGE_SIZE);
  if (pages <= 1) return null;
  return (
    <div style={{ display:'flex', alignItems:'center', gap:6, marginTop:'1rem', flexWrap:'wrap' }}>
      <button disabled={page === 0} onClick={() => onPage(page - 1)} style={{
        padding:'4px 12px', borderRadius:6, border:'1px solid var(--color-hairline)',
        background:'var(--color-canvas)', color:'var(--color-ink)',
        fontFamily:'var(--font-sans)', fontSize:12, cursor: page === 0 ? 'not-allowed' : 'pointer',
        opacity: page === 0 ? 0.4 : 1,
      }}>← Prev</button>
      <span style={{ fontFamily:'var(--font-sans)', fontSize:12, color:'var(--color-body)' }}>
        Page {page + 1} of {pages} ({total} programmes)
      </span>
      <button disabled={page >= pages - 1} onClick={() => onPage(page + 1)} style={{
        padding:'4px 12px', borderRadius:6, border:'1px solid var(--color-hairline)',
        background:'var(--color-canvas)', color:'var(--color-ink)',
        fontFamily:'var(--font-sans)', fontSize:12,
        cursor: page >= pages - 1 ? 'not-allowed' : 'pointer',
        opacity: page >= pages - 1 ? 0.4 : 1,
      }}>Next →</button>
    </div>
  );
};

// ─── ROUNDS TABLE ─────────────────────────────────────────────────────────────
const RoundsTable = ({ rows, rounds, rank, buf, page, onPage, search }) => {
  const filtered = search
    ? rows.filter(r => r.program_name.toLowerCase().includes(search.toLowerCase()) ||
                       r.institute.toLowerCase().includes(search.toLowerCase()))
    : rows;
  const paged = filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE);
  if (!filtered.length) return (
    <p style={{ color:'var(--color-body)', padding:'1rem 0', fontFamily:'var(--font-sans)', fontSize:14 }}>
      No programmes match your filters.
    </p>
  );
  return (
    <>
      <div style={{ overflowX:'auto', borderRadius:10, border:'1px solid var(--color-hairline)' }}>
        <table style={{ width:'100%', borderCollapse:'collapse' }}>
          <thead>
            <tr>
              <th style={thSt()}>Type</th>
              <th style={thSt()}>Institute</th>
              <th style={thSt()}>Programme</th>
              {rounds.map(r => (
                <th key={r} style={thSt('right')}>R{r}</th>
              ))}
            </tr>
          </thead>
          <tbody>
            {paged.map((row, i) => (
              <tr key={i} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--color-surface-soft)' }}>
                <td style={tdSt({ whiteSpace:'nowrap' })}><TypeBadge type={row.type} /></td>
                <td style={tdSt({ color:'var(--color-ink)', fontWeight:500, minWidth:200 })}>{row.institute}</td>
                <td style={tdSt({ color:'var(--color-body)', minWidth:200 })}>{row.program_name}</td>
                {rounds.map(r => {
                  const d = row.rounds[r];
                  return (
                    <td key={r} style={tdSt({
                      textAlign:'right', fontVariantNumeric:'tabular-nums', fontWeight:600,
                      fontSize:12, whiteSpace:'nowrap',
                      background: d ? rankCellBg(d.closing, rank) : 'transparent',
                      color: d ? 'var(--color-ink)' : 'var(--color-muted)',
                    })}>
                      {d ? d.closing.toLocaleString() : '—'}
                    </td>
                  );
                })}
              </tr>
            ))}
          </tbody>
        </table>
      </div>
      <Pager page={page} total={filtered.length} onPage={onPage} />
    </>
  );
};

// ─── TREND TABLE ──────────────────────────────────────────────────────────────
const TrendTable = ({ rows, rank, buf, page, onPage, search }) => {
  const filtered = search
    ? rows.filter(r => r.program_name.toLowerCase().includes(search.toLowerCase()) ||
                       r.institute.toLowerCase().includes(search.toLowerCase()))
    : rows;
  const paged = filtered.slice(page * PAGE_SIZE, (page + 1) * PAGE_SIZE);
  if (!filtered.length) return (
    <p style={{ color:'var(--color-body)', padding:'1rem 0', fontFamily:'var(--font-sans)', fontSize:14 }}>
      No programmes match your filters.
    </p>
  );
  return (
    <>
      <div style={{ overflowX:'auto', borderRadius:10, border:'1px solid var(--color-hairline)' }}>
        <table style={{ width:'100%', borderCollapse:'collapse' }}>
          <thead>
            <tr>
              <th style={thSt()}>Type</th>
              <th style={thSt()}>Institute</th>
              <th style={thSt()}>Programme</th>
              {RP_TREND_YEARS.map(y => <th key={y} style={thSt('right')}>{y}</th>)}
              <th style={thSt('center')}>Trend</th>
            </tr>
          </thead>
          <tbody>
            {paged.map((row, i) => {
              // trend arrow: compare earliest vs latest available
              const available = RP_TREND_YEARS.filter(y => row.years[y] != null);
              let trendEl = null;
              if (available.length >= 2) {
                const first = row.years[available[0]];
                const last  = row.years[available[available.length - 1]];
                const diff  = last - first; // positive = closing rank going up = getting easier
                trendEl = diff > 500  ? <span style={{ color:'var(--color-positive)', fontWeight:700 }}>↑ easier</span>
                        : diff < -500 ? <span style={{ color:'var(--color-critical)', fontWeight:700 }}>↓ tougher</span>
                        :               <span style={{ color:'var(--color-muted)' }}>— stable</span>;
              }
              return (
                <tr key={i} style={{ background: i % 2 === 0 ? 'transparent' : 'var(--color-surface-soft)' }}>
                  <td style={tdSt({ whiteSpace:'nowrap' })}><TypeBadge type={row.type} /></td>
                  <td style={tdSt({ color:'var(--color-ink)', fontWeight:500, minWidth:200 })}>{row.institute}</td>
                  <td style={tdSt({ color:'var(--color-body)', minWidth:200 })}>{row.program_name}</td>
                  {RP_TREND_YEARS.map(y => {
                    const cr = row.years[y];
                    return (
                      <td key={y} style={tdSt({
                        textAlign:'right', fontVariantNumeric:'tabular-nums', fontWeight:600,
                        fontSize:12, whiteSpace:'nowrap',
                        background: cr != null ? rankCellBg(cr, rank) : 'transparent',
                        color: cr != null ? 'var(--color-ink)' : 'var(--color-muted)',
                      })}>
                        {cr != null ? cr.toLocaleString() : '—'}
                      </td>
                    );
                  })}
                  <td style={tdSt({ textAlign:'center', whiteSpace:'nowrap', fontSize:12, fontFamily:'var(--font-sans)' })}>
                    {trendEl || '—'}
                  </td>
                </tr>
              );
            })}
          </tbody>
        </table>
      </div>
      <Pager page={page} total={filtered.length} onPage={onPage} />
    </>
  );
};

// ─── main component ───────────────────────────────────────────────────────────
const RankPredictor = () => {
  const [form, setForm] = React.useState({
    rank:'', category:'OPEN', gender:'Gender-Neutral',
    quota:'AI', instType:'All', year:'2024',
  });
  const [search,      setSearch]      = React.useState('');
  const [results,     setResults]     = React.useState(null);
  const [loading,     setLoading]     = React.useState(false);
  const [error,       setError]       = React.useState(null);
  const [activeTab,   setActiveTab]   = React.useState('target');
  const [viewMode,    setViewMode]    = React.useState('rounds');  // 'rounds' | 'trend'
  const [trendData,   setTrendData]   = React.useState(null);
  const [trendLoading,setTrendLoading]= React.useState(false);
  const [page,        setPage]        = React.useState(0);

  const set = (k) => (e) => setForm(f => ({ ...f, [k]: e.target.value }));
  const resetPage = () => setPage(0);

  // ── main search ────────────────────────────────────────────────────────────
  const handleSearch = async (e) => {
    e.preventDefault();
    const rank = parseInt(form.rank);
    if (!rank || rank < 1) return;
    setLoading(true); setError(null); setResults(null);
    setTrendData(null); setViewMode('rounds'); setPage(0); setSearch('');

    try {
      let query = window.supabaseClient
        .from('jee_cutoffs')
        .select('institute,program_name,opening_rank,closing_rank,type,round')
        .eq('category', form.category)
        .eq('gender',   form.gender)
        .eq('year',     parseInt(form.year))
        .eq('quota',    form.quota)
        .order('closing_rank', { ascending: false })
        .limit(10000);
      if (form.instType !== 'All') query = query.eq('type', form.instType);

      const { data, error: err } = await query;
      if (err) throw err;

      // find available rounds
      const roundSet = new Set();
      data.forEach(r => roundSet.add(r.round));
      const rounds = [...roundSet].sort((a,b) => a - b);

      // group by (institute, programme) → rounds map
      const byKey = {};
      for (const row of data) {
        const key = `${row.institute}||${row.program_name}`;
        if (!byKey[key]) byKey[key] = {
          institute: row.institute, program_name: row.program_name,
          type: row.type, rounds: {},
        };
        byKey[key].rounds[row.round] = { opening: row.opening_rank, closing: row.closing_rank };
      }
      const rows = Object.values(byKey);

      // ── classify using last available round per programme ───────────────────
      // In JEE a smaller rank number = better performance.
      // closing_rank is the rank of the last admitted student last year.
      //
      //   Dream  : closing < rank/2          → cutoff would need to drop >50% — skip
      //   Reach  : rank/2 ≤ closing < rank   → realistic stretch; cutoff needs to rise
      //   Target : rank ≤ closing < rank×1.5 → you'd get in, but it's competitive
      //   Safe   : rank×1.5 ≤ closing ≤ rank×5 → comfortable buffer
      //   Easy   : closing > rank×5          → too trivial to list; just count
      //
      // Within each bucket sort so the most relevant row appears first:
      //   Reach  → descending (closest-to-you reach at top)
      //   Target → ascending  (tightest target at top, then easier ones)
      //   Safe   → ascending  (most prestigious safe at top)
      const lastRound = rounds[rounds.length - 1];
      const getD = (r) => r.rounds[lastRound] || Object.values(r.rounds).at(-1);
      const getCR = (r) => { const d = getD(r); return d ? d.closing : null; };

      const reach  = rows
        .filter(r => { const cr = getCR(r); return cr != null && cr >= rank / 2 && cr < rank; })
        .sort((a,b) => getCR(b) - getCR(a));         // desc — closest reach first

      const target = rows
        .filter(r => { const cr = getCR(r); return cr != null && cr >= rank && cr < rank * 1.5; })
        .sort((a,b) => getCR(a) - getCR(b));         // asc  — tightest target first

      const safe   = rows
        .filter(r => { const cr = getCR(r); return cr != null && cr >= rank * 1.5 && cr <= rank * 5; })
        .sort((a,b) => getCR(a) - getCR(b));         // asc  — most competitive safe first

      const hiddenDream = rows.filter(r => { const cr = getCR(r); return cr != null && cr < rank / 2; }).length;
      const hiddenEasy  = rows.filter(r => { const cr = getCR(r); return cr != null && cr > rank * 5; }).length;

      setResults({ safe, target, reach, total: rows.length, rounds, rank, hiddenDream, hiddenEasy });
      // default tab: target if any exist, otherwise reach (most useful direction)
      setActiveTab(target.length ? 'target' : reach.length ? 'reach' : 'safe');
    } catch (err) {
      setError('Could not fetch data. Please try again.');
    } finally {
      setLoading(false);
    }
  };

  // ── trend query ────────────────────────────────────────────────────────────
  const handleTrend = async () => {
    if (!results) return;
    setTrendLoading(true); setTrendData(null); setPage(0);
    try {
      let query = window.supabaseClient
        .from('jee_cutoffs')
        .select('institute,program_name,closing_rank,type,round,year')
        .eq('category', form.category)
        .eq('gender',   form.gender)
        .eq('quota',    form.quota)
        .order('year',  { ascending: true })
        .limit(15000);
      if (form.instType !== 'All') query = query.eq('type', form.instType);

      const { data, error: err } = await query;
      if (err) throw err;

      // keep max round per (institute, programme, year)
      const byRound = {};
      for (const row of data) {
        const key = `${row.institute}||${row.program_name}||${row.year}`;
        if (!byRound[key] || row.round > byRound[key].round) byRound[key] = row;
      }
      // group by (institute, programme) → year map
      const byProg = {};
      for (const row of Object.values(byRound)) {
        const key = `${row.institute}||${row.program_name}`;
        if (!byProg[key]) byProg[key] = {
          institute: row.institute, program_name: row.program_name,
          type: row.type, years: {},
        };
        byProg[key].years[row.year] = row.closing_rank;
      }
      setTrendData(Object.values(byProg));
    } catch (err) {
      setError('Could not load trend data.');
    } finally {
      setTrendLoading(false);
    }
  };

  // filter trend rows using same thresholds as main search
  const trendForTab = React.useMemo(() => {
    if (!trendData || !results) return [];
    const { rank } = results;
    const getRef = (row) => row.years[2024] ?? row.years[2025] ?? row.years[2023] ??
      row.years[Object.keys(row.years).sort().at(-1)];
    if (activeTab === 'safe')   return trendData.filter(r => { const cr = getRef(r); return cr != null && cr >= rank * 1.5 && cr <= rank * 5; });
    if (activeTab === 'target') return trendData.filter(r => { const cr = getRef(r); return cr != null && cr >= rank && cr < rank * 1.5; });
    if (activeTab === 'reach')  return trendData.filter(r => { const cr = getRef(r); return cr != null && cr >= rank / 2 && cr < rank; });
    return trendData;
  }, [trendData, activeTab, results]);

  const activeRows = results
    ? (activeTab === 'safe' ? results.safe : activeTab === 'target' ? results.target : results.reach)
    : [];

  // ── tab button ─────────────────────────────────────────────────────────────
  const TabBtn = ({ id, label, count, color }) => (
    <button onClick={() => { setActiveTab(id); resetPage(); }} style={{
      background:'none', border:'none',
      borderBottom: activeTab === id ? `3px solid ${color}` : '3px solid transparent',
      marginBottom:-2, padding:'10px 16px',
      fontFamily:'var(--font-sans)', fontWeight: activeTab === id ? 700 : 500,
      color: activeTab === id ? color : 'var(--color-body)',
      cursor:'pointer', fontSize:14, transition:'color 150ms',
    }}>
      {label} <span style={{ opacity:0.7 }}>({count})</span>
    </button>
  );

  // ── view mode toggle ───────────────────────────────────────────────────────
  const ModeBtn = ({ id, label }) => (
    <button onClick={() => { setViewMode(id); resetPage(); if (id === 'trend' && !trendData) handleTrend(); }} style={{
      padding:'6px 14px', borderRadius:6, fontSize:12, fontWeight:600,
      fontFamily:'var(--font-sans)', cursor:'pointer', transition:'background 150ms',
      background: viewMode === id ? 'var(--color-ink)' : 'var(--color-surface-soft)',
      color:       viewMode === id ? 'var(--color-canvas)' : 'var(--color-body)',
      border:      viewMode === id ? 'none' : '1px solid var(--color-hairline)',
    }}>{label}</button>
  );

  // ──────────────────────────────────────────────────────────────────────────
  return (
    <section style={{ maxWidth:1100, margin:'0 auto', padding:'2.5rem 1rem 5rem' }}>

      {/* heading */}
      <div style={{ marginBottom:'2rem' }}>
        <h1 style={{
          fontFamily:'var(--font-serif)', fontSize:'clamp(1.6rem,4vw,2.4rem)',
          color:'var(--color-ink)', marginBottom:'.4rem',
        }}>Rank Predictor</h1>
        <p style={{ color:'var(--color-body)', fontFamily:'var(--font-sans)', fontSize:15, maxWidth:600, margin:0 }}>
          Enter your JEE rank to see round-by-round and year-by-year cutoffs — colour-coded as Safe, Target and Reach.
        </p>
      </div>

      {/* filter card */}
      <form onSubmit={handleSearch} style={{
        background:'var(--color-surface-soft)',
        border:'1px solid var(--color-hairline)',
        borderRadius:14, padding:'1.5rem', marginBottom:'2rem',
      }}>
        <div style={{
          display:'grid', gridTemplateColumns:'repeat(auto-fit,minmax(150px,1fr))',
          gap:'1rem', marginBottom:'1.25rem',
        }}>
          <div>
            <label style={labelSt}>Your JEE Rank *</label>
            <input
              type="number" min="1" max="999999" required
              placeholder="e.g. 8500"
              value={form.rank} onChange={set('rank')} style={inputSt}
            />
          </div>
          <div>
            <label style={labelSt}>Category</label>
            <select value={form.category} onChange={set('category')} style={inputSt}>
              {RP_CATEGORIES.map(c => <option key={c} value={c}>{c}</option>)}
            </select>
          </div>
          <div>
            <label style={labelSt}>Gender</label>
            <select value={form.gender} onChange={set('gender')} style={inputSt}>
              <option value="Gender-Neutral">Gender-Neutral</option>
              <option value="Female-only">Female-only</option>
            </select>
          </div>
          <div>
            <label style={labelSt}>Quota</label>
            <select value={form.quota} onChange={set('quota')} style={inputSt}>
              {RP_QUOTAS.map(q => <option key={q.value} value={q.value}>{q.label}</option>)}
            </select>
          </div>
          <div>
            <label style={labelSt}>Institute Type</label>
            <select value={form.instType} onChange={set('instType')} style={inputSt}>
              {RP_INST_TYPES.map(t => <option key={t} value={t}>{t === 'All' ? 'All Institutes' : t}</option>)}
            </select>
          </div>
          <div>
            <label style={labelSt}>Reference Year</label>
            <select value={form.year} onChange={set('year')} style={inputSt}>
              {RP_YEARS.map(y => <option key={y} value={y}>{y}</option>)}
            </select>
          </div>
        </div>

        <div style={{ display:'flex', alignItems:'center', gap:16, flexWrap:'wrap' }}>
          <button
            type="submit" disabled={loading} className="btn btn-primary"
            style={{ opacity: loading ? 0.7 : 1, cursor: loading ? 'not-allowed' : 'pointer' }}
          >
            {loading ? 'Searching…' : 'Find Colleges'}
            {!loading && <IconArrowRight size={16} />}
          </button>
          <p style={{ fontFamily:'var(--font-sans)', fontSize:12, color:'var(--color-muted)', margin:0 }}>
            Based on JoSAA cutoff data (2018–2025). Round-by-round breakdown shown.
          </p>
        </div>
      </form>

      {error && (
        <p style={{ color:'var(--color-critical)', fontFamily:'var(--font-sans)', marginBottom:'1rem', fontSize:14 }}>
          {error}
        </p>
      )}

      {/* results */}
      {results && (
        <div>
          {/* summary bar */}
          <div style={{
            display:'flex', flexWrap:'wrap', alignItems:'center',
            justifyContent:'space-between', gap:12, marginBottom:'1rem',
          }}>
            <p style={{ fontFamily:'var(--font-sans)', fontSize:13, color:'var(--color-body)', margin:0, lineHeight:1.7 }}>
              <span style={{ color:'var(--color-critical)', fontWeight:600 }}>🚀 Reach: {results.reach.length}</span>
              {' · '}
              <span style={{ color:'#C99A3F', fontWeight:600 }}>🎯 Target: {results.target.length}</span>
              {' · '}
              <span style={{ color:'var(--color-positive)', fontWeight:600 }}>✅ Safe: {results.safe.length}</span>
              {results.hiddenDream > 0 && (
                <span style={{ color:'var(--color-muted)', fontSize:12 }}>
                  {' · '}{results.hiddenDream} too-selective (closing &lt; {Math.round(results.rank / 2).toLocaleString()}) hidden
                </span>
              )}
              {results.hiddenEasy > 0 && (
                <span style={{ color:'var(--color-muted)', fontSize:12 }}>
                  {' · '}{results.hiddenEasy} trivially easy (closing &gt; {(results.rank * 5).toLocaleString()}) hidden
                </span>
              )}
              <span style={{ color:'var(--color-muted)', fontSize:12 }}>
                {' · '}Rounds: {results.rounds.map(r => `R${r}`).join(', ')}
              </span>
            </p>

            {/* view mode toggle */}
            <div style={{ display:'flex', gap:6 }}>
              <ModeBtn id="rounds" label="📋 Rounds" />
              <ModeBtn id="trend"  label={trendLoading ? '⏳ Loading…' : '📈 8-yr Trend'} />
            </div>
          </div>

          {/* colour legend */}
          <div style={{
            display:'flex', gap:14, flexWrap:'wrap', marginBottom:'1rem',
            fontFamily:'var(--font-sans)', fontSize:11, color:'var(--color-body)',
          }}>
            {[
              { bg:'rgba(79,124,90,0.18)',  label:'Safe — closing rank 1.5× – 5× yours (comfortable buffer)' },
              { bg:'rgba(201,154,63,0.18)', label:'Target — closing rank between your rank and 1.5× (competitive)' },
              { bg:'rgba(184,71,71,0.18)',  label:'Reach — closing rank between half your rank and your rank (stretch)' },
            ].map(l => (
              <span key={l.label} style={{ display:'flex', alignItems:'center', gap:5 }}>
                <span style={{ display:'inline-block', width:14, height:14, borderRadius:3, background:l.bg, flexShrink:0 }} />
                {l.label}
              </span>
            ))}
          </div>

          {/* search */}
          <div style={{ marginBottom:'1rem' }}>
            <input
              type="text" placeholder="Filter by institute or programme name…"
              value={search} onChange={e => { setSearch(e.target.value); resetPage(); }}
              style={{ ...inputSt, maxWidth:380 }}
            />
          </div>

          {/* tabs */}
          <div style={{ display:'flex', gap:4, borderBottom:'2px solid var(--color-hairline)', marginBottom:'1.25rem' }}>
            <TabBtn id="safe"   label="✅ Safe"   count={results.safe.length}   color="var(--color-positive)" />
            <TabBtn id="target" label="🎯 Target" count={results.target.length} color="#C99A3F" />
            <TabBtn id="reach"  label="🚀 Reach"  count={results.reach.length}  color="var(--color-critical)" />
          </div>

          {/* table */}
          {viewMode === 'rounds' && (
            <RoundsTable
              rows={activeRows} rounds={results.rounds}
              rank={results.rank} buf={results.buf}
              page={page} onPage={setPage} search={search}
            />
          )}
          {viewMode === 'trend' && (
            trendLoading
              ? <p style={{ fontFamily:'var(--font-sans)', color:'var(--color-body)', fontSize:14 }}>Loading 8-year trend data…</p>
              : trendData
                ? <TrendTable
                    rows={trendForTab}
                    rank={results.rank} buf={results.buf}
                    page={page} onPage={setPage} search={search}
                  />
                : null
          )}

          {/* CTA */}
          <div style={{
            marginTop:'2.5rem', background:'var(--color-primary-soft)',
            borderRadius:12, padding:'1.5rem',
            display:'flex', flexWrap:'wrap', alignItems:'center',
            justifyContent:'space-between', gap:'1rem',
          }}>
            <div>
              <p style={{ fontFamily:'var(--font-serif)', fontSize:18, fontWeight:700, color:'var(--color-ink)', margin:'0 0 4px' }}>
                Not sure which ones to pick?
              </p>
              <p style={{ fontFamily:'var(--font-sans)', fontSize:14, color:'var(--color-body)', margin:0 }}>
                Our counsellors help you build a personalised shortlist accounting for placement data, campus life and branch fit.
              </p>
            </div>
            <a href="#/counselling" className="btn btn-primary">
              Book a session <IconArrowRight size={16} />
            </a>
          </div>
        </div>
      )}

    </section>
  );
};

window.RankPredictor = RankPredictor;
