const E = s => { const d = document.createElement('div'); d.textContent = String(s); return d.innerHTML; };
let cache = {}, activeId = null;

async function init() {
  try {
    const list = await (await fetch('/api/compare/list')).json();
    if (!list.length) { document.getElementById('tabs').innerHTML = '<div style="color:var(--text-3);padding:8px">No comparisons found. Add JSON files to project-docs/index/data/</div>'; return; }
    document.getElementById('tabs').innerHTML = list.map(c =>
      '<div class="tab" data-id="'+E(c.id)+'" onclick="loadTab(\''+c.id.replace(/'/g,"\\'")+ '\')">'+E(c.label)+'</div>'
    ).join('');
    loadTab(list[0].id);
  } catch(e) { document.getElementById('content').innerHTML = '<div class="loading" style="color:var(--red)">Failed to load: '+E(e.message)+'</div>'; }
}

async function loadTab(id) {
  activeId = id;
  document.querySelectorAll('.tab').forEach(t => t.classList.toggle('active', t.dataset.id === id));
  const el = document.getElementById('content');
  if (cache[id]) { el.innerHTML = render(cache[id]); return; }
  el.innerHTML = '<div class="loading">Loading...</div>';
  try {
    const data = await (await fetch('/api/compare/' + encodeURIComponent(id))).json();
    if (data.error) { el.innerHTML = '<div class="loading" style="color:var(--red)">'+E(data.error)+'</div>'; return; }
    cache[id] = data;
    el.innerHTML = render(data);
  } catch(e) { el.innerHTML = '<div class="loading" style="color:var(--red)">'+E(e.message)+'</div>'; }
}

function render(D) {
  if (D.dimension1) return rValue(D);
  let h = rMeta(D) + rSystems(D);
  if (D.write) h += rWrite(D);
  if (D.architecture) h += rArch(D);
  if (D.fairness) h += rFairness(D);
  h += rQueries(D);
  if (D.rootCause) h += rRC(D.rootCause);
  h += rScore(D);
  h += rExtra(D);
  return h;
}

function rMeta(D) {
  if (!D.meta) return '';
  const m = D.meta;
  let h = '<div class="section">';
  if (m.method) h += '<p style="color:var(--text-2);font-size:13px;margin-bottom:12px">'+E(m.method)+'</p>';
  if (m.note) h += '<p style="color:var(--yellow);font-size:12px;margin-bottom:12px">\u26a0 '+E(m.note)+'</p>';
  return h + '</div>';
}

function rSystems(D) {
  if (!D.systems) return '';
  const keys = Object.keys(D.systems);
  let h = '<div class="overview">';
  keys.forEach(k => {
    const s = D.systems[k];
    h += '<div class="sys-card"><h4>'+E(s.name||k)+'</h4>';
    Object.entries(s).forEach(([fk,fv]) => { if (fk !== 'name') h += '<div class="stat">'+E(fk)+': <b>'+E(String(fv))+'</b></div>'; });
    h += '</div>';
  });
  return h + '</div>';
}

function rWrite(D) {
  const w = D.write;
  let h = '<div class="section"><h3>Write Performance</h3><div style="display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:12px;margin-bottom:16px">';
  Object.entries(w).forEach(([k,v]) => { h += '<div class="stat-card"><div class="label">'+E(k)+'</div><div class="value" style="font-size:20px">'+E(String(v))+'</div></div>'; });
  h += '</div>';
  if (D.mem0_stored) { h += '<p style="color:var(--text-3);font-size:12px;margin-bottom:8px">mem0 stored memories:</p>'; D.mem0_stored.forEach(m => { h += '<div class="detail-item" style="color:var(--green)">'+E(m)+'</div>'; }); }
  return h + '</div>';
}

function rArch(D) {
  const A = D.architecture, cols = Object.keys(A[0]);
  let h = '<div class="section"><h3>Architecture Comparison</h3><table class="tbl"><thead><tr>';
  cols.forEach(c => { h += '<th>'+E(c)+'</th>'; });
  h += '</tr></thead><tbody>';
  A.forEach(row => { h += '<tr>'; cols.forEach(c => { h += '<td class="'+(c==='winner'?wc(row[c]):'')+'">'+E(String(row[c]||''))+'</td>'; }); h += '</tr>'; });
  return h + '</tbody></table></div>';
}

function rFairness(D) {
  let h = '<div class="section"><h3>Fairness Analysis</h3><table class="tbl"><thead><tr><th>Advantage</th><th>Detail</th></tr></thead><tbody>';
  D.fairness.forEach(f => { h += '<tr><td class="'+wc(f.advantage)+'">'+E(f.advantage)+'</td><td>'+E(f.item)+'</td></tr>'; });
  return h + '</tbody></table></div>';
}

function rQueries(D) {
  if (!D.queries || !D.queries.length) return '';
  const Q = D.queries;
  const skip = new Set(['id','query','dim','type','file','winner','notes']);
  const sys = [], det = [];
  Object.keys(Q[0]).forEach(k => { if (skip.has(k)) return; if (k.endsWith('_items')) { det.push(k); return; } if (typeof Q[0][k]==='object' && Q[0][k]!==null) sys.push(k); });
  const wins = {}; Q.forEach(q => { const w = q.winner||'tie'; wins[w]=(wins[w]||0)+1; });

  let h = '<div class="section"><h3>Search Results: '+Q.length+' Queries</h3>';
  h += '<div style="display:flex;gap:12px;margin-bottom:16px">';
  Object.entries(wins).forEach(([w,n]) => { h += '<div class="stat-card" style="flex:1;text-align:center"><div class="label">'+E(w)+'</div><div class="value '+wc(w)+'">'+n+'</div></div>'; });
  h += '</div><table class="tbl"><thead><tr><th>#</th><th>Query</th>';
  if (Q[0].dim!==undefined) h += '<th>Dim</th>';
  if (Q[0].type!==undefined) h += '<th>Type</th>';
  sys.forEach(k => { const nm = D.systems && D.systems[k] ? D.systems[k].name : k; h += '<th>'+E(nm)+'</th>'; });
  h += '<th>Winner</th></tr></thead><tbody>';

  const colSpan = 2 + (Q[0].dim!==undefined?1:0) + (Q[0].type!==undefined?1:0) + sys.length + 1;
  Q.forEach(q => {
    h += '<tr class="expandable" onclick="toggleDetail(\'q'+q.id+'\')">';
    h += '<td class="num">'+q.id+'</td><td style="font-family:var(--mono);font-size:12px;max-width:220px">'+E(q.query)+'</td>';
    if (q.dim!==undefined) h += '<td>'+E(q.dim||'')+'</td>';
    if (q.type!==undefined) h += '<td>'+E(q.type||'')+'</td>';
    sys.forEach(k => {
      const r = q[k];
      if (!r) { h += '<td>-</td>'; return; }
      let c = '';
      if (r.top) c = E(String(r.top)).substring(0,80)+'...';
      else if (r.results) c = E(String(r.results));
      else if (r.p5!==undefined) c = 'P@5:'+r.p5+' MRR:'+(r.mrr!==undefined?r.mrr.toFixed(3):'-');
      else if (r.depth) c = E(String(r.depth)).substring(0,80);
      else c = Object.entries(r).slice(0,3).map(([a,b])=>a+':'+b).join(' ');
      const rel = r.relevant===true?' \u2705':r.relevant===false?' \u274c':'';
      h += '<td style="font-size:11px;max-width:200px;overflow:hidden;text-overflow:ellipsis">'+c+rel+'</td>';
    });
    h += '<td class="'+wc(q.winner)+'">'+E(q.winner||'')+'</td></tr>';
    // Detail row (hidden, toggled by click)
    h += '<tr class="detail" id="d-q'+q.id+'"><td colspan="'+colSpan+'">';
    h += '<div class="detail-grid">';
    sys.forEach(k => {
      const r = q[k];
      const nm = D.systems && D.systems[k] ? D.systems[k].name : k;
      h += '<div class="detail-col"><h5 style="color:'+(wc(k)==='win-a'?'var(--accent)':'var(--green)')+'">'+E(nm)+' Top Result</h5>';
      if (r && r.top) {
        h += '<div class="detail-item"><div style="font-size:10px;color:var(--text-3);margin-bottom:4px">'+(r.count||'-')+' results | '+(r.lat||'-')+'ms | relevant: '+(r.relevant?'yes':'no')+'</div><div>'+E(String(r.top))+'</div></div>';
      } else if (r) {
        h += '<div class="detail-item">'+E(JSON.stringify(r))+'</div>';
      } else {
        h += '<div class="detail-item" style="color:var(--text-3)">No data</div>';
      }
      h += '</div>';
    });
    if (q.notes) h += '<div style="margin-top:8px;font-size:11px;color:var(--text-3)">'+E(q.notes)+'</div>';
    h += '</div></td></tr>';
  });
  return h + '</tbody></table></div>';
}

function rScore(D) {
  if (!D.queries || !D.queries.length) return '';
  const Q = D.queries, wins = {};
  Q.forEach(q => { const w = q.winner||'tie'; wins[w]=(wins[w]||0)+1; });
  const total = Q.length;
  let h = '<div class="section"><h3>Scoreboard</h3><div class="score-grid">';
  Object.entries(wins).forEach(([w,n]) => {
    const pct = Math.round(n/total*100);
    h += '<div class="score-item"><div class="label">'+E(w)+'</div><div class="bar-wrap"><div class="bar '+(wc(w).includes('win-a')?'a':'b')+'" style="width:'+pct+'%"></div><div class="bar-label">'+n+'/'+total+' ('+pct+'%)</div></div></div>';
  });
  return h + '</div></div>';
}

function rRC(text) {
  return '<div class="section"><h3>Root Cause Analysis</h3><div style="background:var(--bg-card);border:1px solid var(--border);border-radius:var(--r);padding:20px"><p style="color:var(--text-2);font-size:13px;line-height:1.8;white-space:pre-wrap">'+E(text)+'</p></div></div>';
}

function rExtra(D) {
  const skip = new Set(['id','label','date','meta','systems','queries','write','architecture','fairness','rootCause','dimension1','dimension2','dimension3','dimension4','timestamp','scores','files','mem0_stored']);
  let h = '';
  Object.keys(D).forEach(k => {
    if (skip.has(k)) return;
    const v = D[k];
    if (v === null || v === undefined) return;
    const title = k.charAt(0).toUpperCase() + k.slice(1);
    if (Array.isArray(v) && v.length && typeof v[0]==='object') {
      const cols = Object.keys(v[0]);
      h += '<div class="section"><h3>'+E(title)+'</h3><table class="tbl"><thead><tr>';
      cols.forEach(c => { h += '<th>'+E(c)+'</th>'; });
      h += '</tr></thead><tbody>';
      v.forEach(row => {
        h += '<tr>';
        cols.forEach(c => {
          let val = row[c];
          if (val === true) val = '\u2705';
          else if (val === false) val = '\u274c';
          else if (val === null) val = '-';
          else if (Array.isArray(val)) { h += '<td style="font-size:11px">'+val.map(it => typeof it==='object'?'<div class="detail-item">'+E(it.src||'')+': '+E(it.txt||'')+'</div>':'<div>'+E(String(it))+'</div>').join('')+'</td>'; return; }
          const isNum = typeof val==='number';
          h += '<td'+(isNum?' class="num"':'')+'>'+E(String(val))+'</td>';
        });
        h += '</tr>';
      });
      h += '</tbody></table></div>';
    } else if (typeof v==='object' && !Array.isArray(v)) {
      const subs = Object.keys(v);
      if (subs.length && typeof v[subs[0]]==='object' && !Array.isArray(v[subs[0]])) {
        h += '<div class="section"><h3>'+E(title)+'</h3><div class="overview">';
        subs.forEach(sk => {
          h += '<div class="sys-card"><h4>'+E(sk)+'</h4>';
          Object.entries(v[sk]).forEach(([fk,fv]) => {
            let dv = fv===true?'\u2705':fv===false?'\u274c':fv===null?'-':String(fv);
            h += '<div class="stat">'+E(fk)+': <b>'+E(dv)+'</b></div>';
          });
          h += '</div>';
        });
        h += '</div></div>';
      } else {
        h += '<div class="section"><h3>'+E(title)+'</h3><div class="sys-card">';
        Object.entries(v).forEach(([fk,fv]) => {
          let dv = fv===true?'\u2705':fv===false?'\u274c':fv===null?'-':String(fv);
          h += '<div class="stat">'+E(fk)+': <b>'+E(dv)+'</b></div>';
        });
        h += '</div></div>';
      }
    }
  });
  return h;
}

function rValue(D) {
  let h = '<div class="section"><h3>Data Source Analysis</h3><p style="color:var(--text-3);font-size:12px;margin-bottom:16px">'+E(D.timestamp||'')+'</p>';
  if (D.dimension1 && D.dimension1.summary) {
    h += '<div style="display:grid;grid-template-columns:1fr 1fr;gap:16px;margin-bottom:16px">';
    Object.values(D.dimension1.summary).forEach(s => {
      h += '<div class="stat-card"><div class="label">'+E(s.label)+'</div><div class="value" style="font-size:20px">'+s.count+'</div>';
      h += '<div style="font-size:11px;color:var(--text-3)">avg conf: '+s.avg_confidence+' | ctx fill: '+s.ctx_fill_rate+'%</div></div>';
    });
    h += '</div>';
  }
  if (D.dimension1 && D.dimension1.sources) {
    h += '<table class="tbl"><thead><tr><th>Source</th><th>Count</th><th>Avg Conf</th><th>Avg Len</th><th>Categories</th></tr></thead><tbody>';
    D.dimension1.sources.forEach(s => { h += '<tr><td>'+E(s.source)+'</td><td class="num">'+s.count+'</td><td class="num">'+s.avg_confidence.toFixed(3)+'</td><td class="num">'+s.avg_assertion_len.toFixed(1)+'</td><td class="num">'+s.category_count+'</td></tr>'; });
    h += '</tbody></table>';
  }
  h += '</div>';
  if (D.dimension3) {
    h += '<div class="section"><h3>Embedding Quality</h3>';
    Object.entries(D.dimension3).forEach(([k,emb]) => {
      h += '<div class="sys-card" style="margin-bottom:12px"><h4>'+E(emb.name||k)+'</h4>';
      h += '<div class="stat">Dim: <b>'+emb.dim+'</b> | Latency: <b>'+emb.latency_ms+'ms</b> | Avg Margin: <b>'+emb.avg_margin.toFixed(4)+'</b></div>';
      if (emb.triplets) {
        h += '<table class="tbl" style="margin-top:8px"><thead><tr><th>Query</th><th>Pos</th><th>Neg</th><th>Margin</th></tr></thead><tbody>';
        emb.triplets.forEach(t => { const mc = t.margin<0?'color:var(--red)':t.margin<0.05?'color:var(--yellow)':'color:var(--green)'; h += '<tr><td style="font-size:12px">'+E(t.q)+'</td><td class="num">'+(t.pos!==undefined?t.pos.toFixed(4):'-')+'</td><td class="num">'+(t.neg!==undefined?t.neg.toFixed(4):'-')+'</td><td class="num" style="'+mc+'">'+t.margin.toFixed(4)+'</td></tr>'; });
        h += '</tbody></table>';
      }
      h += '</div>';
    });
    h += '</div>';
  }
  return h;
}

function wc(w) {
  if (!w) return '';
  const l = w.toLowerCase();
  if (l==='tie'||l==='draw') return 'win-tie';
  if (l.includes('idx1')||l.includes('index1')||l==='index1') return 'win-a';
  return 'win-b';
}

function toggleDetail(id) {
  const el = document.getElementById('d-'+id);
  if (el) el.classList.toggle('open');
}

init();
