/* global React, YComps, YagodaStore, YDrawer */
const { useState, useEffect, useMemo, useCallback, useRef } = React;
const Y = window.YagodaStore;
const { Chip, JsonView, DriftChart, BenchmarkChart, BenchmarkDeltaBars, useToast, I } = window.YComps;
const { RunDrawer, downloadJSON } = window.YDrawer;

// ============ QUANTUM STATE ATLAS — HELPERS ============
const STATUS_COLORS = {
  stable:     { main: '#62E4F7', alpha: 'rgba(98,228,247,0.11)' },
  warning:    { main: '#F5C56B', alpha: 'rgba(245,197,107,0.11)' },
  unstable:   { main: '#FF3D6E', alpha: 'rgba(255,61,110,0.13)' },
  regression: { main: '#FF3D6E', alpha: 'rgba(255,61,110,0.13)' },
  reviewed:   { main: '#A7F06D', alpha: 'rgba(167,240,109,0.11)' },
};
const scol = (s) => STATUS_COLORS[s] || STATUS_COLORS.stable;
const nLabel = (run) => run.sample.replace(/Qubit-/g, '').split(/\s*\/\s*/)[0].trim();

// ============ QUANTUM STATE ATLAS SVG ============
function QuantumStateAtlas({ runs, alerts, selectedRunId, onSelectRun }) {
  const CX = 260, CY = 260, OR = 218, NODE_R = 16, N = runs.length;

  const alertsByRun = {};
  alerts.filter(a => !a.resolved).forEach(a => {
    if (!alertsByRun[a.run_id]) alertsByRun[a.run_id] = [];
    alertsByRun[a.run_id].push(a);
  });

  const nodes = runs.map((run, i) => {
    const angle = (i / N) * 2 * Math.PI - Math.PI / 2;
    return { run, x: CX + OR * Math.cos(angle), y: CY + OR * Math.sin(angle) };
  });

  // Central waveform derived from deviation data
  const wavePoints = runs.map((run, i) => {
    const x = CX - 54 + (i / (N - 1)) * 108;
    const y = CY + (run.deviation - 2.5) * 9;
    return `${i === 0 ? 'M' : 'L'}${x.toFixed(1)},${y.toFixed(1)}`;
  }).join(' ');

  return (
    <svg viewBox="0 0 520 520" className="atlas-svg" xmlns="http://www.w3.org/2000/svg" aria-label="Quantum State Atlas — run visibility map">
      <defs>
        <filter id="af-gr" x="-60%" y="-60%" width="220%" height="220%">
          <feGaussianBlur stdDeviation="3" result="b"/>
          <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
        <filter id="af-gc" x="-60%" y="-60%" width="220%" height="220%">
          <feGaussianBlur stdDeviation="5" result="b"/>
          <feMerge><feMergeNode in="b"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
        <radialGradient id="af-cg" cx="50%" cy="50%">
          <stop offset="0%"   stopColor="#FF3D6E" stopOpacity="0.32"/>
          <stop offset="65%"  stopColor="#FF3D6E" stopOpacity="0.05"/>
          <stop offset="100%" stopColor="#FF3D6E" stopOpacity="0"/>
        </radialGradient>
      </defs>

      {/* Radial grid lines */}
      {Array.from({ length: 12 }).map((_, i) => {
        const a = (i / 12) * Math.PI * 2;
        return <line key={i} x1={CX} y1={CY}
          x2={(CX + (OR + 40) * Math.cos(a)).toFixed(1)}
          y2={(CY + (OR + 40) * Math.sin(a)).toFixed(1)}
          stroke="rgba(255,255,255,0.022)" strokeWidth="1"/>;
      })}

      {/* Atlas rings — outer to inner */}
      <circle cx={CX} cy={CY} r={OR + 38} fill="none" stroke="rgba(98,228,247,0.032)" strokeWidth="1" strokeDasharray="2,12"/>
      <circle cx={CX} cy={CY} r={OR + 18} fill="none" stroke="rgba(98,228,247,0.068)" strokeWidth="1"/>
      <circle cx={CX} cy={CY} r={OR}      fill="none" stroke="rgba(98,228,247,0.13)"  strokeWidth="1"/>
      <circle cx={CX} cy={CY} r={148}     fill="none" stroke="rgba(98,228,247,0.05)"  strokeWidth="1" strokeDasharray="2,10"/>
      <circle cx={CX} cy={CY} r={80}      fill="none" stroke="rgba(255,61,110,0.07)"  strokeWidth="1"/>
      <circle cx={CX} cy={CY} r={46}      fill="none" stroke="rgba(255,61,110,0.11)"  strokeWidth="1"/>

      {/* Connection spokes from center to each node */}
      {nodes.map(({ run, x, y }) => (
        <line key={`s-${run.run_id}`} x1={CX} y1={CY}
          x2={x.toFixed(1)} y2={y.toFixed(1)}
          stroke={run.run_id === selectedRunId ? 'rgba(98,228,247,0.12)' : 'rgba(255,255,255,0.032)'}
          strokeWidth={run.run_id === selectedRunId ? 1.5 : 0.8}/>
      ))}

      {/* Center glow */}
      <circle cx={CX} cy={CY} r={56} fill="url(#af-cg)"/>

      {/* Central waveform — generated from run deviations */}
      <path d={wavePoints} fill="none" stroke="rgba(255,61,110,0.52)" strokeWidth="1.5" strokeLinecap="round" filter="url(#af-gr)"/>

      {/* Center core dot */}
      <circle cx={CX} cy={CY} r={7}   fill="rgba(255,61,110,0.28)" filter="url(#af-gr)"/>
      <circle cx={CX} cy={CY} r={3.5} fill="#FF3D6E"/>
      <circle cx={CX} cy={CY} r={1.5} fill="rgba(255,255,255,0.82)"/>

      {/* Atlas label */}
      <text x={CX} y={CY + 20} textAnchor="middle" fontSize="6.5"
        fontFamily="JetBrains Mono, monospace" fill="rgba(255,61,110,0.48)" letterSpacing="2.5">
        QUANTUM STATE ATLAS
      </text>

      {/* Run nodes */}
      {nodes.map(({ run, x, y }) => {
        const sel = run.run_id === selectedRunId;
        const c   = scol(run.derived_status);
        const xi  = x.toFixed(1), yi = y.toFixed(1);
        const isGolden  = run.tags?.includes('golden');
        const runAlerts = alertsByRun[run.run_id] || [];
        const hasCrit   = runAlerts.some(a => a.severity === 'critical');
        const hasWarn   = runAlerts.length > 0 && !hasCrit;
        const lbl = nLabel(run);

        return (
          <g key={run.run_id} onClick={() => onSelectRun(run.run_id)}
            style={{ cursor: 'pointer' }} role="button" aria-label={`${run.run_id} · ${run.derived_status}`}>
            {/* Alert pulse rings */}
            {hasCrit && <circle cx={xi} cy={yi} r={NODE_R + 12} fill="none"
              stroke="rgba(255,61,110,0.28)" strokeWidth="1.5" className="af-pulse-crit"/>}
            {hasWarn && <circle cx={xi} cy={yi} r={NODE_R + 10} fill="none"
              stroke="rgba(245,197,107,0.26)" strokeWidth="1" className="af-pulse-warn"/>}
            {/* Golden run dashed indicator */}
            {isGolden && <circle cx={xi} cy={yi} r={NODE_R + 5} fill="none"
              stroke="rgba(245,197,107,0.62)" strokeWidth="1.5" strokeDasharray="3,3"/>}
            {/* Selection glow ring */}
            {sel && <circle cx={xi} cy={yi} r={NODE_R + 4} fill="none"
              stroke={c.main} strokeWidth="2" opacity="0.72" filter="url(#af-gc)"/>}
            {/* Main node */}
            <circle cx={xi} cy={yi} r={NODE_R} fill={c.alpha} stroke={c.main} strokeWidth={sel ? 2 : 1}/>
            {/* Sample label */}
            <text x={xi} y={yi} textAnchor="middle" dominantBaseline="central"
              fontSize="8.5" fontFamily="JetBrains Mono, monospace"
              fill={c.main} letterSpacing="0.4">{lbl}</text>
            {/* Run ID below node */}
            <text x={xi} y={(parseFloat(yi) + NODE_R + 11).toFixed(1)}
              textAnchor="middle" fontSize="7"
              fontFamily="JetBrains Mono, monospace"
              fill="rgba(238,241,246,0.28)" letterSpacing="0.3">
              {run.run_id.replace('QL-RUN-', '')}
            </text>
          </g>
        );
      })}
    </svg>
  );
}


