/* Page: Keyword rankings + page mapping (SERanking-style centerpiece) */
const { useState: useStateR } = React;

function RankingsView({ client }) {
  const { data, loading, error } = useApi(
    `/api/clients/${client.id}/rankings`,
    [client.id]
  );
  const [selectedKw, setSelectedKw] = useStateR(null);
  const [tab, setTab] = useStateR('keywords');
  const [groupBy, setGroupBy] = useStateR('flat');
  const [valueSort, setValueSort] = useStateR(null); // null | 'asc' | 'desc'

  const [filter, setFilter] = useStateR('all');
  const [search, setSearch] = useStateR('');

  if (loading) return <div className="loading-state">Loading rankings...</div>;
  if (error) return <div className="error-state">Failed to load rankings: {error}</div>;

  const RAW_KEYWORDS = data?.keywords || [];
  const PAGES = data?.pages || [];

  // Derived counts (real data, not hardcoded).
  const total = RAW_KEYWORDS.length;
  const top3 = RAW_KEYWORDS.filter(k => k.pos > 0 && k.pos <= 3).length;
  const top10 = RAW_KEYWORDS.filter(k => k.pos > 0 && k.pos <= 10).length;
  const striking = RAW_KEYWORDS.filter(k => k.pos > 10 && k.pos <= 20).length; // pos 11-20
  const lost = RAW_KEYWORDS.filter(k => !k.pos || k.pos > 100).length;

  // Apply filter pill + search.
  let FILTERED = RAW_KEYWORDS;
  if (filter === 'top3')      FILTERED = FILTERED.filter(k => k.pos > 0 && k.pos <= 3);
  else if (filter === 'top10')   FILTERED = FILTERED.filter(k => k.pos > 0 && k.pos <= 10);
  else if (filter === 'striking') FILTERED = FILTERED.filter(k => k.pos > 10 && k.pos <= 20);
  else if (filter === 'lost')    FILTERED = FILTERED.filter(k => !k.pos || k.pos > 100);
  if (search.trim()) {
    const q = search.toLowerCase();
    FILTERED = FILTERED.filter(k => (k.kw || '').toLowerCase().includes(q));
  }

  const KEYWORDS = valueSort
    ? [...FILTERED].sort((a, b) => {
        const av = a.value || 0;
        const bv = b.value || 0;
        return valueSort === 'asc' ? av - bv : bv - av;
      })
    : FILTERED;

  const activeKw = selectedKw || KEYWORDS[0] || null;

  // Visibility score = % of tracked keywords ranking in top 10.
  const visibility = total > 0 ? Math.round((top10 / total) * 1000) / 10 : 0;
  const avgPos = (() => {
    const ranked = RAW_KEYWORDS.filter(k => k.pos > 0);
    if (!ranked.length) return null;
    return Math.round((ranked.reduce((a, k) => a + k.pos, 0) / ranked.length) * 10) / 10;
  })();

  return (
    <>
      <div className="page-head">
        <div>
          <div className="eyebrow gold"><span className="dot"/>Rankings · {total} keywords tracked</div>
          <h1>Keyword rankings</h1>
          <div className="sub">Tracked keywords mapped to landing pages. Drill into any row for position history.</div>
        </div>
        <div className="actions">
          <button className="btn btn-secondary" disabled title="Add keywords flow not yet built — edit api/config/clients.json directly for now" style={{opacity:0.5, cursor:'not-allowed'}}>
            <Icon name="plus" size={13}/> Add keywords (soon)
          </button>
        </div>
      </div>

      <div className="kpi-grid">
        <div className="kpi">
          <span className="label">Visibility · top 10</span>
          <span className="value">{visibility}%</span>
          <span className="delta flat">{top10} of {total}</span>
          <span className="source">% of tracked in top 10</span>
        </div>
        <div className="kpi">
          <span className="label">Top-3</span>
          <span className="value">{top3}</span>
          <span className="delta flat">of {total}</span>
          <span className="source">positions 1–3</span>
        </div>
        <div className="kpi">
          <span className="label">Top-10</span>
          <span className="value">{top10}</span>
          <span className="delta flat">of {total}</span>
          <span className="source">positions 1–10</span>
        </div>
        <div className="kpi">
          <span className="label">Avg position</span>
          <span className="value">{avgPos ?? '—'}</span>
          <span className="delta flat">Lower is better</span>
          <span className="source">across ranked keywords</span>
        </div>
        <div className="kpi">
          <span className="label">Striking distance</span>
          <span className="value">{striking}</span>
          <span className="delta flat">pos 11–20</span>
          <span className="source">page-1 candidates</span>
        </div>
      </div>

      <div className="section-head">
        <span className="label">Tracked keywords</span>
        <span className="rule"/>
      </div>

      <div className="filter-row">
        <div className="search">
          <Icon name="search" size={14}/>
          <input placeholder={`Search ${total} keywords...`} value={search} onChange={e => setSearch(e.target.value)}/>
        </div>
        <button className={`filter-pill ${filter === 'all' ? 'active' : ''}`} onClick={() => setFilter('all')}>All <span className="v">{total}</span></button>
        <button className={`filter-pill ${filter === 'top3' ? 'active' : ''}`} onClick={() => setFilter('top3')}>Top 3 <span className="v">{top3}</span></button>
        <button className={`filter-pill ${filter === 'top10' ? 'active' : ''}`} onClick={() => setFilter('top10')}>Top 10 <span className="v">{top10}</span></button>
        <button className={`filter-pill ${filter === 'striking' ? 'active' : ''}`} onClick={() => setFilter('striking')}>Striking distance <span className="v">{striking}</span></button>
        <button className={`filter-pill ${filter === 'lost' ? 'active' : ''}`} onClick={() => setFilter('lost')}>Unranked <span className="v">{lost}</span></button>
      </div>

      <div style={{display: 'grid', gridTemplateColumns: '1.6fr 1fr', gap: 16}}>
        {/* Left: keyword table */}
        <div className="panel" style={{minHeight: 520}}>
          <table className="table">
            <thead>
              <tr>
                <th>Keyword</th>
                <th>Mapped page</th>
                <th className="num">Pos</th>
                <th className="num">Δ</th>
                <th className="num">Target</th>
                <th>History · 90d</th>
                <th className="num">Vol</th>
                <th className="num">KD</th>
                <th className="num"
                    style={{cursor:'pointer'}}
                    onClick={() => setValueSort(valueSort === 'desc' ? 'asc' : 'desc')}>
                  Value {valueSort === 'asc' ? '↑' : valueSort === 'desc' ? '↓' : ''}
                </th>
                <th>SERP features</th>
              </tr>
            </thead>
            <tbody>
              {KEYWORDS.map((k, i) => {
                const sel = activeKw?.kw === k.kw;
                const notRanking = k.pos == null || k.pos <= 0; // not found in tracked SERP depth
                const posClass = notRanking ? 'beyond' : k.pos <= 3 ? 'top3' : k.pos <= 10 ? 'top10' : k.pos <= 30 ? 'top30' : 'beyond';
                const delta = (notRanking || k.posPrev == null || k.posPrev <= 0) ? 0 : k.posPrev - k.pos; // positive = improved
                return (
                  <tr key={i}
                      onClick={() => setSelectedKw(k)}
                      style={{cursor:'pointer', background: sel ? 'var(--gold-dim)' : undefined}}>
                    <td>
                      <div className="cell-stack">
                        <span className="lead">{k.kw}</span>
                        <span className="meta">{k.intent} · {k.tags.join(' · ')}</span>
                      </div>
                    </td>
                    <td><span className="mono" style={{color: 'var(--text-muted)', fontSize: 11}}>{k.page}</span></td>
                    <td className="num"><span className={`pos-chip ${posClass}`} title={notRanking ? 'Not found in tracked SERP depth' : ''}>{notRanking ? '>100' : k.pos}</span></td>
                    <td className="num">
                      {delta !== 0 ? (
                        <span className={`delta-chip ${delta > 0 ? 'up' : 'down'}`}>
                          <Icon name={delta > 0 ? 'arrowUp' : 'arrowDown'} size={10}/>
                          {Math.abs(delta)}
                        </span>
                      ) : <span className="delta-chip flat">—</span>}
                    </td>
                    <td className="num"><span style={{fontFamily:'var(--font-mono)', fontSize: 11, color: 'var(--text-dim)'}}>≤{k.target}</span></td>
                    <td><PosSpark values={k.history} w={120} h={28}/></td>
                    <td className="num mono">{k.vol.toLocaleString()}</td>
                    <td className="num mono" style={{color: 'var(--text-muted)'}}>{k.kd}</td>
                    <td className="num mono">{k.value > 0 ? '$' + k.value.toLocaleString() : '—'}</td>
                    <td>
                      <div style={{display:'flex', gap: 4, flexWrap:'wrap'}}>
                        {k.serp.length === 0 ? <span className="dim mono" style={{fontSize: 10}}>—</span> :
                          k.serp.map((s, j) => (
                            <span key={j} className={`serp-badge ${s.toLowerCase().includes('snippet') ? 'gold' : ''}`}>{s}</span>
                          ))}
                      </div>
                    </td>
                  </tr>
                );
              })}
            </tbody>
          </table>
        </div>

        {/* Right: keyword detail panel */}
        <div className="panel" style={{position: 'sticky', top: 0, alignSelf: 'flex-start'}}>
          <div className="panel-head">
            <h3 style={{fontSize: 15}}>{activeKw?.kw || ''}</h3>
            <div className="right">
              <button className="icon-btn" style={{width: 28, height: 28}}><Icon name="ext" size={13}/></button>
            </div>
          </div>
          <div className="panel-body" style={{padding: 0}}>
            <div style={{padding: '14px 18px', display:'grid', gridTemplateColumns:'1fr 1fr', gap: 12, borderBottom:'1px solid var(--border-light)'}}>
              <div>
                <div className="mono-label">Position · today</div>
                <div style={{fontFamily:'var(--font-display)', fontWeight: 900, fontSize: 36, lineHeight: 1, color: 'var(--text)', marginTop: 4}}>{(activeKw?.pos == null || activeKw.pos <= 0) ? '>100' : activeKw.pos}</div>
                <div className={`delta-chip ${(activeKw?.posPrev || 0) - (activeKw?.pos || 0) > 0 ? 'up' : (activeKw?.posPrev || 0) - (activeKw?.pos || 0) < 0 ? 'down' : 'flat'}`} style={{marginTop: 6}}>
                  {(activeKw?.posPrev || 0) - (activeKw?.pos || 0) > 0 ? <Icon name="arrowUp" size={10}/> : (activeKw?.posPrev || 0) - (activeKw?.pos || 0) < 0 ? <Icon name="arrowDown" size={10}/> : null}
                  {(activeKw?.posPrev || 0) - (activeKw?.pos || 0) === 0 ? 'No change' : `${Math.abs((activeKw?.posPrev || 0) - (activeKw?.pos || 0))} from prev week`}
                </div>
              </div>
              <div>
                <div className="mono-label">Best · 90d</div>
                <div style={{fontFamily:'var(--font-display)', fontWeight: 900, fontSize: 36, lineHeight: 1, color: 'var(--gold)', marginTop: 4}}>{(() => { const v = (activeKw?.history || []).filter(x => x != null && x > 0); return v.length ? Math.min(...v) : '>100'; })()}</div>
                <div className="mono-label" style={{marginTop: 6, fontSize: 9}}>Target · ≤{activeKw?.target || 0}</div>
              </div>
            </div>

            <div style={{padding: '14px 18px', borderBottom:'1px solid var(--border-light)'}}>
              <div className="mono-label" style={{marginBottom: 8}}>Position history · 90d</div>
              <PosHistoryChart values={activeKw?.history || []}/>
            </div>

            <div style={{padding: '14px 18px'}}>
              <div className="mono-label" style={{marginBottom: 8}}>Mapped page</div>
              <div style={{display:'flex', gap: 12, alignItems:'flex-start'}}>
                <div style={{flex: 1, minWidth: 0}}>
                  {activeKw?.page ? (
                    <a href={`https://${client?.url || ''}${activeKw.page}`} target="_blank" rel="noreferrer"
                       className="mono" style={{fontSize: 12, color: 'var(--text)', wordBreak:'break-all', textDecoration: 'none'}}>
                      {client?.url || ''}{activeKw.page}
                    </a>
                  ) : (
                    <span className="dim" style={{fontSize: 12}}>No mapped page yet.</span>
                  )}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </>
  );
}

