/* global React, ReactDOM, Recharts */
const { useState, useEffect, useMemo, useRef, useCallback } = React;
const Y = window.YagodaStore;

// ---------- Toast system ----------
let _toastId = 0;
const ToastCtx = React.createContext({ push: () => {} });
function ToastProvider({ children }) {
  const [items, setItems] = useState([]);
  const push = useCallback((title, msg, kind='info') => {
    const id = ++_toastId;
    setItems(prev => [...prev, { id, title, msg, kind }]);
    setTimeout(() => setItems(prev => prev.filter(t => t.id !== id)), 4200);
  }, []);
  return (
    <ToastCtx.Provider value={{ push }}>
      {children}
      <div className="toast-wrap">
        {items.map(t => (
          <div key={t.id} className={`toast ${t.kind}`}>
            <div style={{flex:1}}>
              <div className="toast-title">{t.title}</div>
              <div>{t.msg}</div>
            </div>
          </div>
        ))}
      </div>
    </ToastCtx.Provider>
  );
}
const useToast = () => React.useContext(ToastCtx);

// ---------- Icons (thin-line, serious) ----------
const Icon = ({ d, size=14 }) => (
  <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="nav-icon">{d}</svg>
);
const I = {
  overview: <Icon d={<><rect x="3" y="3" width="7" height="9"/><rect x="14" y="3" width="7" height="5"/><rect x="14" y="12" width="7" height="9"/><rect x="3" y="16" width="7" height="5"/></>}/>,
  runs: <Icon d={<><path d="M3 6h18"/><path d="M3 12h18"/><path d="M3 18h18"/></>}/>,
  cal: <Icon d={<><path d="M3 18l5-8 4 5 4-9 5 12"/></>}/>,
  bench: <Icon d={<><path d="M4 20V10"/><path d="M10 20V4"/><path d="M16 20v-7"/><path d="M22 20H2"/></>}/>,
  snap: <Icon d={<><rect x="3" y="6" width="18" height="13" rx="1"/><circle cx="12" cy="12.5" r="3.5"/><path d="M8 6l1.5-2h5L16 6"/></>}/>,
  alert: <Icon d={<><path d="M12 3l10 17H2L12 3z"/><path d="M12 10v4"/><circle cx="12" cy="17" r="0.6" fill="currentColor"/></>}/>,
  set: <Icon d={<><circle cx="12" cy="12" r="3"/><path d="M19 12a7 7 0 0 0-.1-1.2l2-1.6-2-3.4-2.4.9a7 7 0 0 0-2-1.2L14 3h-4l-.5 2.5a7 7 0 0 0-2 1.2l-2.4-.9-2 3.4 2 1.6A7 7 0 0 0 5 12a7 7 0 0 0 .1 1.2l-2 1.6 2 3.4 2.4-.9a7 7 0 0 0 2 1.2L10 21h4l.5-2.5a7 7 0 0 0 2-1.2l2.4.9 2-3.4-2-1.6c.07-.4.1-.8.1-1.2z"/></>}/>,
  download: <Icon d={<><path d="M12 3v12"/><path d="M7 10l5 5 5-5"/><path d="M4 21h16"/></>}/>,
  upload: <Icon d={<><path d="M12 21V9"/><path d="M7 14l5-5 5 5"/><path d="M4 3h16"/></>}/>,
  reset: <Icon d={<><path d="M3 12a9 9 0 1 0 3-6.7"/><path d="M3 4v5h5"/></>}/>,
  search: <Icon d={<><circle cx="11" cy="11" r="7"/><path d="M21 21l-4.5-4.5"/></>}/>,
  close: <Icon d={<><path d="M5 5l14 14"/><path d="M19 5L5 19"/></>}/>,
  star: <Icon d={<><path d="M12 3l2.5 6 6.5.6-5 4.5 1.5 6.4L12 17l-5.5 3.5 1.5-6.4-5-4.5L9.5 9z"/></>}/>,
};

// ---------- Status chip ----------
function Chip({ kind, children }) { return <span className={`chip ${kind||''}`}>{kind && <span className="chip-dot"/>}{children || kind}</span>; }

// ---------- JSON viewer with light syntax coloring ----------
function JsonView({ data, max=520 }) {
  const txt = useMemo(() => JSON.stringify(data, null, 2), [data]);
  const html = useMemo(() => {
    return txt
      .replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;')
      .replace(/("(?:\\.|[^"\\])*")(\s*:)/g, '<span class="k">$1</span>$2')
      .replace(/:\s*("(?:\\.|[^"\\])*")/g, ': <span class="s">$1</span>')
      .replace(/:\s*(-?\d+(?:\.\d+)?)/g, ': <span class="n">$1</span>')
      .replace(/:\s*(true|false|null)/g, ': <span class="b">$1</span>');
  }, [txt]);
  return <pre className="json-view" style={{maxHeight: max}} dangerouslySetInnerHTML={{__html: html}}/>;
}