function AtlasLegend() {
  return (
    <div className="atlas-legend" aria-label="Atlas legend">
      <div className="atlas-legend-title">Atlas legend</div>
      <div className="atlas-legend-items">
        {['stable','warning','unstable','reviewed'].map(s => {
          const c = scol(s);
          return (
            <span key={s} className={`atlas-legend-item ${s}`}>
              <i style={{borderColor:c.main, background:c.alpha}}/>
              {s}
            </span>
          );
        })}
      </div>
      <div className="atlas-legend-note">
        Nodes are runs. Color shows derived state. Pulsing rings show unresolved alerts. Dashed amber ring marks the golden reference.
      </div>
    </div>
  );
}


// ============ LEFT PANEL: RUN STATE METRICS ============
function AtlasRunMetrics({ run, goldenRun }) {
  let projectProfile = null;
  try {
    projectProfile = JSON.parse(localStorage.getItem('yagoda_project_profile') || 'null');
  } catch(e) {
    projectProfile = null;
  }

  const projectId = projectProfile?.id || 'quantum';
  const labels =
    projectId === 'engineering'
      ? { experiment:'Simulation', sample:'Model', framework:'Toolchain', sweep:'Parameter set', fidelity:'Output score', showT:false }
    : projectId === 'biomedical'
      ? { experiment:'Analysis', sample:'Dataset', framework:'Toolchain', sweep:'Feature set', fidelity:'Quality score', showT:false }
    : projectId === 'materials'
      ? { experiment:'Workflow', sample:'Sample batch', framework:'Toolchain', sweep:'Process set', fidelity:'Property score', showT:false }
    : projectId === 'chemistry'
      ? { experiment:'Experiment', sample:'Batch', framework:'Toolchain', sweep:'Method set', fidelity:'Yield score', showT:false }
    : projectId === 'earth'
      ? { experiment:'Pipeline', sample:'Dataset', framework:'Toolchain', sweep:'Config set', fidelity:'Output score', showT:false }
    : { experiment:'Experiment', sample:'Sample', framework:'Framework', sweep:'Sweep', fidelity:'Fidelity', showT:true };

  const cal  = run.calibration_metrics_json || {};
  const T1   = cal.T1;
  const T2   = cal.T2;
  const dc   = run.drift_state;
  const statusCls = `arm-status arm-status-${dc === 'regression' ? 'regression' : dc}`;

  return (
    <div className="arm-panel">
      <div className="arm-header">
        <div className="arm-title">Run State</div>
        <span className={statusCls}>{dc}</span>
      </div>
      <div className="arm-rows">
        {[
          { k: 'Active run',  v: run.run_id.replace('QL-RUN-', '#'), mono: true, cyan: true },
          { k: labels.experiment,  v: run.experiment },
          { k: labels.sample,      v: run.sample, mono: true },
          { k: labels.framework,   v: run.framework },
          { k: labels.sweep,       v: run.parameter_sweep },
        ].map(row => (
          <div key={row.k} className="arm-row">
            <div className="arm-key">{row.k}</div>
            <div className={`arm-val${row.mono ? ' arm-mono' : ''}`}
              style={{ color: row.cyan ? 'var(--cyan)' : undefined }}>
              {row.v}
            </div>
          </div>
        ))}
        <div className="arm-divider"/>
        <div className="arm-row">
          <div className="arm-key">Drift</div>
          <div className="arm-val arm-mono" style={{ color: dc==='stable'?'var(--cyan)':dc==='warning'?'var(--amber)':'var(--strawberry)' }}>
            {run.deviation.toFixed(1)}%
          </div>
        </div>
        <div className="arm-row">
          <div className="arm-key">Confidence</div>
          <div className="arm-val arm-mono">{Y.driftConfidence(run.deviation)}%</div>
        </div>
        <div className="arm-row">
          <div className="arm-key">Bench Δ</div>
          <div className="arm-val arm-mono" style={{ color: run.benchmark_delta>=0?'var(--leaf)':'var(--strawberry)' }}>
            {run.benchmark_delta > 0 ? '+' : ''}{run.benchmark_delta}
          </div>
        </div>
        <div className="arm-row">
          <div className="arm-key">{labels.fidelity}</div>
          <div className="arm-val arm-mono">{run.benchmark_current?.toFixed(2)}%</div>
        </div>
        {labels.showT && T1 && <div className="arm-row"><div className="arm-key">T1</div><div className="arm-val arm-mono">{T1.current?.toFixed(1)} µs</div></div>}
        {labels.showT && T2 && <div className="arm-row"><div className="arm-key">T2</div><div className="arm-val arm-mono">{T2.current?.toFixed(1)} µs</div></div>}
        <div className="arm-divider"/>
        <div className="arm-row">
          <div className="arm-key">Instrument</div>
          <Chip kind={run.instrument_state==='captured'?'stable':run.instrument_state==='partial'?'warning':'unstable'}>
            {run.instrument_state}
          </Chip>
        </div>
        <div className="arm-row">
          <div className="arm-key">Snapshot</div>
          <div className="arm-val arm-mono" style={{ color: run.snapshot_completeness>=70?'var(--leaf)':'var(--amber)' }}>
            {run.snapshot_completeness}%
          </div>
        </div>
      </div>
      {goldenRun && (
        <div className="arm-footer">
          <div className="arm-key">Golden run</div>
          <div className="arm-val arm-mono" style={{ color:'var(--amber)', fontSize:9 }}>{goldenRun.run_id}</div>
        </div>
      )}
    </div>
  );
}

