// Panels — left (scenario + target) and right (variant + delivery + methylation)
// Methylation-sensitive ThermoCas9 (Roth et al., Nature 2026)

const { useState, useEffect, useMemo, useRef } = React;

function LeftPanel({ scenarioKey, setScenarioKey, targetIdx, setTargetIdx }) {
  const scenario = SCENARIOS[scenarioKey];
  return (
    <div className="panel panel-left">
      <div className="section">
        <h3 className="section-title">Scenario <span className="count">{Object.keys(SCENARIOS).length}</span></h3>
        <div className="cancer-list">
          {Object.entries(SCENARIOS).map(([k, s]) => {
            const cancer = CELL_LINES[s.cancer_line];
            const normal = CELL_LINES[s.normal_line];
            return (
              <div
                key={k}
                className={`cancer-card ${k === scenarioKey ? 'active' : ''}`}
                onClick={() => { setScenarioKey(k); setTargetIdx(DEFAULT_TARGET_INDEX[k] || 0); }}
              >
                <div className="cname">
                  <span>{s.name}</span>
                  <span className="cshort">{s.short}</span>
                </div>
                <div className="cmeta">
                  <span>{cancer.name}</span>
                  <span>vs</span>
                  <span>{normal.name}</span>
                </div>
              </div>
            );
          })}
        </div>
      </div>

      <div className="section">
        <h3 className="section-title">Target Sites <span className="count">{scenario.targets.length}</span></h3>
        <div style={{display:'flex', flexDirection:'column', gap: 2}}>
          {scenario.targets.map((t, i) => (
            <div
              key={`${t.gene}-${t.site}`}
              className={`target-row ${i === targetIdx ? 'active' : ''}`}
              onClick={() => setTargetIdx(i)}
            >
              <div>
                <div className="gene">{t.gene} <span style={{fontSize: 10, color:'var(--fg-mute)', fontWeight: 400}}>· {t.site}</span></div>
                <div className="locus">{t.coords} · PAM {t.pam}</div>
                <BetaPair betaCancer={t.beta_cancer} betaNormal={t.beta_normal} />
              </div>
              <div className="strategy-badge" style={{
                color: t.beta_cancer < t.beta_normal ? 'var(--good)' : t.beta_cancer > t.beta_normal ? 'var(--warn)' : 'var(--fg-dim)',
                borderColor: 'var(--line-2)',
              }}>
                {t.beta_cancer < t.beta_normal ? '↓ in cancer' : t.beta_cancer > t.beta_normal ? '↑ in cancer' : 'equal'}
              </div>
            </div>
          ))}
        </div>
      </div>

      <div className="section">
        <h3 className="section-title">Target Detail</h3>
        <TargetDetail target={scenario.targets[targetIdx]} scenario={scenario} />
      </div>
    </div>
  );
}

function BetaPair({ betaCancer, betaNormal }) {
  // Two stacked bars: cancer methylation and normal methylation
  return (
    <div style={{marginTop: 6, display:'grid', gridTemplateColumns:'auto 1fr auto', gap: 6, alignItems:'center', fontSize: 9, fontFamily:'JetBrains Mono, monospace', color:'var(--fg-mute)'}}>
      <span>cancer β</span>
      <div style={{height: 3, background:'var(--bg-3)'}}>
        <div style={{height:'100%', width: `${betaCancer * 100}%`, background:'var(--good)'}} />
      </div>
      <span style={{color:'var(--fg-dim)'}}>{betaCancer.toFixed(2)}</span>
      <span>normal β</span>
      <div style={{height: 3, background:'var(--bg-3)'}}>
        <div style={{height:'100%', width: `${betaNormal * 100}%`, background:'var(--warn)'}} />
      </div>
      <span style={{color:'var(--fg-dim)'}}>{betaNormal.toFixed(2)}</span>
    </div>
  );
}

