
const { useState, useEffect, useRef } = React;
const { SectionHeader, useReveal } = window;

const LAMBDAS = [0.3, 0.5, 0.7, 1.0];
const VD_SOLO = 0.732, SCA_SOLO = 0.994;

const VD_GRID = [
  [0.683,0.699,0.707,0.717],
  [0.678,0.690,0.685,0.686],
  [0.663,0.661,0.663,0.659],
  [0.621,0.639,0.634,0.499],
];
const SCA_GRID = [
  [0.544,0.470,0.399,0.329],
  [0.788,0.578,0.428,0.357],
  [0.840,0.660,0.466,0.313],
  [0.907,0.682,0.419,0.245],
];
const VD_MCC_GRID = [
  [0.433,0.437,0.447,0.469],
  [0.412,0.430,0.429,0.431],
  [0.398,0.409,0.409,0.412],
  [0.366,0.393,0.385,0.078],
];

const CELL_META = {
  '0-3': { label:'BEST VD',      tip:'98% of solo VD retained' },
  '1-0': { label:'BALANCED',     tip:'93% VD · 79% SCA simultaneously' },
  '3-0': { label:'BEST SCA',     tip:'91% of solo SCA retained' },
  '3-3': { label:'CATASTROPHIC', tip:'Unnormalized 2× magnitude — both tasks collapse' },
};

function lerp3(t, lo, hi) {
  return lo.map((l, k) => Math.round(l + (hi[k]-l) * Math.max(0, Math.min(1, t))));
}
function cellBg(val, mode, grid) {
  const flat = grid.flat(), mn = Math.min(...flat), mx = Math.max(...flat);
  const t = (val-mn)/(mx-mn);
  const [r,g,b] = mode === 'vd'
    ? lerp3(t, [10,14,30], [30,90,165])
    : lerp3(t, [10,22,18], [24,92,64]);
  return `rgb(${r},${g},${b})`;
}