// ============ RIGHT PANEL: ALERT STREAM ============
function AtlasAlertStream({ alerts, onAlertClick }) {
  return (
    <div className="aas-panel">
      <div className="aas-header">
        <div className="aas-title">Alert Stream</div>
        <span className="aas-count">{alerts.length} active</span>
      </div>
      <div>
        {alerts.length === 0
          ? <div className="aas-empty">All clear — no active alerts.</div>
          : alerts.slice(0, 7).map(a => (
            <div key={a.id} className={`aas-row aas-sev-${a.severity}`} onClick={() => onAlertClick(a)}>
              <span className={`sev-dot ${a.severity}`}/>
              <div className="aas-body">
                <div className="aas-run">{a.run_id.replace('QL-RUN-', '#')}</div>
                <div className="aas-msg">{a.message.replace(` on ${a.run_id}`, '')}</div>
              </div>
              <div className="aas-ts">{a.created_at.slice(11, 16)}</div>
            </div>
          ))
        }
      </div>
    </div>
  );
}

// ============ RIGHT PANEL: CALIBRATION DRIFT ============
function AtlasCalibration({ run }) {
  const dc   = run.drift_state;
  const conf = Y.driftConfidence(run.deviation);
  const T1   = run.calibration_metrics_json?.T1;
  const color = dc==='stable'?'var(--cyan)':dc==='warning'?'var(--amber)':'var(--strawberry)';
  return (
    <div className="acd-panel">
      <div className="acd-header">
        <div className="acd-title">Calibration Drift</div>
        <Chip kind={dc}>{dc}</Chip>
      </div>
      <div className="acd-body">
        <div className="acd-big" style={{ color }}>{run.deviation.toFixed(1)}<span className="acd-unit">%</span></div>
        <div className="acd-rows">
          <div className="acd-row"><span className="acd-k">Confidence</span><span className="acd-v">{conf}%</span></div>
          <div className="acd-row"><span className="acd-k">Warning thr.</span><span className="acd-v">2.5%</span></div>
          <div className="acd-row"><span className="acd-k">Critical thr.</span><span className="acd-v">3.5%</span></div>
          {T1 && <div className="acd-row"><span className="acd-k">T1 current</span><span className="acd-v">{T1.current?.toFixed(1)} µs</span></div>}
          <div className="acd-row"><span className="acd-k">Run</span><span className="acd-v" style={{color:'var(--cyan)'}}>{run.run_id}</span></div>
        </div>
      </div>
    </div>
  );
}