function TargetDetail({ target, scenario }) {
  // Deterministic pseudo-spacer seeded by gene + site
  const seq = useMemo(() => {
    const rng = mulberry32(hashStr(target.gene + target.site));
    const bases = ['A','C','G','T'];
    let s = '';
    for (let i = 0; i < 20; i++) s += bases[Math.floor(rng() * 4)];
    return s;
  }, [target.gene, target.site]);
  const gc = (seq.match(/[GC]/g) || []).length / seq.length;
  const tm = (54 + gc * 18).toFixed(1);

  // The PAM cytosine that gets methylated — "C5*" of the NNNNCGA / NNNNCCA motif
  const pam = target.pam;
  const c5Index = 4; // position of the critical cytosine in the PAM (0-indexed)

  return (
    <div>
      <div style={{marginBottom: 8, fontSize: 11, color: 'var(--fg-dim)'}}>
        <span className="role-pill">{target.role}</span>
        <span className="role-pill" style={{color: 'var(--good)'}}>cancer β {target.beta_cancer.toFixed(2)}</span>
        <span className="role-pill" style={{color: 'var(--warn)'}}>normal β {target.beta_normal.toFixed(2)}</span>
      </div>
      <div style={{fontSize: 11, color: 'var(--fg-dim)', marginBottom: 10, lineHeight: 1.5}}>
        {target.note}
      </div>
      <div className="grna-block">
        <div className="label-row">
          <span>gRNA spacer (20nt) + PAM</span>
          <span>5′ → 3′</span>
        </div>
        <div className="seq">
          <span className="nt">{seq}</span>
          <span className="pam">
            {pam.split('').map((b, i) => (
              <span key={i} style={i === c5Index ? {textDecoration: 'underline', textDecorationStyle:'dotted', textUnderlineOffset: '2px'} : {}}>{b}</span>
            ))}
          </span>
        </div>
        <div className="tm">
          <span>GC <b>{Math.round(gc * 100)}%</b></span>
          <span>Tm <b>{tm}°C</b></span>
          <span>PAM C5 <b style={{color:'var(--accent)'}}>methylation-gated</b></span>
        </div>
      </div>
      <div style={{fontSize: 10, color: 'var(--fg-mute)', marginTop: 8, fontFamily: 'JetBrains Mono, monospace', lineHeight: 1.6}}>
        ThermoCas9 Asp1017 contacts the C5* base of the PAM through the major groove. A 5-methyl group on this cytosine sterically blocks DNA binding — the discrimination step happens before any cleavage attempt (Roth et al., 2026, Fig. 4).
      </div>
    </div>
  );
}