/* Position history line — for the detail panel */
function PosHistoryChart({ values }) {
  const w = 420, h = 140;
  const padL = 28, padR = 8, padT = 8, padB = 22;
  const innerW = w - padL - padR;
  const innerH = h - padT - padB;
  // null / 0 / >100 = not found in tracked SERP depth. Plot at chart floor (100)
  // so unranked weeks drop to the bottom; coercing them to 0 puts them above
  // position 1 and makes unranked keywords look like rank #1.
  const UNRANKED = 100;
  const isUnranked = (v) => v == null || v <= 0 || v > 100;
  const safe = values.map(v => isUnranked(v) ? UNRANKED : v);
  const max = Math.max(20, Math.max(...safe));
  const min = 1;
  const stepX = innerW / (safe.length - 1);
  // Top of chart = best position (1)
  const yFor = (v) => padT + ((v - min) / (max - min)) * innerH;
  const pts = safe.map((v, i) => [padL + i * stepX, yFor(v)]);
  const d = pts.map((p, i) => (i === 0 ? `M${p[0]},${p[1]}` : `L${p[0]},${p[1]}`)).join(' ');
  const last = values[values.length - 1];
  const lastColor = isUnranked(last) ? 'var(--text-muted)'
                  : last <= 3 ? 'var(--gold)' : last <= 10 ? 'var(--accent)' : 'var(--text-muted)';

  const yTicks = [1, 3, 10, 20, 50, 100].filter(t => t <= max);
  return (
    <svg viewBox={`0 0 ${w} ${h}`} style={{width: '100%', height: 140, display:'block'}}>
      {yTicks.map((t, i) => {
        const y = yFor(t);
        return (
          <g key={i}>
            <line x1={padL} x2={w - padR} y1={y} y2={y} className="chart-grid"
                  strokeDasharray={t === 3 || t === 10 ? '2 4' : null}/>
            <text x={padL - 6} y={y + 3} textAnchor="end" className="chart-y-label">{t}</text>
          </g>
        );
      })}
      <path d={d} fill="none" stroke="var(--gold)" strokeWidth="1.75"/>
      {pts.map((p, i) => (
        <circle key={i} cx={p[0]} cy={p[1]} r={i === pts.length - 1 ? 3 : 1.5} fill={i === pts.length - 1 ? lastColor : 'var(--gold)'}/>
      ))}
      <text x={padL} y={h - 6} className="chart-x-label">90d ago</text>
      <text x={w - padR} y={h - 6} textAnchor="end" className="chart-x-label">today</text>
    </svg>
  );
}

window.RankingsView = RankingsView;