// ============ RIGHT PANEL: REPRODUCIBILITY SNAPSHOT ============
function AtlasSnapshot({ run, store, generateSnapshot, toast }) {
  const pct     = run.snapshot_completeness;
  const hasSnap = store.snapshots.some(s => s.run_id === run.run_id);
  return (
    <div className="ars-panel">
      <div className="ars-header">
        <div className="ars-title">Reproducibility</div>
        <Chip kind={pct >= 70 ? 'stable' : 'warning'}>{pct}%</Chip>
      </div>
      <div className="ars-body">
        {[
          { k: 'Station snap.',    v: run.station_snapshot_available },
          { k: 'Instrument snap.', v: run.instrument_snapshot_available },
          { k: 'Parameters',       v: true },
          { k: 'Cal. data',        v: !!run.calibration_metrics_json },
          { k: 'Captured',         v: hasSnap },
        ].map(({ k, v }) => (
          <div key={k} className="ars-row">
            <span className="ars-k">{k}</span>
            <span className="ars-v" style={{ color: v?'var(--leaf)':'var(--strawberry)' }}>{v?'✓':'✗'}</span>
          </div>
        ))}
        <button className="btn btn-primary" style={{ width:'100%', justifyContent:'center', marginTop:10, fontSize:9, padding:'6px 10px' }}
          onClick={() => generateSnapshot(run)}>
          {I.snap} Snapshot {run.run_id.replace('QL-RUN-','#')}
        </button>
      </div>
    </div>
  );
}

// ============ BOTTOM DOCK ============
function BottomDock({ selectedRun, goldenRun, comparison, runs, alerts, generateSnapshot, openRun, store, toast }) {
  const changed = useMemo(() => {
    if (!comparison) return [];
    const out = [];
    if (comparison.benchmark_movement !== 0)
      out.push(`Benchmark Δ ${comparison.benchmark_movement>0?'+':''}${comparison.benchmark_movement}% vs golden`);
    if (comparison.calibration_diff.length > 0)
      out.push(`${comparison.calibration_diff.length} calibration parameter(s) shifted`);
    if (comparison.instrument_state.changed)
      out.push(`Instrument state: ${comparison.instrument_state.baseline} → ${comparison.instrument_state.current}`);
    if (selectedRun.snapshot_completeness < 70)
      out.push('Snapshot completeness below threshold');
    if (selectedRun.instrument_state === 'missing')
      out.push('Missing instrument state — reproducibility at risk');
    return out;
  }, [comparison, selectedRun]);

  const pipeline = [
    { label:'Acquiring',  active:true },
    { label:'Processing', active:true },
    { label:'Persisting', active:true },
    { label:'Snapshot',   active:store.snapshots.length > 0 },
    { label:'Alert',      active:alerts.some(a => !a.resolved) },
  ];

  const exportSnap = () => {
    const snap = store.snapshots[store.snapshots.length - 1];
    if (!snap) { toast.push('No snapshot', 'Generate a snapshot first.', 'error'); return; }
    downloadJSON(snap.snapshot_id + '.json', snap);
    toast.push('Exported', `${snap.snapshot_id}.json downloaded`, 'success');
  };

  return (
    <div className="dock">
      {/* Run comparison */}
      <div className="dock-sec">
        <div className="dock-sec-title">Run Comparison</div>
        <div className="dock-cmp-heads">
          <div>
            <span className="dock-cmp-label">Baseline (golden)</span>
            <span className="dock-cmp-id amber">{goldenRun?.run_id?.replace('QL-RUN-','#') || '—'}</span>
          </div>
          <div>
            <span className="dock-cmp-label">Selected</span>
            <span className="dock-cmp-id cyan">{selectedRun.run_id.replace('QL-RUN-','#')}</span>
          </div>
        </div>
        {comparison ? (
          <div className="dock-cmp-rows">
            <div className="dock-cmp-row"><span className="dock-cmp-k">Fidelity</span><span className="dock-cmp-b">{goldenRun?.benchmark_current?.toFixed(2)}%</span><span className="dock-cmp-c">{selectedRun.benchmark_current?.toFixed(2)}%</span></div>
            <div className="dock-cmp-row"><span className="dock-cmp-k">Drift</span><span className="dock-cmp-b">{goldenRun?.deviation?.toFixed(1)}%</span><span className="dock-cmp-c" style={{color:selectedRun.drift_state!=='stable'?'var(--amber)':undefined}}>{selectedRun.deviation?.toFixed(1)}%</span></div>
            <div className="dock-cmp-row"><span className="dock-cmp-k">Bench Δ</span><span className="dock-cmp-b">ref.</span><span className="dock-cmp-c" style={{color:comparison.benchmark_movement<0?'var(--strawberry)':'var(--leaf)'}}>{comparison.benchmark_movement>0?'+':''}{comparison.benchmark_movement}</span></div>
            <div className="dock-cmp-row"><span className="dock-cmp-k">Instrument</span><span className="dock-cmp-b">{goldenRun?.instrument_state}</span><span className="dock-cmp-c">{selectedRun.instrument_state}</span></div>
          </div>
        ) : <div className="dock-empty">Select a run to compare.</div>}
      </div>

      {/* What changed */}
      <div className="dock-sec">
        <div className="dock-sec-title">What Changed</div>
        {changed.length === 0
          ? <div className="dock-empty">{comparison ? 'No significant changes vs golden run.' : 'No golden run available.'}</div>
          : changed.map((c, i) => (
            <div key={i} className="dock-change">
              <span className="dock-change-dot" style={{color:'var(--strawberry)'}}>·</span>
              <span className="dock-change-txt">{c}</span>
            </div>
          ))
        }
        {comparison && comparison.calibration_diff.slice(0, 3).map(d => (
          <div key={d.metric} className="dock-change" style={{opacity:0.7}}>
            <span className="dock-change-dot" style={{color:'var(--cyan)'}}>·</span>
            <span className="dock-change-txt dock-mono">{d.metric}: {d.baseline?.toFixed(3)} → {d.current?.toFixed(3)} {d.unit}</span>
          </div>
        ))}
      </div>

      {/* Data pipeline */}
      <div className="dock-sec">
        <div className="dock-sec-title">Data Pipeline</div>
        <div className="dock-pipeline">
          {pipeline.map((step, i) => (
            <React.Fragment key={step.label}>
              <div className={`dock-pipe-step ${step.active ? 'active' : ''}`}>
                <span className="dock-pipe-dot"/>
                <span>{step.label}</span>
              </div>
              {i < pipeline.length - 1 && <span className="dock-pipe-arr">›</span>}
            </React.Fragment>
          ))}
        </div>
        <div style={{marginTop:10, fontSize:9.5, color:'var(--dim)', fontFamily:'var(--mono)'}}>
          {store.snapshots.length} snapshot{store.snapshots.length!==1?'s':''} captured this session
        </div>
      </div>

      {/* Quick actions */}
      <div className="dock-sec dock-actions-sec">
        <div className="dock-sec-title">Quick Actions</div>
        <div className="dock-actions">
          <button className="btn btn-primary" style={{fontSize:9, padding:'5px 9px'}} onClick={() => generateSnapshot(selectedRun)}>{I.snap} Snapshot</button>
          <button className="btn" style={{fontSize:9, padding:'5px 9px'}} onClick={() => goldenRun && openRun(goldenRun.run_id)}>{I.star} Golden run</button>
          <button className="btn" style={{fontSize:9, padding:'5px 9px'}} onClick={() => openRun(selectedRun.run_id)}>{I.runs} Open run</button>
          <button className="btn btn-ghost" style={{fontSize:9, padding:'5px 9px'}} onClick={exportSnap}>{I.download} Export</button>
        </div>
      </div>
    </div>
  );
}