// ---------- Topbar ----------
function TopBar({ store, lastSync }) {
  const [now, setNow] = useState(new Date());
  useEffect(() => { const i = setInterval(()=>setNow(new Date()), 1000); return ()=>clearInterval(i); }, []);
  const lastRun = store?.runs?.[store.runs.length - 1];
  const unresCrit = (store?.alerts || []).filter(a => !a.resolved && a.severity === 'critical').length;
  const health = unresCrit > 0 ? 'critical' : (store?.alerts || []).some(a => !a.resolved) ? 'warning' : 'nominal';
  return (
    <div className="topbar">
      <div className="topbar-cluster">
        <div className="topbar-item"><span className="label">Stack</span><span className="val">Multi-workflow</span></div>
        <div className="topbar-divider"/>
        <div className="topbar-item"><span className="label">Adapter mode</span><span className="val" style={{color:'var(--amber)'}}>Sample Data</span></div>
        <div className="topbar-divider"/>
        <div className="topbar-item"><span className="label">Data</span><span className="val" style={{color:'var(--leaf)'}}>● Local</span></div>
        <div className="topbar-divider"/>
        {lastRun && <><div className="topbar-item"><span className="label">Last run</span><span className="val" style={{fontFamily:'var(--mono)', color:'var(--cyan)', fontSize:11}}>{lastRun.run_id}</span></div><div className="topbar-divider"/></>}
        <div className="topbar-item">
          <span className="label">Health</span>
          <span className="val" style={{color: health==='critical'?'var(--strawberry)':health==='warning'?'var(--amber)':'var(--leaf)'}}>
            {health==='critical'?`${unresCrit} critical`:health==='warning'?'alerts active':'Nominal'}
          </span>
        </div>
        <div className="topbar-divider"/>
        <div className="topbar-item"><span className="label">Last sync</span><span className="val">{new Date(lastSync).toLocaleTimeString([],{hour12:false})}</span></div>
      </div>
      <div className="topbar-spacer"/>
      <div className="topbar-rt"><span className="dot"/>{now.toISOString().slice(11,19)} UTC</div>
    </div>
  );
}

// ---------- Sidebar ----------
function Sidebar({ page, setPage, alertCount, lastRun }) {
  const items = [
    { id:'overview',    label:'Overview',    icon:I.overview },
    { id:'runs',        label:'Runs',        icon:I.runs },
    { id:'calibration', label:'Calibration', icon:I.cal },
    { id:'benchmarks',  label:'Benchmarks',  icon:I.bench },
    { id:'snapshots',   label:'Snapshots',   icon:I.snap },
    { id:'alerts',      label:'Alerts',      icon:I.alert, badge: alertCount },
    { id:'settings',    label:'Settings',    icon:I.set },
  ];
  return (
    <aside className="sidebar">
      <div className="brand">
        <a className="brand-parent" href="https://quantumlog.eu" target="_blank" rel="noreferrer" title="QuantumLog · quantumlog.eu">
          <img className="brand-parent-wordmark" src="assets/quantumlog-wordmark.png" alt="QuantumLog"/>
        </a>
        <div className="brand-product">
          <div className="brand-mark"><img src="assets/yagoda-icon.png" alt="Yagoda"/></div>
          <div>
            <div className="brand-name">Yagoda</div>
            <div className="brand-sub">Lab Console</div>
          </div>
          <span className="brand-version">v0.1</span>
        </div>
      </div>
      <nav className="nav">
        {items.map(it => (
          <button key={it.id} className={`nav-item ${page===it.id?'active':''}`} onClick={() => setPage(it.id)} style={{position:'relative'}}>
            {it.icon}
            <span>{it.label}</span>
            {it.badge>0 && <span className="nav-badge">{it.badge}</span>}
          </button>
        ))}
      </nav>
      {/* System state info block */}
      {lastRun && (
        <div className="sidebar-sysinfo">
          <div className="sysinfo-row">
            <span className="sysinfo-k">Stack</span>
            <span className="sysinfo-v">Multi-workflow</span>
          </div>
          <div className="sysinfo-row">
            <span className="sysinfo-k">Mode</span>
            <span className="sysinfo-v amber">Sample Data</span>
          </div>
          <div className="sysinfo-row">
            <span className="sysinfo-k">Active run</span>
            <span className="sysinfo-v cyan">{lastRun.run_id.replace('QL-RUN-','#')}</span>
          </div>
          <div className="sysinfo-row">
            <span className="sysinfo-k">Workflow</span>
            <span className="sysinfo-v">{lastRun.framework}</span>
          </div>
        </div>
      )}
      <div className="sidebar-foot">
        <span className="local-badge"><span className="local-dot"/>Local-first · online</span>
        <span className="foot-meta">v0.1.0 · data stays in lab</span>
      </div>
    </aside>
  );
}

// ---------- Drift / Benchmark charts ----------
const { LineChart, Line, AreaChart, Area, XAxis, YAxis, Tooltip, ReferenceArea, ReferenceLine, ResponsiveContainer, CartesianGrid, BarChart, Bar, Cell } = Recharts;