/* ── Interactive Heatmap ── */
function Heatmap() {
  const [mode, setMode] = useState('vd');
  const [hov, setHov] = useState(null);
  const [sel, setSel] = useState(null);
  const grid = mode === 'vd' ? VD_GRID : SCA_GRID;

  const selD = sel ? {
    vdF1: VD_GRID[sel[0]][sel[1]],
    scaF1: SCA_GRID[sel[0]][sel[1]],
    mcc: VD_MCC_GRID[sel[0]][sel[1]],
    scaL: LAMBDAS[sel[0]], vdL: LAMBDAS[sel[1]],
    meta: CELL_META[`${sel[0]}-${sel[1]}`],
  } : null;

  return (
    <div>
      {/* Toggle */}
      <div style={{ display:'flex', gap:1, marginBottom:28, border:'1px solid var(--bdr)', width:'fit-content' }}>
        {['vd','sca'].map(m => (
          <button key={m} onClick={() => setMode(m)} style={{
            padding:'8px 24px', cursor:'pointer', fontFamily:'var(--fm)',
            fontSize:11, fontWeight:600, letterSpacing:'0.08em', border:'none',
            background: mode===m ? 'var(--accent)' : 'transparent',
            color: mode===m ? 'var(--bg)' : 'var(--t2)',
            transition:'all 0.2s',
          }}>
            {m==='vd' ? 'VD F1' : 'SCA F1'}
          </button>
        ))}
        <div style={{ display:'flex', alignItems:'center', padding:'0 16px', borderLeft:'1px solid var(--bdr)' }}>
          <span style={{ fontFamily:'var(--fm)', fontSize:10, color:'var(--t3)' }}>
            Solo {mode.toUpperCase()}: <span style={{ color:'var(--t1)' }}>{(mode==='vd'?VD_SOLO:SCA_SOLO).toFixed(3)}</span>
          </span>
        </div>
      </div>

      {/* Grid */}
      <div style={{ maxWidth:540, userSelect:'none' }}>
        <div style={{ display:'grid', gridTemplateColumns:'48px repeat(4,1fr)', gap:3, marginBottom:3 }}>
          <div style={{ display:'flex', alignItems:'flex-end', justifyContent:'flex-end', paddingBottom:4, paddingRight:6 }}>
            <span style={{ fontFamily:'var(--fm)', fontSize:8, color:'var(--t3)', transform:'rotate(-20deg)', whiteSpace:'nowrap', display:'block' }}>λSCA↓ λVD→</span>
          </div>
          {LAMBDAS.map(l => (
            <div key={l} style={{ textAlign:'center', fontFamily:'var(--fm)', fontSize:11, color:'var(--t2)', padding:'4px 0' }}>
              {l}
            </div>
          ))}
        </div>

        {LAMBDAS.map((scaL, i) => (
          <div key={i} style={{ display:'grid', gridTemplateColumns:'48px repeat(4,1fr)', gap:3, marginBottom:3 }}>
            <div style={{ display:'flex', alignItems:'center', justifyContent:'flex-end', paddingRight:10 }}>
              <span style={{ fontFamily:'var(--fm)', fontSize:11, color:'var(--t2)' }}>{scaL}</span>
            </div>
            {LAMBDAS.map((vdL, j) => {
              const val = grid[i][j];
              const key = `${i}-${j}`;
              const meta = CELL_META[key];
              const isHov = hov?.[0]===i && hov?.[1]===j;
              const isSel = sel?.[0]===i && sel?.[1]===j;
              const isCat = i===3 && j===3;
              const pct = Math.round((val/(mode==='vd'?VD_SOLO:SCA_SOLO))*100);
              return (
                <div key={j}
                  onClick={() => setSel(isSel ? null : [i,j])}
                  onMouseEnter={() => setHov([i,j])}
                  onMouseLeave={() => setHov(null)}
                  style={{
                    borderRadius:2, cursor:'pointer', position:'relative',
                    aspectRatio:'1.1', display:'flex', flexDirection:'column',
                    alignItems:'center', justifyContent:'center',
                    background: isCat ? 'rgb(60,10,12)' : cellBg(val, mode, grid),
                    border: isSel ? '2px solid rgba(255,255,255,0.7)' : isHov ? '1px solid rgba(255,255,255,0.35)' : '1px solid rgba(0,0,0,0.3)',
                    transform: isHov ? 'scale(1.06)' : 'scale(1)',
                    transition:'transform 0.12s, border 0.1s',
                    animation: isCat ? 'pulse-glow 2.5s ease-in-out infinite' : 'none',
                    zIndex: isHov||isSel ? 2 : 1,
                  }}>
                  <span style={{ fontFamily:'var(--fm)', fontSize:12, fontWeight:700, color:'rgba(255,255,255,0.92)' }}>
                    {val.toFixed(3)}
                  </span>
                  <span style={{ fontFamily:'var(--fm)', fontSize:9, color:'rgba(255,255,255,0.45)', marginTop:1 }}>
                    {pct}%
                  </span>
                  {meta && (
                    <span style={{ fontFamily:'var(--fm)', fontSize:7, color: isCat ? '#e87070' : 'rgba(255,255,255,0.6)', fontWeight:700, marginTop:2, letterSpacing:'0.04em', textAlign:'center', lineHeight:1.2 }}>
                      {meta.label}
                    </span>
                  )}
                </div>
              );
            })}
          </div>
        ))}

        {/* Scale */}
        <div style={{ display:'flex', alignItems:'center', gap:10, marginTop:14, paddingLeft:51 }}>
          <span style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)' }}>Low</span>
          <div style={{ width:120, height:6, borderRadius:0, background: mode==='vd'
            ? 'linear-gradient(to right,rgb(10,14,30),rgb(30,90,165))'
            : 'linear-gradient(to right,rgb(10,22,18),rgb(24,92,64))' }} />
          <span style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)' }}>High</span>
        </div>
      </div>

      {/* Selected detail */}
      {selD && (
        <div style={{ maxWidth:540, marginTop:18, padding:'18px 20px', border:'1px solid var(--bdr)', background:'var(--card)', animation:'fade-up 0.3s ease both' }}>
          <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center', marginBottom:14, flexWrap:'wrap', gap:8 }}>
            <span style={{ fontFamily:'var(--fm)', fontSize:12, color:'var(--t2)' }}>
              λ<sub>SCA</sub>={selD.scaL} &nbsp;·&nbsp; λ<sub>VD</sub>={selD.vdL}
            </span>
            {selD.meta && (
              <span style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--accent)', letterSpacing:'0.12em' }}>{selD.meta.label}</span>
            )}
          </div>
          <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:8, marginBottom: selD.meta ? 12 : 0 }}>
            {[
              { l:'VD F1',  v:selD.vdF1.toFixed(3),  pct:Math.round(selD.vdF1/VD_SOLO*100),   c:'var(--blue)' },
              { l:'SCA F1', v:selD.scaF1.toFixed(3), pct:Math.round(selD.scaF1/SCA_SOLO*100), c:'var(--green)' },
              { l:'VD MCC', v:selD.mcc.toFixed(3),   pct:null,                                  c:'var(--purple)' },
            ].map(m => (
              <div key={m.l} style={{ padding:'11px 14px', border:'1px solid var(--bdr)' }}>
                <div style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)', marginBottom:5 }}>{m.l}</div>
                <div style={{ fontFamily:'var(--fm)', fontSize:19, fontWeight:700, color:m.c }}>{m.v}</div>
                {m.pct!==null && <div style={{ fontSize:11, color:'var(--t3)', marginTop:3 }}>{m.pct}% of solo</div>}
              </div>
            ))}
          </div>
          {selD.meta && <p style={{ fontSize:13, color:'var(--t2)', fontStyle:'italic' }}>{selD.meta.tip}</p>}
        </div>
      )}
      <p style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)', marginTop:12, letterSpacing:'0.05em' }}>
        Click any cell to inspect · Row = λ<sub>SCA</sub> · Column = λ<sub>VD</sub> · % shown relative to solo adapter
      </p>
    </div>
  );
}