// ============ OVERVIEW PAGE — QUANTUM STATE ATLAS ============
function OverviewPage({ store, setStore, openRun, generateSnapshot, resetSample }) {
  const toast = useToast();
  const [selectedRunId, setSelectedRunId] = useState(null);

  const runs    = store.runs;
  const alerts  = store.alerts;
  const selectedRun = (selectedRunId ? runs.find(r => r.run_id === selectedRunId) : null) || runs[runs.length - 1];
  const goldenRun   = runs.find(r => r.tags?.includes('golden'));
  const comparison  = goldenRun ? Y.compareRuns(selectedRun, goldenRun) : null;
  const unresolved  = alerts.filter(a => !a.resolved);
  const critCount   = unresolved.filter(a => a.severity === 'critical').length;

  const handleAlertClick = (a) => {
    setSelectedRunId(a.run_id);
    openRun(a.run_id);
  };

  return (
    <div className="atlas-page">
      {/* Status strip */}
      <div className="atlas-strip">
        <div className="astrp-cell">
          <div className="astrp-lbl">Stack</div>
          <div className="astrp-val">Multi-workflow adapter</div>
        </div>
        <div className="astrp-sep"/>
        <div className="astrp-cell">
          <div className="astrp-lbl">Mode</div>
          <div className="astrp-val" style={{color:'var(--amber)'}}>Sample Data</div>
        </div>
        <div className="astrp-sep"/>
        <div className="astrp-cell">
          <div className="astrp-lbl">Workflow</div>
          <div className="astrp-val">Observe → Compare → Snapshot → Review</div>
        </div>
        <div className="astrp-sep"/>
        <div className="astrp-cell">
          <div className="astrp-lbl">Active run</div>
          <div className="astrp-val" style={{fontFamily:'var(--mono)', color:'var(--cyan)', fontSize:11}}>{selectedRun.run_id}</div>
        </div>
        <div className="astrp-sep"/>
        <div className="astrp-cell">
          <div className="astrp-lbl">Health</div>
          <div className="astrp-val" style={{color: critCount>0?'var(--strawberry)':unresolved.length>0?'var(--amber)':'var(--leaf)'}}>
            <span className="astrp-dot" style={{background: critCount>0?'var(--strawberry)':unresolved.length>0?'var(--amber)':'var(--leaf)'}}/>
            {critCount > 0 ? `${critCount} critical` : unresolved.length > 0 ? `${unresolved.length} alerts` : 'Nominal'}
          </div>
        </div>
        <div style={{marginLeft:'auto', display:'flex', gap:8, alignItems:'center'}}>
          <button className="btn btn-ghost" style={{fontSize:9, padding:'5px 9px'}} onClick={resetSample}>{I.reset} Reset</button>
          <button className="btn btn-primary" style={{fontSize:9, padding:'5px 9px'}} onClick={() => generateSnapshot(selectedRun)}>{I.snap} Snapshot</button>
        </div>
      </div>

      <div className="intel-strip">
        <div className="intel-card">
          <div className="k">Operational intelligence</div>
          <strong>Drift likely started before the active run.</strong>
          <span>Compare QL-RUN-0124 and QL-RUN-0127 before promoting this run to reference.</span>
        </div>
        <div className="intel-card">
          <div className="k">Missing context</div>
          <strong>Instrument state is partial.</strong>
          <span>Snapshot is exportable, but the station context needs one review note.</span>
        </div>
        <div className="intel-card">
          <div className="k">Recommended action</div>
          <strong>Capture snapshot, then mark golden only after review.</strong>
          <span>The console should guide the next research action, not only display metrics.</span>
        </div>
      </div>

      {/* 3-column atlas layout */}
      <div className="atlas-main">
        <div className="atlas-left">
          <AtlasRunMetrics run={selectedRun} goldenRun={goldenRun}/>
        </div>
        <div className="atlas-center">
          <div className="atlas-visual-stack">
            <QuantumStateAtlas
              runs={runs}
              alerts={alerts}
              selectedRunId={selectedRun.run_id}
              onSelectRun={setSelectedRunId}
            />
            <AtlasLegend/>
          </div>
        </div>
        <div className="atlas-right">
          <AtlasAlertStream alerts={unresolved} onAlertClick={handleAlertClick}/>
          <AtlasCalibration run={selectedRun}/>
          <AtlasSnapshot run={selectedRun} store={store} generateSnapshot={generateSnapshot} toast={toast}/>
        </div>
      </div>

      {/* Bottom dock */}
      <BottomDock
        selectedRun={selectedRun}
        goldenRun={goldenRun}
        comparison={comparison}
        runs={runs}
        alerts={alerts}
        generateSnapshot={generateSnapshot}
        openRun={openRun}
        store={store}
        toast={toast}
      />
    </div>
  );
}