function DriftChart({ runs, height=280 }) {
  const data = runs.map(r => ({ name: r.run_id.replace('QL-RUN-',''), full: r.run_id, deviation: r.deviation, fidelity: r.benchmark_current, state: r.drift_state }));
  return (
    <ResponsiveContainer width="100%" height={height}>
      <AreaChart data={data} margin={{top: 10, right: 16, left: 0, bottom: 0}}>
        <defs>
          <linearGradient id="gDrift" x1="0" y1="0" x2="0" y2="1">
            <stop offset="0%" stopColor="#FF4D6D" stopOpacity={0.4}/>
            <stop offset="100%" stopColor="#FF4D6D" stopOpacity={0}/>
          </linearGradient>
        </defs>
        <CartesianGrid stroke="rgba(255,255,255,0.04)" vertical={false}/>
        <XAxis dataKey="name" stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}}/>
        <YAxis stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}} unit="%"/>
        <Tooltip contentStyle={{background:'#0B0E14', border:'1px solid rgba(255,255,255,0.14)', fontFamily:'JetBrains Mono', fontSize:11}} labelFormatter={(v,p)=>p[0]?.payload?.full||v} formatter={(val, key, obj) => key==='deviation' ? [`${val}% · ${obj.payload.state}`,'deviation'] : [val, key]}/>
        <ReferenceArea y1={1.5} y2={3.5} fill="#F5C56B" fillOpacity={0.06} stroke="rgba(245,197,107,0.2)"/>
        <ReferenceArea y1={3.5} y2={6} fill="#FF4D6D" fillOpacity={0.07} stroke="rgba(255,77,109,0.2)"/>
        <ReferenceLine y={1.5} stroke="rgba(245,197,107,0.4)" strokeDasharray="3 3"/>
        <ReferenceLine y={3.5} stroke="rgba(255,77,109,0.4)" strokeDasharray="3 3"/>
        <Area type="monotone" dataKey="deviation" stroke="#FF4D6D" strokeWidth={1.5} fill="url(#gDrift)" dot={{r:3, fill:'#FF4D6D', stroke:'#0B0E14', strokeWidth:1.5}} activeDot={{r:5, stroke:'#FF6B8A', strokeWidth:2}}/>
      </AreaChart>
    </ResponsiveContainer>
  );
}

function BenchmarkChart({ runs, height=240 }) {
  const data = runs.map(r => ({ name: r.run_id.replace('QL-RUN-',''), full: r.run_id, fidelity: r.benchmark_current, prev: r.benchmark_previous, delta: r.benchmark_delta }));
  return (
    <ResponsiveContainer width="100%" height={height}>
      <LineChart data={data} margin={{top: 10, right: 16, left: 0, bottom: 0}}>
        <CartesianGrid stroke="rgba(255,255,255,0.04)" vertical={false}/>
        <XAxis dataKey="name" stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}}/>
        <YAxis stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}} unit="%" domain={['auto','auto']}/>
        <Tooltip contentStyle={{background:'#0B0E14', border:'1px solid rgba(255,255,255,0.14)', fontFamily:'JetBrains Mono', fontSize:11}} labelFormatter={(v,p)=>p[0]?.payload?.full||v}/>
        <Line type="monotone" dataKey="fidelity" stroke="#76E4F7" strokeWidth={1.5} dot={{r:3, fill:'#76E4F7', stroke:'#0B0E14', strokeWidth:1.5}}/>
        <Line type="monotone" dataKey="prev" stroke="rgba(243,245,248,0.3)" strokeDasharray="3 3" strokeWidth={1} dot={false}/>
      </LineChart>
    </ResponsiveContainer>
  );
}

function BenchmarkDeltaBars({ runs, height=200 }) {
  const data = runs.map(r => ({ name: r.run_id.replace('QL-RUN-',''), full: r.run_id, delta: r.benchmark_delta, status: r.benchmark_status }));
  return (
    <ResponsiveContainer width="100%" height={height}>
      <BarChart data={data} margin={{top: 10, right: 16, left: 0, bottom: 0}}>
        <CartesianGrid stroke="rgba(255,255,255,0.04)" vertical={false}/>
        <XAxis dataKey="name" stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}}/>
        <YAxis stroke="rgba(243,245,248,0.45)" fontSize={10} tick={{fontFamily:'JetBrains Mono'}}/>
        <Tooltip contentStyle={{background:'#0B0E14', border:'1px solid rgba(255,255,255,0.14)', fontFamily:'JetBrains Mono', fontSize:11}} labelFormatter={(v,p)=>p[0]?.payload?.full||v}/>
        <ReferenceLine y={0} stroke="rgba(255,255,255,0.2)"/>
        <Bar dataKey="delta">
          {data.map((d, i) => <Cell key={i} fill={d.status==='regression'?'#FF4D6D':d.status==='warning'?'#F5C56B':'#A7F06D'}/>)}
        </Bar>
      </BarChart>
    </ResponsiveContainer>
  );
}

window.YComps = { ToastProvider, useToast, Chip, JsonView, TopBar, Sidebar, DriftChart, BenchmarkChart, BenchmarkDeltaBars, I, Icon };