function RightPanel({ variantKey, setVariantKey, delivery, setDelivery, beta, setBeta, scenarioKey, targetIdx }) {
  return (
    <div className="panel panel-right">
      <div className="section">
        <h3 className="section-title">Enzyme Variant</h3>
        <div className="mode-select">
          {Object.entries(VARIANTS).map(([k, v]) => (
            <div
              key={k}
              className={`mode-opt ${k === variantKey ? 'active' : ''}`}
              onClick={() => setVariantKey(k)}
            >
              <div className="mlabel">
                <span>{v.name}</span>
                <span className="mabbr">{v.abbr}</span>
              </div>
              <div className="mdesc">{v.desc}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="section">
        <h3 className="section-title">Delivery Format</h3>
        <div className="delivery-select">
          {Object.entries(DELIVERY).map(([k, d]) => (
            <button
              key={k}
              className={`delivery-opt ${k === delivery ? 'active' : ''}`}
              onClick={() => setDelivery(k)}
            >
              {d.name}
              <span className="deff">→ {Math.round(d.efficiency * 100)}% peak efficiency</span>
            </button>
          ))}
        </div>
      </div>

      <div className="section">
        <h3 className="section-title">Methylation Sensitivity Probe</h3>
        <div className="temp-block">
          <div className="temp-readout tabular">
            β {beta.toFixed(2)}<span className="unit">5mC at PAM C5</span>
          </div>
          <input
            type="range"
            min="0" max="1" step="0.01"
            value={beta}
            onChange={e => setBeta(parseFloat(e.target.value))}
          />
          <div className="temp-subrow">
            <span>0.00 hypo</span>
            <span>0.25</span>
            <span>0.50</span>
            <span>1.00 hyper</span>
          </div>
          <NucleaseReadouts beta={beta} variantKey={variantKey} />
          <ActivityCurve beta={beta} variantKey={variantKey} />
        </div>
      </div>

      <div className="section">
        <h3 className="section-title">Specificity Bonus</h3>
        <SpecificityPanel beta={beta} variantKey={variantKey} scenarioKey={scenarioKey} targetIdx={targetIdx} />
      </div>
    </div>
  );
}

function NucleaseReadouts({ beta, variantKey }) {
  // Pick the active ThermoCas9 series based on variant
  const tcKey = variantKey === 'CE' ? 'ce_thermocas9' : 'thermocas9';
  const variantScale = VARIANTS[variantKey].activity_scale;
  const showsMethylation = VARIANTS[variantKey].methylation_sensitive;
  const tcAct = (showsMethylation ? activityVsMethylation(tcKey, beta) : activityVsMethylation(tcKey, 0)) * variantScale;
  const spAct = activityVsMethylation('spcas9', beta);
  return (
    <div style={{display:'grid', gridTemplateColumns:'1fr 1fr', gap: 8, marginTop: 8}}>
      <div>
        <div style={{fontFamily:'JetBrains Mono, monospace', fontSize: 9, color:'var(--fg-mute)', letterSpacing:'0.1em'}}>
          {VARIANTS[variantKey].abbr === 'CE' ? 'CE-THERMOCAS9' : 'THERMOCAS9'} ({VARIANTS[variantKey].abbr})
        </div>
        <div className="tabular" style={{fontFamily:'JetBrains Mono, monospace', fontSize: 18, color:'var(--accent)'}}>
          {(tcAct * 100).toFixed(0)}<span style={{fontSize: 10, color:'var(--fg-mute)'}}>% act</span>
        </div>
      </div>
      <div>
        <div style={{fontFamily:'JetBrains Mono, monospace', fontSize: 9, color:'var(--fg-mute)', letterSpacing:'0.1em'}}>SpCas9 (control)</div>
        <div className="tabular" style={{fontFamily:'JetBrains Mono, monospace', fontSize: 18, color:'var(--fg-dim)'}}>
          {(spAct * 100).toFixed(0)}<span style={{fontSize: 10, color:'var(--fg-mute)'}}>% act</span>
        </div>
      </div>
    </div>
  );
}

function ActivityCurve({ beta, variantKey }) {
  const W = 280, H = 80, PAD = 2;
  const tcKey = variantKey === 'CE' ? 'ce_thermocas9' : 'thermocas9';
  const series = [
    { key: tcKey, color: 'var(--accent)' },
    { key: 'acecas9', color: 'var(--purple)' },
    { key: 'spcas9', color: 'var(--fg-dim)' },
  ];
  const toX = (b) => PAD + b * (W - PAD * 2);
  const toY = (a) => H - PAD - a * (H - PAD * 2);
  const samples = [];
  for (let b = 0; b <= 1.001; b += 0.02) samples.push(b);

  return (
    <div className="curve-mini" style={{height: 80}}>
      <div className="legend">
        <span><i style={{background:'var(--accent)'}} /> {VARIANTS[variantKey].abbr === 'CE' ? 'CE-TC9' : 'TC9'}</span>
        <span><i style={{background:'var(--purple)'}} /> AceCas9</span>
        <span><i style={{background:'var(--fg-dim)'}} /> SpCas9</span>
      </div>
      <svg viewBox={`0 0 ${W} ${H}`} preserveAspectRatio="none">
        {series.map(s => {
          const path = samples.map(b => `${toX(b).toFixed(1)},${toY(activityVsMethylation(s.key, b)).toFixed(1)}`).join(' ');
          return <polyline key={s.key} points={path} fill="none" stroke={s.color} strokeWidth={s.key === 'spcas9' ? 1 : 1.5} strokeDasharray={s.key === 'spcas9' ? '2 2' : 'none'} opacity={s.key === 'spcas9' ? 0.6 : 1} />;
        })}
        <line x1={toX(beta)} x2={toX(beta)} y1={PAD} y2={H - PAD} stroke="var(--warn)" strokeWidth="1" />
        <circle cx={toX(beta)} cy={toY(activityVsMethylation(tcKey, beta))} r="3" fill="var(--accent)" />
      </svg>
    </div>
  );
}

function SpecificityPanel({ beta, variantKey, scenarioKey, targetIdx }) {
  const scenario = SCENARIOS[scenarioKey];
  const target = scenario.targets[targetIdx];
  const tcKey = variantKey === 'CE' ? 'ce_thermocas9' : 'thermocas9';
  const showsMethylation = VARIANTS[variantKey].methylation_sensitive;
  const cancerAct = (showsMethylation ? activityVsMethylation(tcKey, target.beta_cancer) : activityVsMethylation(tcKey, 0));
  const normalAct = (showsMethylation ? activityVsMethylation(tcKey, target.beta_normal) : activityVsMethylation(tcKey, 0));
  const ratio = normalAct > 0.001 ? (cancerAct / normalAct) : 999;
  const severity = ratio > 50 ? 'good' : ratio > 5 ? 'warn' : 'danger';

  return (
    <div>
      <div className="tabular" style={{fontFamily:'JetBrains Mono, monospace', fontSize: 11, color:'var(--fg-dim)', display:'flex', justifyContent:'space-between'}}>
        <span>Cancer / normal selectivity</span>
        <span className={severity === 'good' ? 'value good' : severity === 'warn' ? 'value warn' : 'value danger'} style={{fontSize: 14}}>
          {ratio > 999 ? '∞' : ratio.toFixed(1)}×
        </span>
      </div>
      <div style={{height: 6, background:'var(--bg-3)', marginTop: 8, border: '1px solid var(--line)'}}>
        <div style={{
          height:'100%',
          width: `${Math.min(100, Math.log10(Math.max(1, ratio)) * 33)}%`,
          background: severity === 'good' ? 'var(--good)' : severity === 'warn' ? 'var(--warn)' : 'var(--danger)',
          transition: 'width 0.3s',
        }} />
      </div>
      <div style={{fontSize: 10, color:'var(--fg-mute)', marginTop: 8, lineHeight: 1.5}}>
        {!showsMethylation
          ? `${VARIANTS[variantKey].abbr} loses methylation discrimination — selectivity collapses to ~1×.`
          : ratio > 50
          ? `Strong methylation lock: ${(cancerAct * 100).toFixed(0)}% activity in cancer line vs ${(normalAct * 100).toFixed(1)}% in normal line.`
          : ratio > 5
          ? 'Useful selectivity. Differential β between cancer and normal allows preferential editing.'
          : 'Low selectivity at this site — methylation differential is too small to gate.'}
      </div>
    </div>
  );
}

Object.assign(window, {
  LeftPanel, RightPanel, ActivityCurve, SpecificityPanel,
  TargetDetail, BetaPair, NucleaseReadouts,
});