function Metric({ label, value, unit, trend, trendText }) {
  return (
    <div className="metric">
      <div className="metric-label">{label}</div>
      <div className="metric-value">{value}<span className="metric-unit">{unit}</span></div>
      {(trend||trendText) && <div className={`metric-trend ${trend||'flat'}`}>{trendText || (trend==='up'?'▲':trend==='down'?'▼':'·')}</div>}
    </div>
  );
}

// ============ RUNS ============
function RunsPage({ store, openRun, generateSnapshot }) {
  const [q, setQ] = useState('');
  const [framework, setFramework] = useState('all');
  const [status, setStatus] = useState('all');
  const filtered = useMemo(() => store.runs.filter(r => {
    if (framework!=='all' && r.framework !== framework) return false;
    if (status!=='all' && r.derived_status !== status) return false;
    if (q) {
      const t = q.toLowerCase();
      return [r.run_id,r.experiment,r.sample,r.parameter_sweep,r.dataset_path].some(v => v?.toLowerCase().includes(t));
    }
    return true;
  }), [store.runs, q, framework, status]);

  return (
    <div>
      <div className="page-head">
        <div><h1 className="page-title">Runs</h1><div className="page-sub">{store.runs.length} runs · QCoDeS-style + Quantify-style data</div></div>
      </div>
      <div className="filters">
        <div style={{display:'flex', alignItems:'center', gap:6, background:'var(--elev)', border:'1px solid var(--border-strong)', borderRadius:3, padding:'0 8px'}}>
          {I.search}
          <input className="input" style={{border:'none', background:'transparent', minWidth:220}} placeholder="search runs, samples, paths…" value={q} onChange={e=>setQ(e.target.value)}/>
        </div>
        <select className="select" value={framework} onChange={e=>setFramework(e.target.value)}>
          <option value="all">All frameworks</option>
          <option>QCoDeS</option><option>Quantify</option><option>QCoDeS + Quantify</option>
        </select>
        <select className="select" value={status} onChange={e=>setStatus(e.target.value)}>
          <option value="all">All statuses</option>
          <option value="stable">stable</option><option value="warning">warning</option><option value="unstable">unstable</option><option value="regression">regression</option><option value="reviewed">reviewed</option>
        </select>
        <span style={{fontFamily:'var(--mono)', fontSize:11, color:'var(--muted)', marginLeft:'auto'}}>{filtered.length} of {store.runs.length}</span>
      </div>
      <div className="panel">
        <div className="table-wrap" style={{maxHeight:'calc(100vh - 240px)'}}>
          <table className="runs">
            <thead><tr>
              <th>Run ID</th><th>Framework</th><th>Experiment</th><th>Sample</th><th>Sweep</th><th>Instrument</th><th>Dataset</th><th>Timestamp</th><th>Status</th><th>Bench Δ</th><th>Tags</th><th></th>
            </tr></thead>
            <tbody>
              {filtered.map(r => (
                <tr key={r.run_id} className="row" onClick={()=>openRun(r.run_id)}>
                  <td className="mono" style={{color:'var(--cyan)'}}>{r.run_id}</td>
                  <td className="muted">{r.framework}</td>
                  <td>{r.experiment}</td>
                  <td className="mono">{r.sample}</td>
                  <td className="muted">{r.parameter_sweep}</td>
                  <td><Chip kind={r.instrument_state==='captured'?'stable':r.instrument_state==='partial'?'warning':'unstable'}>{r.instrument_state}</Chip></td>
                  <td className="mono muted" style={{maxWidth:220, overflow:'hidden', textOverflow:'ellipsis'}}>{r.dataset_path}</td>
                  <td className="mono muted">{r.timestamp.replace('T',' ').replace('Z','')}</td>
                  <td><Chip kind={r.derived_status}>{r.derived_status}</Chip></td>
                  <td className="mono" style={{color:r.benchmark_delta<0?'var(--strawberry)':'var(--leaf)'}}>{r.benchmark_delta>0?'+':''}{r.benchmark_delta}</td>
                  <td>{r.tags?.includes('golden') && <Chip kind="golden">★ golden</Chip>}</td>
                  <td onClick={e=>e.stopPropagation()}><button className="btn btn-ghost" style={{padding:'4px 8px', fontSize:10}} onClick={()=>generateSnapshot(r)}>Snapshot</button></td>
                </tr>
              ))}
            </tbody>
          </table>
          {filtered.length===0 && <div className="empty"><div className="empty-icon">∅</div>No runs match the current filters.</div>}
        </div>
      </div>
    </div>
  );
}