/* ── Dataset Evolution Chart ── */
function DatasetChart() {
  const ref = useRef(null); const inst = useRef(null);
  useEffect(() => {
    if (!ref.current) return;
    if (inst.current) inst.current.destroy();
    Chart.defaults.color = '#68645e';
    inst.current = new Chart(ref.current.getContext('2d'), {
      type:'bar',
      data:{
        labels:['Qwen2.5-3B\n+ BigVul','Llama-3.1-8B\n+ BigVul','Llama-3.1-8B\n+ PrimeVul'],
        datasets:[{ label:'VD F1', data:[0.405,0.483,0.732],
          backgroundColor:['rgba(72,120,184,0.35)','rgba(72,120,184,0.5)','rgba(58,136,96,0.55)'],
          borderColor:['#4878b8','#4878b8','#3a8860'], borderWidth:1, borderRadius:0 }]
      },
      options:{
        responsive:true, maintainAspectRatio:true,
        plugins:{ legend:{display:false},
          tooltip:{ backgroundColor:'#111219', borderColor:'rgba(255,255,255,0.07)', borderWidth:1,
            callbacks:{ label:c=>` VD F1: ${c.parsed.y.toFixed(3)}` } }
        },
        scales:{
          y:{ beginAtZero:true, max:1.0, grid:{color:'rgba(255,255,255,0.05)'}, ticks:{font:{family:'JetBrains Mono',size:10}}, border:{display:false} },
          x:{ grid:{display:false}, ticks:{font:{family:'JetBrains Mono',size:10}}, border:{display:false} }
        }
      }
    });
    return () => { if (inst.current) inst.current.destroy(); };
  }, []);
  return <canvas ref={ref} style={{ maxHeight:240 }} />;
}

/* ── Interference Chart ── */
function InterferenceChart() {
  const ref = useRef(null); const inst = useRef(null);
  useEffect(() => {
    if (!ref.current) return;
    if (inst.current) inst.current.destroy();
    inst.current = new Chart(ref.current.getContext('2d'), {
      type:'line',
      data:{
        labels:['0.3','0.5','0.7','1.0'],
        datasets:[
          { label:'VD F1 (λVD fixed=0.3)', data:[0.683,0.678,0.663,0.621],
            borderColor:'#4878b8', backgroundColor:'rgba(72,120,184,0.07)',
            pointBackgroundColor:'#4878b8', pointRadius:4, tension:0.3, fill:true },
          { label:'SCA F1 (λSCA fixed=0.3)', data:[0.544,0.470,0.399,0.329],
            borderColor:'#3a8860', backgroundColor:'rgba(58,136,96,0.07)',
            pointBackgroundColor:'#3a8860', pointRadius:4, tension:0.3, fill:true }
        ]
      },
      options:{
        responsive:true, maintainAspectRatio:true,
        plugins:{
          legend:{ labels:{ color:'#68645e', font:{family:'JetBrains Mono',size:10}, boxWidth:10, padding:14 } },
          tooltip:{ backgroundColor:'#111219', borderColor:'rgba(255,255,255,0.07)', borderWidth:1 }
        },
        scales:{
          y:{ min:0.2, max:0.75, grid:{color:'rgba(255,255,255,0.05)'}, ticks:{font:{family:'JetBrains Mono',size:10}}, border:{display:false} },
          x:{ title:{display:true, text:'λ of interfering task', color:'#35322c', font:{family:'JetBrains Mono',size:10}},
            grid:{color:'rgba(255,255,255,0.03)'}, ticks:{font:{family:'JetBrains Mono',size:10}}, border:{display:false} }
        }
      }
    });
    return () => { if (inst.current) inst.current.destroy(); };
  }, []);
  return <canvas ref={ref} style={{ maxHeight:240 }} />;
}