// ============ CALIBRATION ============
function CalibrationPage({ store, openRun }) {
  const toast = useToast();
  const runs = store.runs;
  const action = (label) => () => toast.push('Prepared in demo mode', label, 'info');
  const driftWindow = runs.filter(r => r.drift_state !== 'stable');
  const explanation = driftWindow.length > 0
    ? `Signal deviation increased by ${Math.max(...driftWindow.map(r=>r.deviation)).toFixed(1)}% over baseline across ${driftWindow.length} affected runs. The affected window begins after ${runs.find(r=>r.tags?.includes('golden'))?.run_id || runs[0].run_id}. Suggested review: recalibration before next benchmark sequence.`
    : 'All runs in current window are within stable drift bounds. No recalibration suggested.';

  return (
    <div>
      <div className="page-head">
        <div><h1 className="page-title">Calibration</h1><div className="page-sub">Drift map · Calibration timeline · Suggested actions</div></div>
      </div>

      <div className="panel" style={{marginBottom:18}}>
        <div className="panel-head"><div className="panel-title">Drift map</div><span style={{fontFamily:'var(--mono)', fontSize:10, color:'var(--muted)'}}>click a node to open the run</span></div>
        <div className="drift-map">
          {runs.map(r => (
            <div key={r.run_id} className={`drift-node ${r.derived_status}`} onClick={()=>openRun(r.run_id)} title={`${r.run_id} · ${r.deviation}% · ${r.derived_status}`}>
              <div className="id">{r.run_id.replace('QL-RUN-','')}</div>
              <div className="dev">{r.deviation}%</div>
              <div style={{fontSize:9, color:'var(--dim)'}}>{r.framework.split(' ')[0]}</div>
            </div>
          ))}
        </div>
      </div>

      <div className="panel" style={{marginBottom:18}}>
        <div className="panel-head"><div className="panel-title">Calibration timeline · deviation over runs</div></div>
        <div className="panel-body" style={{padding:'12px 8px 4px'}}><DriftChart runs={runs} height={260}/></div>
      </div>

      <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:18}}>
        <div className="panel">
          <div className="panel-head"><div className="panel-title">Drift explanation</div></div>
          <div className="panel-body">
            <p style={{fontSize:13, lineHeight:1.6, margin:0, color:'var(--text)'}}>{explanation}</p>
            <div style={{marginTop:14, fontSize:11, color:'var(--muted)'}}>
              Drift confidence range across affected window: <span style={{color:'var(--text)', fontFamily:'var(--mono)'}}>{driftWindow.length>0?`${Math.min(...driftWindow.map(r=>Y.driftConfidence(r.deviation)))}% – ${Math.max(...driftWindow.map(r=>Y.driftConfidence(r.deviation)))}%`:'—'}</span>
            </div>
          </div>
        </div>
        <div className="panel">
          <div className="panel-head"><div className="panel-title">Suggested actions</div></div>
          <div className="panel-body" style={{display:'flex', flexDirection:'column', gap:8}}>
            <button className="btn" onClick={action('Recalibration window prepared')}>Review recalibration window</button>
            <button className="btn" onClick={action('Stable run comparison prepared')}>Compare with previous stable run</button>
            <button className="btn" onClick={action('Reproducibility snapshot opened')}>Open reproducibility snapshot</button>
            <button className="btn btn-primary" onClick={()=>{
              const report = { generated_at: new Date().toISOString(), affected_runs: driftWindow.map(r=>r.run_id), explanation };
              downloadJSON('drift_report.json', report);
              toast.push('Exported', 'drift_report.json downloaded', 'success');
            }}>{I.download} Export drift report</button>
          </div>
        </div>
      </div>
    </div>
  );
}

// ============ BENCHMARKS ============
function BenchmarksPage({ store }) {
  const runs = store.runs;
  const regressions = runs.filter(r => r.benchmark_status === 'regression');
  return (
    <div>
      <div className="page-head"><div><h1 className="page-title">Benchmarks</h1><div className="page-sub">Fidelity trend · Delta · Regression watch</div></div></div>
      <div className="panel" style={{marginBottom:18}}>
        <div className="panel-head"><div className="panel-title">Fidelity trend</div><span style={{fontFamily:'var(--mono)', fontSize:10, color:'var(--muted)'}}>cyan: current · dashed: previous</span></div>
        <div className="panel-body" style={{padding:'12px 8px 4px'}}><BenchmarkChart runs={runs}/></div>
      </div>
      <div style={{display:'grid', gridTemplateColumns:'1.4fr 1fr', gap:18}}>
        <div className="panel">
          <div className="panel-head"><div className="panel-title">Benchmark delta per run</div></div>
          <div className="panel-body" style={{padding:'12px 8px 4px'}}><BenchmarkDeltaBars runs={runs}/></div>
        </div>
        <div className="panel">
          <div className="panel-head"><div className="panel-title">Regressions ({regressions.length})</div></div>
          {regressions.length===0 ? <div className="empty">No regressions in current window.</div> : regressions.map(r => (
            <div key={r.run_id} className="alert-row">
              <div className="alert-time">{r.timestamp.slice(11,16)}</div>
              <div><span className="ref" style={{fontFamily:'var(--mono)', color:'var(--cyan)'}}>{r.run_id}</span>{' '}{r.experiment}</div>
              <Chip kind="regression">{r.benchmark_delta}</Chip>
            </div>
          ))}
        </div>
      </div>
      <div className="panel" style={{marginTop:18}}>
        <div className="panel-head"><div className="panel-title">Comparison table</div></div>
        <div className="table-wrap">
          <table className="runs">
            <thead><tr><th>Run</th><th>Experiment</th><th>Previous</th><th>Current</th><th>Delta</th><th>Status</th></tr></thead>
            <tbody>{runs.map(r => (
              <tr key={r.run_id}>
                <td className="mono" style={{color:'var(--cyan)'}}>{r.run_id}</td>
                <td>{r.experiment}</td>
                <td className="mono muted">{r.benchmark_previous}</td>
                <td className="mono">{r.benchmark_current}</td>
                <td className="mono" style={{color:r.benchmark_delta<0?'var(--strawberry)':'var(--leaf)'}}>{r.benchmark_delta>0?'+':''}{r.benchmark_delta}</td>
                <td><Chip kind={r.benchmark_status==='regression'?'regression':r.benchmark_status}>{r.benchmark_status}</Chip></td>
              </tr>
            ))}</tbody>
          </table>
        </div>
      </div>
    </div>
  );
}

// ============ SNAPSHOTS ============
function SnapshotsPage({ store, generateSnapshot, openRun }) {
  const toast = useToast();
  const [selected, setSelected] = useState(null);
  const snaps = store.snapshots;
  const sel = snaps.find(s => s.snapshot_id === selected) || snaps[snaps.length-1];

  return (
    <div>
      <div className="page-head"><div><h1 className="page-title">Snapshots</h1><div className="page-sub">Reproducibility · {snaps.length} captured</div></div></div>
      {snaps.length===0 ? (
        <div className="panel"><div className="empty"><div className="empty-icon">◇</div>No snapshots yet. Open a run and click <strong style={{color:'var(--text)'}}>Generate snapshot</strong>.</div></div>
      ) : (
        <div style={{display:'grid', gridTemplateColumns:'1fr 1.2fr', gap:18}}>
          <div>
            {snaps.map(s => (
              <div key={s.snapshot_id} className="snap-card" style={{borderColor: sel?.snapshot_id===s.snapshot_id?'var(--strawberry)':'var(--border)'}} onClick={()=>setSelected(s.snapshot_id)}>
                <div className="snap-card-head">
                  <div className="snap-card-title" style={{color:'var(--cyan)'}}>{s.snapshot_id}</div>
                  <Chip kind={s.snapshot_completeness>=70?'stable':'warning'}>{s.snapshot_completeness}%</Chip>
                </div>
                <div className="snap-fields">
                  <div>run</div><div className="v">{s.run_id}</div>
                  <div>framework</div><div className="v">{s.framework}</div>
                  <div>calibration</div><div className="v">{s.calibration_state}</div>
                  <div>benchmark</div><div className="v">{s.benchmark_state}</div>
                </div>
              </div>
            ))}
          </div>
          {sel && (
            <div className="panel">
              <div className="panel-head">
                <div className="panel-title">{sel.snapshot_id}</div>
                <div style={{display:'flex', gap:6}}>
                  <button className="btn btn-ghost" onClick={()=>openRun(sel.run_id)}>Open run</button>
                  <button className="btn btn-primary" onClick={()=>{ downloadJSON(sel.snapshot_id+'.json', sel); toast.push('Exported', `${sel.snapshot_id}.json downloaded`, 'success'); }}>{I.download} Export JSON</button>
                </div>
              </div>
              <div className="panel-body"><JsonView data={sel} max={620}/></div>
            </div>
          )}
        </div>
      )}
    </div>
  );
}

// ============ ALERTS ============
function AlertsPage({ store, setStore, openRun }) {
  const [filter, setFilter] = useState('all');
  const alerts = store.alerts.filter(a => filter==='all' || a.severity===filter);
  const toggle = (id) => {
    setStore(s => ({ ...s, alerts: s.alerts.map(a => a.id===id ? {...a, resolved: !a.resolved} : a) }));
  };
  return (
    <div>
      <div className="page-head">
        <div><h1 className="page-title">Alerts</h1><div className="page-sub">{store.alerts.length} generated · rule-based</div></div>
        <div className="page-actions">
          {['all','info','warning','critical'].map(f => (
            <button key={f} className={`btn ${filter===f?'btn-primary':'btn-ghost'}`} onClick={()=>setFilter(f)}>{f}</button>
          ))}
        </div>
      </div>
      {alerts.length===0 ? <div className="panel"><div className="empty">No alerts.</div></div> : (
        <div className="panel">
          {alerts.map(a => (
            <div key={a.id} className="alert-row" style={{gridTemplateColumns:'auto 90px 1fr auto auto', opacity:a.resolved?0.5:1}}>
              <span className={`sev-dot ${a.severity}`}/>
              <div className="alert-time" style={{fontFamily:'var(--mono)'}}>{a.created_at.slice(11,16)}</div>
              <div>
                <div style={{fontSize:12}}><span className="ref" style={{fontFamily:'var(--mono)', color:'var(--cyan)', marginRight:6}}>{a.run_id}</span>{a.message}</div>
                <div style={{fontSize:11, color:'var(--muted)', marginTop:2}}>{a.explanation}</div>
                <div style={{fontSize:11, color:'var(--dim)', marginTop:2, fontStyle:'italic'}}>→ {a.recommended_action}</div>
              </div>
              <Chip kind={a.severity==='critical'?'unstable':a.severity==='warning'?'warning':'info'}>{a.severity}</Chip>
              <div style={{display:'flex', gap:6}}>
                <button className="btn btn-ghost" onClick={()=>openRun(a.run_id)}>Open</button>
                <button className="btn btn-ghost" onClick={()=>toggle(a.id)}>{a.resolved?'Reopen':'Resolve'}</button>
              </div>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

window.YPages1 = { OverviewPage, RunsPage, CalibrationPage, BenchmarksPage, SnapshotsPage, AlertsPage };