/* ── Results Section ── */
function ResultsSection() {
  const r1 = useReveal(), r2 = useReveal(), r3 = useReveal(), r4 = useReveal();
  const soloCards = [
    { label:'Base Model', tag:'degenerate', vdF1:'0.362', scaF1:'0.004', mcc:'0.117', note:'Near-random on both tasks — no LoRA adapter loaded.' },
    { label:'SCA Adapter', tag:'solo', vdF1:'0.416', scaF1:'0.994', mcc:'0.122', note:'366 exact + 3 fuzzy + 2 category matches; zero false alarms on clean code.' },
    { label:'VD Adapter',  tag:'solo', vdF1:'0.732', scaF1:'0.023', mcc:'0.466', note:'Balanced predictions: Safe P=0.749, Vuln P=0.718 — genuine classification signal.' },
  ];

  return (
    <>
      {/* Solo performance */}
      <section id="results" className="sec sec-alt">
        <div className="wrap">
          <SectionHeader label="§4 — Solo Adapter Performance" title="Baseline Results"
            desc="Each adapter performs strongly in isolation. The unaugmented base model is near-random on both tasks, confirming LoRA fine-tuning provides substantial value." />
          <div ref={r1} className="reveal" style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:1, border:'1px solid var(--bdr)', marginBottom:40 }}>
            {soloCards.map((c,i) => (
              <div key={c.label} style={{ padding:'24px', background:'var(--card)', borderRight: i<2 ? '1px solid var(--bdr)' : 'none' }}>
                <div style={{ display:'flex', justifyContent:'space-between', alignItems:'flex-start', marginBottom:16 }}>
                  <span style={{ fontWeight:700, fontSize:14, color:'var(--t1)' }}>{c.label}</span>
                  <span style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)', letterSpacing:'0.1em' }}>{c.tag.toUpperCase()}</span>
                </div>
                <div style={{ display:'grid', gridTemplateColumns:'repeat(3,1fr)', gap:8, marginBottom:14 }}>
                  {[['VD F1',c.vdF1,'var(--blue)'],['SCA F1',c.scaF1,'var(--green)'],['MCC',c.mcc,'var(--purple)']].map(([l,v,col])=>(
                    <div key={l} style={{ textAlign:'center' }}>
                      <div style={{ fontFamily:'var(--fm)', fontSize:9, color:'var(--t3)', marginBottom:4 }}>{l}</div>
                      <div style={{ fontFamily:'var(--fm)', fontSize:18, fontWeight:700, color:col }}>{v}</div>
                    </div>
                  ))}
                </div>
                <p style={{ fontSize:12, color:'var(--t3)', lineHeight:1.6 }}>{c.note}</p>
              </div>
            ))}
          </div>

          {/* Dataset evolution */}
          <div ref={r2} className="reveal glass" style={{ padding:'28px 32px' }}>
            <p style={{ fontFamily:'var(--fm)', fontSize:10, color:'var(--t3)', letterSpacing:'0.14em', marginBottom:6 }}>FINDING: DATASET QUALITY IMPACT</p>
            <h3 style={{ fontFamily:'var(--fh)', fontSize:18, fontWeight:700, marginBottom:6 }}>Data Quality Beats Model Scaling</h3>
            <p style={{ fontSize:14, color:'var(--t2)', marginBottom:24, maxWidth:520, lineHeight:1.72 }}>
              Switching from BigVul (∼25% label accuracy) to PrimeVul on the same Llama-3.1-8B produced the largest VD improvement — larger than upgrading from Qwen-3B to Llama-8B.
            </p>
            <div style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:24, alignItems:'center' }}>
              <div>
                <DatasetChart />
                <p className="fig-caption">Fig. 1 — VD F1 across model and dataset combinations</p>
              </div>
              <div style={{ display:'flex', flexDirection:'column', gap:10 }}>
                {[
                  { label:'Model Scaling', delta:'+0.078', note:'Qwen2.5-3B+BigVul → Llama-3.1-8B+BigVul', muted:true },
                  { label:'Dataset Quality', delta:'+0.249', note:'Llama-3.1-8B+BigVul → Llama-3.1-8B+PrimeVul', muted:false },
                ].map(d=>(
                  <div key={d.label} style={{ padding:'14px 18px', border:'1px solid var(--bdr)', background: d.muted ? 'transparent' : 'rgba(168,139,90,0.05)', borderColor: d.muted ? 'var(--bdr)' : 'rgba(168,139,90,0.2)' }}>
                    <div style={{ fontSize:11, color:'var(--t3)', marginBottom:6, fontFamily:'var(--fm)' }}>{d.note}</div>
                    <div style={{ display:'flex', justifyContent:'space-between', alignItems:'center' }}>
                      <span style={{ fontSize:13, color: d.muted ? 'var(--t2)' : 'var(--accent)' }}>{d.label}</span>
                      <span style={{ fontFamily:'var(--fm)', fontSize:16, fontWeight:700, color: d.muted ? 'var(--t2)' : 'var(--accent)' }}>{d.delta} F1</span>
                    </div>
                  </div>
                ))}
                <div style={{ padding:'12px 16px', border:'1px solid var(--bdr)', fontSize:13, color:'var(--t2)', lineHeight:1.65, fontStyle:'italic' }}>
                  Implication: prioritise dataset curation over model scaling for vulnerability detection research.
                </div>
              </div>
            </div>
          </div>
        </div>
      </section>

      {/* Interactive Heatmap */}
      <section className="sec">
        <div className="wrap">
          <SectionHeader label="§5 — Lambda Grid Results" title="Interactive Interference Map"
            desc="The 4×4 grid of merged configurations. Toggle between VD F1 and SCA F1 views. Click any cell to inspect the full metrics for that configuration." />
          <div ref={r3} className="reveal glass" style={{ padding:'36px 32px' }}>
            <Heatmap />
            <p className="fig-caption" style={{ marginTop:24 }}>Fig. 2 — Lambda grid heatmap. Row = λ<sub>SCA</sub>, Column = λ<sub>VD</sub>. Performance surfaces are approximately complementary.</p>
          </div>
        </div>
      </section>

      {/* Interference analysis */}
      <section className="sec sec-alt">
        <div className="wrap">
          <SectionHeader label="§6 — Interference Analysis" title="Asymmetric Task Interference"
            desc="VD is four times more sensitive to SCA adapter weight than SCA is to VD adapter weight — suggesting binary classification requires more precise parameter specialisation." />
          <div ref={r4} className="reveal" style={{ display:'grid', gridTemplateColumns:'1fr 1fr', gap:32, alignItems:'start' }}>
            <div className="glass" style={{ padding:'28px' }}>
              <p style={{ fontFamily:'var(--fm)', fontSize:10, color:'var(--t3)', letterSpacing:'0.14em', marginBottom:18 }}>F1 vs LAMBDA OF INTERFERING TASK</p>
              <InterferenceChart />
              <p className="fig-caption">Fig. 3 — Degradation as the other task's lambda increases 0.3→1.0</p>
            </div>
            <div style={{ display:'flex', flexDirection:'column', gap:14 }}>
              {[
                { title:'VD sensitivity: −9%', color:'var(--blue)',  body:'At fixed λVD=0.3, VD F1 drops 0.683→0.621 as λSCA increases to 1.0. Modest but consistent degradation — VD parameters are relatively robust.', from:'0.683', to:'0.621', pct:'−9%' },
                { title:'SCA sensitivity: −40%', color:'var(--green)', body:'At fixed λSCA=0.3, SCA F1 drops 0.544→0.329 as λVD increases to 1.0. Structured JSON generation is four times more disrupted by VD adapter weight.', from:'0.544', to:'0.329', pct:'−40%' },
                { title:'Catastrophic at (1.0, 1.0)', color:'var(--red)',   body:'Unnormalised 2× magnitude pushes parameters far outside what either task expects. VD F1 collapses to 0.499, SCA F1 to 0.245 — worse than either solo adapter.', from:'0.732/0.994', to:'0.499/0.245', pct:'FAIL' },
              ].map(c=>(
                <div key={c.title} style={{ padding:'18px 20px', border:'1px solid var(--bdr)', borderLeft:`2px solid ${c.color}`, background:'var(--card)' }}>
                  <div style={{ fontWeight:600, fontSize:13, color:c.color, marginBottom:8 }}>{c.title}</div>
                  <p style={{ fontSize:13, color:'var(--t2)', lineHeight:1.65, marginBottom:10 }}>{c.body}</p>
                  <div style={{ display:'flex', alignItems:'center', gap:8, fontFamily:'var(--fm)', fontSize:11 }}>
                    <span style={{ color:'var(--t3)' }}>{c.from}</span>
                    <span style={{ color:'var(--t3)' }}>→</span>
                    <span style={{ color:c.color }}>{c.to}</span>
                    <span style={{ marginLeft:'auto', color:c.color, fontWeight:700 }}>{c.pct}</span>
                  </div>
                </div>
              ))}
            </div>
          </div>
        </div>
      </section>
    </>
  );
}

Object.assign(window, { ResultsSection });
