const { useState, useEffect, useRef } = React;

/* ─── CONFIG ─────────────────────────────────────────────────────────────── */
const API_URL = "";   // Same-origin API in production

/* ─── STATIC DATA ────────────────────────────────────────────────────────── */
const STORES  = ["S1","S2","S3","S4","S5","S6","S7","S8","S9","S10","S11","S12","S13","S14","S15","S16","S17","S18","S19","S20"];
const WEATHER = ["Low","Medium","High"];
const PRODUCTS= ["P1001","P1006","P1008","P1009","P1012","P1014","P1016","P1018","P1019","P1020","P1021","P1022","P1024","P1025","P1026","P1027","P1028","P1029","P1030","P1031","P1032","P1034","P1035","P1036","P1038","P1039","P1040","P1041","P1042","P1043","P1044","P1046","P1047","P1048","P1049","P1051","P1052","P1053","P1055","P1056","P1058","P1059","P1060","P1061","P1062","P1065","P1066","P1067","P1068","P1069","P1070","P1071","P1074","P1075","P1078","P1079","P1080","P1081","P1082","P1084","P1085","P1086","P1087","P1088","P1089","P1091","P1092","P1093","P1094","P1097","P1098","P1099","P1100","P1101","P1102","P1104","P1105","P1106","P1107","P1109","P1110","P1112","P1113","P1114","P1115","P1116","P1119","P1120","P1200","P1250","P1300","P1350","P1400","P1450","P1500","P1550","P1600","P1650","P1700","P1750","P1800","P1850","P1900","P1950","P2000","P2050","P2100","P2150","P2200","P2250","P2300","P2350","P2400","P2450","P2500","P2550","P2600","P2650","P2700","P2750","P2800","P2850","P2900","P2950","P3000","P3050","P3100","P3150","P3200","P3250","P3300","P3350","P3400","P3450","P3500","P3550","P3600","P3650","P3700","P3750","P3799"];

/* ─── COLOUR HELPERS ─────────────────────────────────────────────────────── */
const rc  = r => r > 65 ? "#ff6b6b" : r > 40 ? "#ffaa3b" : "#3ecf8e";
const rb  = r => r > 65 ? "rgba(255,107,107,.13)" : r > 40 ? "rgba(255,170,59,.13)" : "rgba(62,207,142,.13)";
const rl  = r => r > 65 ? "Critical" : r > 40 ? "Moderate" : "Healthy";

/* ─── SEEDED RNG (for deterministic demo data) ───────────────────────────── */
function seedRng(seed) {
  let s = seed;
  return () => { s = (s * 1664525 + 1013904223) & 0xffffffff; return (s >>> 0) / 0xffffffff; };
}

/* ─── DEMO PRODUCTS (dashboard / products tab) ───────────────────────────── */
function genProducts() {
  return Array.from({ length: 40 }, (_, i) => {
    const rng = seedRng(i * 137 + 42);
    const stock = Math.floor(rng() * 280) + 20;
    const demand = Math.floor(rng() * 130) + 30;
    const lead = Math.floor(rng() * 12) + 3;
    const reliability = Math.floor(rng() * 50) + 50;
    const promo = rng() > 0.6;
    const weather = WEATHER[Math.floor(rng() * 3)];
    const store = STORES[Math.floor(rng() * STORES.length)];
    const dos = stock / demand;
    let risk = 0;
    if (dos < lead) risk += 40; else if (dos < lead * 1.5) risk += 20;
    if (reliability < 60) risk += 20; else if (reliability < 75) risk += 10;
    if (promo) risk += 15;
    if (weather === "High") risk += 15; else if (weather === "Medium") risk += 7;
    risk = Math.min(95, Math.max(5, risk + Math.floor((rng() - .5) * 20)));
    return { id: PRODUCTS[i % PRODUCTS.length], store, stock, demand, lead, reliability, promo, weather, risk, predicted: risk > 45 ? "Yes" : "No" };
  });
}
const DEMO_PRODUCTS = genProducts();

/* ─── ANIMATED COUNTER ───────────────────────────────────────────────────── */
function Counter({ to, suffix = "" }) {
  const [val, setVal] = useState(0);
  useEffect(() => {
    let start = 0, raf;
    const step = ts => {
      if (!start) start = ts;
      const p = Math.min((ts - start) / 1100, 1);
      setVal(Math.floor(p * p * (3 - 2 * p) * to));
      if (p < 1) raf = requestAnimationFrame(step); else setVal(to);
    };
    raf = requestAnimationFrame(step);
    return () => cancelAnimationFrame(raf);
  }, [to]);
  return <>{val}{suffix}</>;
}

/* ─── SPARKLINE ──────────────────────────────────────────────────────────── */
function Sparkline({ data, color = "#3ecf8e" }) {
  const w = 80, h = 30;
  const mn = Math.min(...data), mx = Math.max(...data), rng = mx - mn || 1;
  const pts = data.map((v, i) => [i * (w / (data.length - 1)), h - ((v - mn) / rng) * h * 0.85 - h * 0.075]);
  const d = "M" + pts.map(p => p.join(",")).join(" L");
  const area = d + ` L${pts[pts.length - 1][0]},${h} L${pts[0][0]},${h} Z`;
  const id = `sg${color.replace("#", "")}`;
  return (
    <svg width={w} height={h} viewBox={`0 0 ${w} ${h}`}>
      <defs>
        <linearGradient id={id} x1="0" y1="0" x2="0" y2="1">
          <stop offset="0%" stopColor={color} stopOpacity=".25" />
          <stop offset="100%" stopColor={color} stopOpacity="0" />
        </linearGradient>
      </defs>
      <path d={area} fill={`url(#${id})`} />
      <path d={d} fill="none" stroke={color} strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" />
      <circle cx={pts[pts.length - 1][0]} cy={pts[pts.length - 1][1]} r="2.5" fill={color} />
    </svg>
  );
}

/* ─── GAUGE ──────────────────────────────────────────────────────────────── */
function Gauge({ score }) {
  const [anim, setAnim] = useState(0);
  useEffect(() => { const t = setTimeout(() => setAnim(score), 80); return () => clearTimeout(t); }, [score]);
  const r = 52, cx = 64, cy = 68, sw = 9;
  const toXY = pct => { const a = -Math.PI * .8 + Math.PI * 1.6 * pct; return [cx + r * Math.cos(a), cy + r * Math.sin(a)]; };
  const arcPath = pct => {
    const [x1, y1] = toXY(0), [x2, y2] = toXY(Math.max(.001, pct));
    return `M${x1},${y1} A${r},${r},0,${pct > .5 ? 1 : 0},1,${x2},${y2}`;
  };
  const [nx, ny] = toXY(anim / 100);
  const color = rc(score);
  return (
    <svg width="128" height="100" viewBox="0 0 128 100">
      <defs>
        <linearGradient id="gg" x1="0%" y1="0%" x2="100%" y2="0%">
          <stop offset="0%" stopColor="#3ecf8e" /><stop offset="50%" stopColor="#ffaa3b" /><stop offset="100%" stopColor="#ff6b6b" />
        </linearGradient>
        <filter id="gf"><feGaussianBlur stdDeviation="2.5" result="b" /><feMerge><feMergeNode in="b" /><feMergeNode in="SourceGraphic" /></feMerge></filter>
      </defs>
      <path d={arcPath(1)} fill="none" stroke="rgba(255,255,255,.07)" strokeWidth={sw} strokeLinecap="round" />
      <path d={arcPath(anim / 100)} fill="none" stroke="url(#gg)" strokeWidth={sw} strokeLinecap="round" filter="url(#gf)" style={{ transition: "d 1.1s cubic-bezier(.34,1.2,.64,1)" }} />
      <circle cx={nx} cy={ny} r={sw / 2 + 1} fill={color} filter="url(#gf)" style={{ transition: "cx 1.1s cubic-bezier(.34,1.2,.64,1),cy 1.1s cubic-bezier(.34,1.2,.64,1)" }} />
      <text x={cx} y={cy + 6} textAnchor="middle" fill={color} fontSize="24" fontWeight="700" fontFamily="'Space Mono',monospace" style={{ transition: "fill .5s" }}>{anim}</text>
      <text x={cx} y={cy + 20} textAnchor="middle" fill="rgba(255,255,255,.3)" fontSize="8.5" fontFamily="'Sora',sans-serif" letterSpacing="2.5">RISK %</text>
    </svg>
  );
}

/* ─── TOGGLE ─────────────────────────────────────────────────────────────── */
function Toggle({ value, onChange }) {
  const on = value === "Yes";
  return (
    <div onClick={() => onChange(on ? "No" : "Yes")}
      style={{ width: 46, height: 26, borderRadius: 13, background: on ? "#3ecf8e" : "rgba(255,255,255,.08)", cursor: "pointer", position: "relative", transition: "background .25s", border: `1px solid ${on ? "#3ecf8e" : "rgba(255,255,255,.12)"}` }}>
      <div style={{ position: "absolute", top: 3, left: on ? 22 : 3, width: 18, height: 18, borderRadius: 9, background: "#fff", transition: "left .25s ease", boxShadow: "0 2px 6px rgba(0,0,0,.4)" }} />
    </div>
  );
}

/* ─── SLIDER ─────────────────────────────────────────────────────────────── */
function SliderField({ label, value, min, max, step = 1, unit = "", onChange, color = "#a78bfa" }) {
  const pct = ((value - min) / (max - min)) * 100;
  return (
    <div style={{ marginBottom: 22 }}>
      <div style={{ display: "flex", justifyContent: "space-between", alignItems: "baseline", marginBottom: 10 }}>
        <span style={{ fontSize: 10, color: "rgba(255,255,255,.38)", letterSpacing: ".09em", textTransform: "uppercase" }}>{label}</span>
        <span style={{ fontSize: 16, fontWeight: 700, color: "#fff", fontFamily: "'Space Mono',monospace" }}>{value}<span style={{ fontSize: 11, color: "rgba(255,255,255,.4)", fontWeight: 400 }}>{unit}</span></span>
      </div>
      <div style={{ position: "relative", height: 6, background: "rgba(255,255,255,.07)", borderRadius: 3 }}>
        <div style={{ position: "absolute", inset: 0, borderRadius: 3, width: pct + "%", background: `linear-gradient(90deg,${color}55,${color})`, transition: "width .08s" }} />
        <div style={{ position: "absolute", top: "50%", left: pct + "%", transform: "translate(-50%,-50%)", width: 16, height: 16, borderRadius: 8, background: "#1e1e30", border: `2.5px solid ${color}`, pointerEvents: "none", transition: "left .08s", boxShadow: `0 0 10px ${color}55,0 2px 4px rgba(0,0,0,.5)` }} />
        <input type="range" min={min} max={max} step={step} value={value} onChange={e => onChange(+e.target.value)}
          style={{ position: "absolute", top: "50%", left: 0, transform: "translateY(-50%)", width: "100%", height: 24, opacity: 0, cursor: "pointer", margin: 0 }} />
      </div>
    </div>
  );
}

/* ─── CONNECTION STATUS BADGE ─────────────────────────────────────────────── */
function StatusBadge({ status }) {
  const cfg = {
    connected:    { color: "#3ecf8e", label: "API connected",    dot: "pulse" },
    disconnected: { color: "#ff6b6b", label: "API offline",      dot: "blink" },
    checking:     { color: "#ffaa3b", label: "Checking API…",    dot: "spin"  },
  }[status] || { color: "#888", label: "Unknown", dot: "" };
  return (
    <div style={{ display: "flex", alignItems: "center", gap: 6 }}>
      <div style={{ width: 7, height: 7, borderRadius: "50%", background: cfg.color, animation: cfg.dot === "pulse" ? "pulse 2.4s ease-in-out infinite" : cfg.dot === "blink" ? "blink 1s step-end infinite" : "spin .9s linear infinite", border: cfg.dot === "spin" ? `2px solid ${cfg.color}44` : "none", borderTopColor: cfg.dot === "spin" ? cfg.color : undefined }} />
      <span style={{ fontSize: 11, color: cfg.color, fontWeight: 500 }}>{cfg.label}</span>
    </div>
  );
}

/* ─── APP ────────────────────────────────────────────────────────────────── */
function App() {
  const [tab, setTab]         = useState("dashboard");
  const [products]            = useState(DEMO_PRODUCTS);
  const [filter, setFilter]   = useState("All");
  const [sort, setSort]       = useState({ col: "risk", dir: -1 });
  const [apiStatus, setApiStatus] = useState("checking");

  const [form, setForm] = useState({
    product_id: "P1009", store_id: "S11", current_stock: 231,
    daily_demand: 29, lead_time_days: 12, supplier_reliability_score: 91,
    promotion_active: "No", weather_impact: "High", month: 6, day_of_week: 3, day: 15,
  });
  const [result, setResult]   = useState(null);
  const [loading, setLoading] = useState(false);
  const [loadMsg, setLoadMsg] = useState("");
  const [history, setHistory] = useState([]);

  /* ── Check API health on mount ── */
  useEffect(() => {
    setApiStatus("checking");
    fetch(`${API_URL}/health`, { signal: AbortSignal.timeout(4000) })
      .then(r => r.ok ? setApiStatus("connected") : setApiStatus("disconnected"))
      .catch(() => setApiStatus("disconnected"));
  }, []);

  /* ── KPIs ── */
  const stockouts    = products.filter(p => p.predicted === "Yes").length;
  const highRisk     = products.filter(p => p.risk > 65).length;
  const avgRisk      = Math.round(products.reduce((s, p) => s + p.risk, 0) / products.length);
  const avgRel       = Math.round(products.reduce((s, p) => s + p.reliability, 0) / products.length);

  /* ── Store chart data ── */
  const storeMap = {};
  products.forEach(p => { if (!storeMap[p.store]) storeMap[p.store] = { t: 0, n: 0 }; storeMap[p.store].t += p.risk; storeMap[p.store].n++; });
  const storeData = Object.entries(storeMap).map(([s, v]) => ({ store: s, avg: Math.round(v.t / v.n) })).sort((a, b) => b.avg - a.avg);

  /* ── Spark data ── */
  const spark = seed => { const r = seedRng(seed); return Array.from({ length: 8 }, () => 15 + r() * 70); };

  /* ── Sort/filter products ── */
  const filtered = [...products]
    .filter(p => filter === "All" || (filter === "High" && p.risk > 65) || (filter === "Medium" && p.risk > 40 && p.risk <= 65) || (filter === "Low" && p.risk <= 40))
    .sort((a, b) => { const v = String(a[sort.col]) < String(b[sort.col]) ? -1 : 1; return v * sort.dir; });
  const toggleSort = col => setSort(s => ({ col, dir: s.col === col ? -s.dir : 1 }));
  const set = k => v => setForm(p => ({ ...p, [k]: v }));

  /* ── Call Flask API ── */
  const LOAD_MSGS = ["Encoding features…", "Running LightGBM trees…", "Computing sigmoid output…", "Assembling result…"];

  async function runPrediction() {
    setLoading(true); setResult(null);
    let mi = 0; setLoadMsg(LOAD_MSGS[0]);
    const iv = setInterval(() => { mi = Math.min(mi + 1, LOAD_MSGS.length - 1); setLoadMsg(LOAD_MSGS[mi]); }, 600);

    try {
      const payload = {
        product_id:                 form.product_id,
        store_id:                   form.store_id,
        promotion_active:           form.promotion_active,
        weather_impact:             form.weather_impact,
        current_stock:              form.current_stock,
        daily_demand:               form.daily_demand,
        lead_time_days:             form.lead_time_days,
        supplier_reliability_score: form.supplier_reliability_score,
        month:                      form.month,
        day_of_week:                form.day_of_week,
        day:                        form.day,
      };

      const resp = await fetch(`${API_URL}/predict`, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(payload),
        signal: AbortSignal.timeout(10000),
      });

      if (!resp.ok) { const e = await resp.json(); throw new Error(e.error || "API error"); }
      const data = await resp.json();

      /* Derive risk factors from inputs */
      const dos = form.current_stock / (form.daily_demand || 1);
      const factors = [];
      if (dos < form.lead_time_days)        factors.push("Stock below lead-time buffer");
      else if (dos < form.lead_time_days * 1.5) factors.push("Stock near lead-time threshold");
      if (form.supplier_reliability_score < 60)  factors.push("Low supplier reliability");
      else if (form.supplier_reliability_score < 75) factors.push("Moderate supplier reliability");
      if (form.promotion_active === "Yes")   factors.push("Active promotion spikes demand");
      if (form.weather_impact === "High")    factors.push("High weather disrupts supply");

      const entry = {
        ...data,
        factors,
        dos: parseFloat(dos.toFixed(2)),
        inputs: { ...payload },
        ts: new Date().toLocaleTimeString(),
      };
      setResult(entry);
      setHistory(h => [entry, ...h].slice(0, 10));
      setApiStatus("connected");

    } catch (err) {
      const isNetwork = err.message.includes("fetch") || err.name === "TimeoutError" || err.message.includes("Failed");
      setApiStatus("disconnected");
      setResult({
        error: isNetwork
          ? "Cannot reach Flask API. Make sure app.py is running on localhost:5000."
          : err.message,
      });
    }
    clearInterval(iv); setLoading(false);
  }

  const MONTHS = ["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];
  const DAYS   = ["Mon","Tue","Wed","Thu","Fri","Sat","Sun"];

  /* ─────────────────────── CSS ─────────────────────────────────────────── */
  const css = `
    @import url('https://fonts.googleapis.com/css2?family=Sora:wght@300;400;500;600;700&family=Space+Mono:wght@400;700&display=swap');
    *{box-sizing:border-box;margin:0;padding:0;}
    body{font-family:'Sora',sans-serif;background:#0c0c17;color:#fff;-webkit-font-smoothing:antialiased;}
    @keyframes fadeUp{from{opacity:0;transform:translateY(18px)}to{opacity:1;transform:translateY(0)}}
    @keyframes scaleIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:scale(1)}}
    @keyframes pulse{0%,100%{opacity:1;transform:scale(1)}50%{opacity:.45;transform:scale(.75)}}
    @keyframes blink{0%,100%{opacity:1}50%{opacity:.2}}
    @keyframes spin{to{transform:rotate(360deg)}}
    @keyframes barIn{from{width:0}}
    @keyframes shimmer{0%{opacity:.5}50%{opacity:1}100%{opacity:.5}}
    .fu{animation:fadeUp .5s ease both;}
    .si{animation:scaleIn .35s ease both;}
    .card{background:#13131f;border:1px solid rgba(255,255,255,.07);border-radius:16px;padding:20px;transition:border-color .2s;}
    .card:hover{border-color:rgba(167,139,250,.18);}
    .pill{display:inline-flex;align-items:center;padding:2px 9px;border-radius:20px;font-size:11px;font-weight:600;letter-spacing:.03em;}
    .tag{display:inline-flex;align-items:center;gap:4px;padding:3px 10px;border-radius:20px;font-size:11px;font-weight:600;}
    select{background:rgba(255,255,255,.05);border:1px solid rgba(255,255,255,.1);border-radius:10px;color:#fff;padding:10px 14px;font-family:'Sora',sans-serif;font-size:13px;width:100%;cursor:pointer;outline:none;transition:border-color .2s;}
    select:focus{border-color:#a78bfa;background:rgba(167,139,250,.06);}
    select option{background:#1a1a2e;color:#fff;}
    .nav-btn{display:flex;align-items:center;gap:11px;padding:10px 12px;border-radius:11px;border:none;background:transparent;color:rgba(255,255,255,.38);cursor:pointer;font-family:'Sora',sans-serif;font-size:13px;font-weight:500;width:100%;transition:all .18s;text-align:left;position:relative;}
    .nav-btn.active{background:rgba(167,139,250,.13);color:#c4b5fd;}
    .nav-btn.active::before{content:'';position:absolute;left:0;top:20%;height:60%;width:3px;background:#a78bfa;border-radius:0 2px 2px 0;}
    .nav-btn:hover:not(.active){background:rgba(255,255,255,.05);color:rgba(255,255,255,.65);}
    .fb{padding:6px 16px;border-radius:20px;border:1px solid rgba(255,255,255,.1);background:transparent;color:rgba(255,255,255,.38);font-size:12px;font-weight:500;cursor:pointer;font-family:'Sora',sans-serif;transition:all .18s;}
    .fb.act{background:rgba(167,139,250,.14);border-color:rgba(167,139,250,.45);color:#c4b5fd;}
    .fb:hover:not(.act){border-color:rgba(255,255,255,.2);color:rgba(255,255,255,.7);}
    th{text-align:left;padding:12px 14px;font-size:10px;letter-spacing:.1em;text-transform:uppercase;color:rgba(255,255,255,.28);font-weight:500;border-bottom:1px solid rgba(255,255,255,.06);white-space:nowrap;cursor:pointer;user-select:none;transition:color .15s;}
    th:hover{color:rgba(255,255,255,.6);}
    td{padding:11px 14px;font-size:13px;border-bottom:1px solid rgba(255,255,255,.04);vertical-align:middle;}
    .tr-h:hover td{background:rgba(167,139,250,.04);}
    tr:last-child td{border-bottom:none;}
    input[type=range]{-webkit-appearance:none;appearance:none;background:transparent;width:100%;height:24px;cursor:pointer;margin:0;}
    input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:0;height:0;}
    ::-webkit-scrollbar{width:5px;height:5px;}
    ::-webkit-scrollbar-track{background:transparent;}
    ::-webkit-scrollbar-thumb{background:rgba(255,255,255,.1);border-radius:3px;}
    .code-box{background:rgba(0,0,0,.4);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:14px 16px;font-family:'Space Mono',monospace;font-size:12px;color:#a5f3a5;line-height:1.7;overflow-x:auto;}
    .history-pill{display:flex;align-items:center;gap:8px;padding:8px 12px;background:rgba(255,255,255,.04);border-radius:8px;font-size:12px;border:1px solid rgba(255,255,255,.07);transition:border-color .15s;cursor:default;}
    .history-pill:hover{border-color:rgba(167,139,250,.2);}
  `;

  const NavIcon = ({ id, active }) => (
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke={active ? "#c4b5fd" : "rgba(255,255,255,.38)"} strokeWidth="1.8" strokeLinecap="round" strokeLinejoin="round">
      {id === "dashboard" && <><rect x="3" y="3" width="7" height="7" rx="1.5" /><rect x="14" y="3" width="7" height="7" rx="1.5" /><rect x="3" y="14" width="7" height="7" rx="1.5" /><rect x="14" y="14" width="7" height="7" rx="1.5" /></>}
      {id === "predict"   && <polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" />}
      {id === "products"  && <><path d="M21 16V8a2 2 0 00-1-1.73l-7-4a2 2 0 00-2 0l-7 4A2 2 0 003 8v8a2 2 0 001 1.73l7 4a2 2 0 002 0l7-4A2 2 0 0021 16z" /><polyline points="3.27 6.96 12 12.01 20.73 6.96" /><line x1="12" y1="22.08" x2="12" y2="12" /></>}
      {id === "setup"     && <><circle cx="12" cy="12" r="3" /><path d="M19.07 4.93a10 10 0 010 14.14M4.93 4.93a10 10 0 000 14.14" /></>}
    </svg>
  );

  /* ───────────────────────── RENDER ───────────────────────────────────── */
  return (
    <div style={{ display: "flex", minHeight: "100vh", background: "#0c0c17" }}>
      <style>{css}</style>

      {/* ═══ SIDEBAR ═══ */}
      <aside style={{ width: 220, borderRight: "1px solid rgba(255,255,255,.06)", padding: "22px 14px", display: "flex", flexDirection: "column", gap: 3, flexShrink: 0, background: "rgba(0,0,0,.25)" }}>
        {/* Logo */}
        <div style={{ display: "flex", alignItems: "center", gap: 11, marginBottom: 34, paddingLeft: 2 }}>
          <div style={{ width: 34, height: 34, borderRadius: 11, background: "linear-gradient(135deg,#7c3aed 0%,#a78bfa 100%)", display: "flex", alignItems: "center", justifyContent: "center", boxShadow: "0 4px 16px rgba(124,58,237,.4)", flexShrink: 0 }}>
            <svg width="17" height="17" viewBox="0 0 16 16" fill="none">
              <rect x="1" y="8" width="3" height="7" rx="1.2" fill="white" fillOpacity=".65" />
              <rect x="6" y="4" width="3" height="11" rx="1.2" fill="white" />
              <rect x="11" y="1" width="3" height="14" rx="1.2" fill="white" fillOpacity=".65" />
            </svg>
          </div>
          <div>
            <div style={{ fontSize: 15, fontWeight: 700, letterSpacing: "-.01em", lineHeight: 1 }}>StockSense</div>
            <div style={{ fontSize: 10, color: "rgba(255,255,255,.28)", marginTop: 3, letterSpacing: ".03em" }}>AI · LightGBM</div>
          </div>
        </div>

        <div style={{ fontSize: 9, color: "rgba(255,255,255,.22)", letterSpacing: ".12em", textTransform: "uppercase", paddingLeft: 12, marginBottom: 6 }}>Navigation</div>
        {[{ id: "dashboard", label: "Dashboard" }, { id: "predict", label: "Predict" }, { id: "products", label: "Products" }, { id: "setup", label: "Setup & API" }].map(n => (
          <button key={n.id} className={`nav-btn${tab === n.id ? " active" : ""}`} onClick={() => setTab(n.id)}>
            <NavIcon id={n.id} active={tab === n.id} />
            {n.label}
          </button>
        ))}

        {/* Model card */}
        <div style={{ marginTop: "auto", padding: "14px", background: "rgba(167,139,250,.07)", border: "1px solid rgba(167,139,250,.14)", borderRadius: 13 }}>
          <div style={{ fontSize: 9, color: "rgba(255,255,255,.3)", letterSpacing: ".1em", marginBottom: 7, textTransform: "uppercase" }}>Model</div>
          <div style={{ fontSize: 12, fontWeight: 600, color: "#c4b5fd", marginBottom: 1 }}>LightGBM Pipeline</div>
          <div style={{ fontSize: 10, color: "rgba(255,255,255,.28)", marginBottom: 10 }}>300 trees · 2272 features</div>
          <StatusBadge status={apiStatus} />
        </div>
      </aside>

      {/* ═══ MAIN ═══ */}
      <main style={{ flex: 1, padding: "28px 30px", overflowY: "auto", minWidth: 0 }}>

        {/* ══ DASHBOARD ══ */}
        {tab === "dashboard" && (
          <div>
            <div style={{ marginBottom: 28 }} className="fu">
              <div style={{ fontSize: 10, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase", marginBottom: 7 }}>
                {new Date().toLocaleDateString("en-GB", { weekday: "long", day: "numeric", month: "long", year: "numeric" })}
              </div>
              <h1 style={{ fontSize: 26, fontWeight: 700, lineHeight: 1.15, letterSpacing: "-.02em" }}>
                Inventory Risk <span style={{ color: "#a78bfa" }}>Overview</span>
              </h1>
            </div>

            {/* KPIs */}
            <div style={{ display: "grid", gridTemplateColumns: "repeat(4,1fr)", gap: 14, marginBottom: 22 }}>
              {[
                { label: "At-risk products", val: stockouts, suffix: "", sub: `of ${products.length} monitored`, color: "#ff6b6b", seed: 11 },
                { label: "High risk items",  val: highRisk,  suffix: "", sub: "score above 65%",        color: "#ffaa3b", seed: 22 },
                { label: "Avg risk score",   val: avgRisk,   suffix: "%", sub: "portfolio average",    color: "#a78bfa", seed: 33 },
                { label: "Supplier avg",     val: avgRel,    suffix: "%", sub: "all stores",           color: "#3ecf8e", seed: 44 },
              ].map((k, i) => (
                <div key={k.label} className="card fu" style={{ animationDelay: `${i * .07}s`, position: "relative", overflow: "hidden", padding: "18px 18px 14px" }}>
                  <div style={{ position: "absolute", top: -20, right: -20, width: 90, height: 90, background: `radial-gradient(circle,${k.color}15,transparent 70%)`, pointerEvents: "none" }} />
                  <div style={{ fontSize: 9, color: "rgba(255,255,255,.32)", letterSpacing: ".12em", textTransform: "uppercase", marginBottom: 14 }}>{k.label}</div>
                  <div style={{ fontSize: 30, fontWeight: 700, color: k.color, fontFamily: "'Space Mono',monospace", letterSpacing: "-.03em", lineHeight: 1 }}>
                    <Counter to={k.val} suffix={k.suffix} />
                  </div>
                  <div style={{ display: "flex", alignItems: "flex-end", justifyContent: "space-between", marginTop: 12 }}>
                    <span style={{ fontSize: 11, color: "rgba(255,255,255,.28)" }}>{k.sub}</span>
                    <Sparkline data={spark(k.seed)} color={k.color} />
                  </div>
                </div>
              ))}
            </div>

            {/* Store + side charts */}
            <div style={{ display: "grid", gridTemplateColumns: "1.45fr 1fr", gap: 16, marginBottom: 16 }}>
              <div className="card fu" style={{ animationDelay: ".22s" }}>
                <div style={{ display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: 22 }}>
                  <div><div style={{ fontSize: 14, fontWeight: 600 }}>Store risk ranking</div><div style={{ fontSize: 11, color: "rgba(255,255,255,.3)", marginTop: 4 }}>Average predicted stockout risk</div></div>
                  <span className="tag" style={{ background: "rgba(167,139,250,.12)", color: "#c4b5fd" }}>{storeData.length} stores</span>
                </div>
                {storeData.map(({ store, avg }, i) => (
                  <div key={store} style={{ marginBottom: 11, display: "flex", alignItems: "center", gap: 12 }}>
                    <span style={{ fontSize: 10, fontFamily: "'Space Mono',monospace", color: "rgba(255,255,255,.35)", minWidth: 26, textAlign: "right" }}>{store}</span>
                    <div style={{ flex: 1, height: 6, background: "rgba(255,255,255,.06)", borderRadius: 3, overflow: "hidden" }}>
                      <div style={{ height: "100%", width: avg + "%", background: `linear-gradient(90deg,${rc(avg)}50,${rc(avg)})`, borderRadius: 3, animation: `barIn .7s ${i * .05}s ease both` }} />
                    </div>
                    <span style={{ fontSize: 11, fontWeight: 700, color: rc(avg), minWidth: 32, fontFamily: "'Space Mono',monospace" }}>{avg}%</span>
                  </div>
                ))}
              </div>

              <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
                {/* Distribution */}
                <div className="card fu" style={{ animationDelay: ".3s", flex: 1, padding: 18 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 16 }}>Risk distribution</div>
                  {[{ lbl: "Critical", sub: ">65%", n: products.filter(p => p.risk > 65).length, c: "#ff6b6b" }, { lbl: "Moderate", sub: "41–65%", n: products.filter(p => p.risk > 40 && p.risk <= 65).length, c: "#ffaa3b" }, { lbl: "Healthy", sub: "≤40%", n: products.filter(p => p.risk <= 40).length, c: "#3ecf8e" }].map(d => (
                    <div key={d.lbl} style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 11 }}>
                      <div style={{ display: "flex", alignItems: "center", gap: 8 }}><div style={{ width: 8, height: 8, borderRadius: 2, background: d.c }} /><span style={{ fontSize: 12, color: "rgba(255,255,255,.45)" }}>{d.lbl}</span><span style={{ fontSize: 10, color: "rgba(255,255,255,.22)" }}>{d.sub}</span></div>
                      <span style={{ fontSize: 16, fontWeight: 700, color: d.c, fontFamily: "'Space Mono',monospace" }}>{d.n}</span>
                    </div>
                  ))}
                  <div style={{ height: 7, borderRadius: 4, display: "flex", overflow: "hidden", gap: 2, marginTop: 8 }}>
                    {[{ n: products.filter(p => p.risk > 65).length, c: "#ff6b6b" }, { n: products.filter(p => p.risk > 40 && p.risk <= 65).length, c: "#ffaa3b" }, { n: products.filter(p => p.risk <= 40).length, c: "#3ecf8e" }].map((d, i) => (
                      <div key={i} style={{ flex: d.n, background: d.c, opacity: .8 }} />
                    ))}
                  </div>
                </div>
                {/* Weather */}
                <div className="card fu" style={{ animationDelay: ".37s", flex: 1, padding: 18 }}>
                  <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 16 }}>Weather impact</div>
                  {[{ w: "High", c: "#ff6b6b" }, { w: "Medium", c: "#ffaa3b" }, { w: "Low", c: "#3ecf8e" }].map(({ w, c }) => {
                    const ps = products.filter(p => p.weather === w);
                    const avg = ps.length ? Math.round(ps.reduce((s, p) => s + p.risk, 0) / ps.length) : 0;
                    return (
                      <div key={w} style={{ display: "flex", alignItems: "center", gap: 10, marginBottom: 12 }}>
                        <div style={{ width: 7, height: 7, borderRadius: "50%", background: c, flexShrink: 0 }} />
                        <span style={{ fontSize: 11, color: "rgba(255,255,255,.38)", minWidth: 52 }}>{w}</span>
                        <div style={{ flex: 1, height: 4, background: "rgba(255,255,255,.06)", borderRadius: 2, overflow: "hidden" }}>
                          <div style={{ height: "100%", width: avg + "%", background: c, opacity: .75, borderRadius: 2 }} />
                        </div>
                        <span style={{ fontSize: 11, fontWeight: 700, color: c, fontFamily: "'Space Mono',monospace", minWidth: 30 }}>{avg}%</span>
                      </div>
                    );
                  })}
                </div>
              </div>
            </div>

            {/* Top 5 */}
            <div className="card fu" style={{ animationDelay: ".44s", padding: 0, overflow: "hidden" }}>
              <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "16px 18px", borderBottom: "1px solid rgba(255,255,255,.06)" }}>
                <div style={{ fontSize: 14, fontWeight: 600 }}>Top 5 highest-risk products</div>
                <button onClick={() => setTab("products")} style={{ fontSize: 12, color: "#a78bfa", background: "none", border: "none", cursor: "pointer", fontFamily: "'Sora',sans-serif", fontWeight: 500 }}>View all →</button>
              </div>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead><tr>{["Product", "Store", "Days supply", "Reliability", "Weather", "Promo", "Risk"].map(h => <th key={h} style={{ cursor: "default", padding: "10px 18px" }}>{h}</th>)}</tr></thead>
                <tbody>
                  {[...products].sort((a, b) => b.risk - a.risk).slice(0, 5).map(p => (
                    <tr key={p.id} className="tr-h">
                      <td style={{ padding: "11px 18px" }}><span style={{ fontFamily: "'Space Mono',monospace", fontSize: 12, fontWeight: 700, color: "#a78bfa" }}>{p.id}</span></td>
                      <td style={{ padding: "11px 18px" }}><span style={{ fontFamily: "'Space Mono',monospace", fontSize: 12, color: "rgba(255,255,255,.4)" }}>{p.store}</span></td>
                      <td style={{ padding: "11px 18px" }}><span style={{ color: (p.stock / p.demand) < p.lead ? "#ff6b6b" : "rgba(255,255,255,.45)", fontWeight: (p.stock / p.demand) < p.lead ? 600 : 400 }}>{(p.stock / p.demand).toFixed(1)}d</span></td>
                      <td style={{ padding: "11px 18px" }}><span style={{ color: p.reliability < 65 ? "#ff6b6b" : p.reliability < 80 ? "#ffaa3b" : "#3ecf8e" }}>{p.reliability}%</span></td>
                      <td style={{ padding: "11px 18px" }}><span style={{ color: "rgba(255,255,255,.4)" }}>{p.weather}</span></td>
                      <td style={{ padding: "11px 18px" }}><span className="pill" style={{ background: p.promo ? "rgba(167,139,250,.13)" : "rgba(255,255,255,.06)", color: p.promo ? "#c4b5fd" : "rgba(255,255,255,.28)" }}>{p.promo ? "Active" : "None"}</span></td>
                      <td style={{ padding: "11px 18px" }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 9 }}>
                          <div style={{ width: 54, height: 5, background: "rgba(255,255,255,.07)", borderRadius: 3, overflow: "hidden" }}>
                            <div style={{ height: "100%", width: p.risk + "%", background: rc(p.risk), borderRadius: 3 }} />
                          </div>
                          <span className="pill" style={{ background: rb(p.risk), color: rc(p.risk) }}>{p.risk}%</span>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        )}

        {/* ══ PREDICT ══ */}
        {tab === "predict" && (
          <div style={{ maxWidth: 900 }}>
            <div style={{ marginBottom: 28 }} className="fu">
              <div style={{ display: "flex", alignItems: "center", gap: 12, marginBottom: 7 }}>
                <div style={{ fontSize: 10, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase" }}>Real model · best_stockout_model.pkl</div>
                <StatusBadge status={apiStatus} />
              </div>
              <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-.02em" }}>Stockout <span style={{ color: "#a78bfa" }}>Prediction</span></h1>
            </div>

            {apiStatus === "disconnected" && (
              <div style={{ background: "rgba(255,107,107,.08)", border: "1px solid rgba(255,107,107,.25)", borderRadius: 12, padding: "14px 18px", marginBottom: 20, display: "flex", gap: 12, alignItems: "flex-start" }}>
                <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="#ff8080" strokeWidth="2" strokeLinecap="round" style={{ flexShrink: 0, marginTop: 1 }}><circle cx="12" cy="12" r="10" /><line x1="12" y1="8" x2="12" y2="12" /><line x1="12" y1="16" x2="12.01" y2="16" /></svg>
                <div>
                  <div style={{ fontSize: 13, fontWeight: 600, color: "#ff8080", marginBottom: 4 }}>Flask API not reachable</div>
                  <div style={{ fontSize: 12, color: "rgba(255,255,255,.5)", lineHeight: 1.6 }}>Start the server: <code style={{ fontFamily: "'Space Mono',monospace", background: "rgba(0,0,0,.3)", padding: "1px 6px", borderRadius: 4 }}>python app.py</code> — then predictions will use the real LightGBM model.</div>
                </div>
              </div>
            )}

            <div style={{ display: "grid", gridTemplateColumns: "1.05fr 1fr", gap: 18, alignItems: "start" }}>
              {/* Form */}
              <div className="card si" style={{ padding: 24 }}>
                <div style={{ fontSize: 9, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase", marginBottom: 22, display: "flex", alignItems: "center", gap: 8 }}>
                  <div style={{ width: 16, height: 1, background: "rgba(255,255,255,.15)" }} />Input parameters<div style={{ flex: 1, height: 1, background: "rgba(255,255,255,.08)" }} />
                </div>

                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 12, marginBottom: 22 }}>
                  <div>
                    <div style={{ fontSize: 10, color: "rgba(255,255,255,.35)", letterSpacing: ".09em", textTransform: "uppercase", marginBottom: 7 }}>Product ID</div>
                    <select value={form.product_id} onChange={e => set("product_id")(e.target.value)}>{PRODUCTS.map(p => <option key={p}>{p}</option>)}</select>
                  </div>
                  <div>
                    <div style={{ fontSize: 10, color: "rgba(255,255,255,.35)", letterSpacing: ".09em", textTransform: "uppercase", marginBottom: 7 }}>Store ID</div>
                    <select value={form.store_id} onChange={e => set("store_id")(e.target.value)}>{STORES.map(s => <option key={s}>{s}</option>)}</select>
                  </div>
                </div>

                <SliderField label="Current stock" value={form.current_stock} min={10} max={500} step={5} unit=" units" onChange={set("current_stock")} color="#a78bfa" />
                <SliderField label="Daily demand" value={form.daily_demand} min={5} max={200} step={5} unit="/day" onChange={set("daily_demand")} color="#38bdf8" />
                <SliderField label="Lead time" value={form.lead_time_days} min={1} max={21} unit=" days" onChange={set("lead_time_days")} color="#fb923c" />
                <SliderField label="Supplier reliability" value={form.supplier_reliability_score} min={40} max={100} unit="%" onChange={set("supplier_reliability_score")} color="#3ecf8e" />

                <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 14, marginBottom: 22 }}>
                  <div style={{ background: "rgba(255,255,255,.04)", borderRadius: 12, padding: 14 }}>
                    <div style={{ fontSize: 9, color: "rgba(255,255,255,.32)", letterSpacing: ".1em", textTransform: "uppercase", marginBottom: 11 }}>Promotion</div>
                    <div style={{ display: "flex", alignItems: "center", gap: 10 }}>
                      <Toggle value={form.promotion_active} onChange={set("promotion_active")} />
                      <span style={{ fontSize: 13, fontWeight: 500, color: form.promotion_active === "Yes" ? "#3ecf8e" : "rgba(255,255,255,.35)" }}>{form.promotion_active}</span>
                    </div>
                  </div>
                  <div style={{ background: "rgba(255,255,255,.04)", borderRadius: 12, padding: 14 }}>
                    <div style={{ fontSize: 9, color: "rgba(255,255,255,.32)", letterSpacing: ".1em", textTransform: "uppercase", marginBottom: 11 }}>Weather impact</div>
                    <select value={form.weather_impact} onChange={e => set("weather_impact")(e.target.value)} style={{ padding: "7px 10px", fontSize: 12 }}>{WEATHER.map(w => <option key={w}>{w}</option>)}</select>
                  </div>
                </div>

                <div style={{ display: "grid", gridTemplateColumns: "repeat(3,1fr)", gap: 12, marginBottom: 26 }}>
                  {[["month", 1, 12, MONTHS], ["day_of_week", 0, 6, DAYS], ["day", 1, 31, null]].map(([key, mn, mx, labels]) => (
                    <div key={key}>
                      <div style={{ display: "flex", justifyContent: "space-between", marginBottom: 9 }}>
                        <span style={{ fontSize: 10, color: "rgba(255,255,255,.35)", letterSpacing: ".09em", textTransform: "uppercase" }}>{key === "day_of_week" ? "Weekday" : key === "month" ? "Month" : "Day"}</span>
                        <span style={{ fontSize: 12, fontWeight: 600, color: "#fff", fontFamily: "'Space Mono',monospace" }}>{labels ? labels[form[key] - (key === "month" ? 1 : 0)] : form[key]}</span>
                      </div>
                      <input type="range" min={mn} max={mx} value={form[key]} onChange={e => set(key)(+e.target.value)} style={{ accentColor: "#a78bfa", width: "100%" }} />
                    </div>
                  ))}
                </div>

                <button onClick={runPrediction} disabled={loading}
                  style={{ width: "100%", padding: "14px 0", borderRadius: 12, border: "none", background: loading ? "rgba(255,255,255,.05)" : "linear-gradient(135deg,#6d28d9 0%,#a78bfa 100%)", color: loading ? "rgba(255,255,255,.25)" : "#fff", fontSize: 14, fontWeight: 600, cursor: loading ? "not-allowed" : "pointer", fontFamily: "'Sora',sans-serif", transition: "all .2s", display: "flex", alignItems: "center", justifyContent: "center", gap: 10, boxShadow: loading ? "none" : "0 4px 20px rgba(124,58,237,.35)" }}>
                  {loading ? (
                    <><div style={{ width: 15, height: 15, borderRadius: "50%", border: "2px solid rgba(255,255,255,.15)", borderTopColor: "rgba(255,255,255,.6)", animation: "spin .75s linear infinite" }} />{loadMsg}</>
                  ) : (
                    <><svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" /></svg>Run real model prediction</>
                  )}
                </button>
              </div>

              {/* Right panel */}
              <div style={{ display: "flex", flexDirection: "column", gap: 14 }}>
                {/* Live signal */}
                <div className="card" style={{ padding: 20 }}>
                  <div style={{ fontSize: 9, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase", marginBottom: 16 }}>Live signal</div>
                  {(() => {
                    const dos = (form.current_stock / (form.daily_demand || 1));
                    const ok = dos >= form.lead_time_days;
                    const relColor = form.supplier_reliability_score < 65 ? "#ff6b6b" : form.supplier_reliability_score < 80 ? "#ffaa3b" : "#3ecf8e";
                    const relLabel = form.supplier_reliability_score < 65 ? "Weak" : form.supplier_reliability_score < 80 ? "Fair" : "Strong";
                    return (
                      <div style={{ display: "flex", flexDirection: "column", gap: 8 }}>
                        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "11px 14px", background: "rgba(255,255,255,.04)", borderRadius: 10 }}>
                          <span style={{ fontSize: 11, color: "rgba(255,255,255,.38)" }}>Days of supply</span>
                          <span style={{ fontSize: 18, fontWeight: 700, fontFamily: "'Space Mono',monospace" }}>{dos.toFixed(1)}<span style={{ fontSize: 11, color: "rgba(255,255,255,.35)", fontWeight: 400 }}> d</span></span>
                        </div>
                        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "11px 14px", background: ok ? "rgba(62,207,142,.07)" : "rgba(255,107,107,.07)", borderRadius: 10, border: `1px solid ${ok ? "rgba(62,207,142,.18)" : "rgba(255,107,107,.18)"}` }}>
                          <span style={{ fontSize: 11, color: "rgba(255,255,255,.38)" }}>vs lead time ({form.lead_time_days}d)</span>
                          <span style={{ fontSize: 12, fontWeight: 600, color: ok ? "#3ecf8e" : "#ff6b6b" }}>{ok ? "✓ Sufficient" : "⚠ Insufficient"}</span>
                        </div>
                        <div style={{ display: "flex", justifyContent: "space-between", alignItems: "center", padding: "11px 14px", background: "rgba(255,255,255,.04)", borderRadius: 10 }}>
                          <span style={{ fontSize: 11, color: "rgba(255,255,255,.38)" }}>Supplier status</span>
                          <span style={{ fontSize: 12, fontWeight: 600, color: relColor }}>{relLabel} · {form.supplier_reliability_score}%</span>
                        </div>
                        {form.promotion_active === "Yes" && <div style={{ padding: "10px 14px", background: "rgba(167,139,250,.07)", borderRadius: 10, border: "1px solid rgba(167,139,250,.18)", fontSize: 11, color: "#c4b5fd" }}>🎯 Promotion active — demand spike risk</div>}
                        {form.weather_impact === "High" && <div style={{ padding: "10px 14px", background: "rgba(255,107,107,.06)", borderRadius: 10, border: "1px solid rgba(255,107,107,.15)", fontSize: 11, color: "#ff9090" }}>🌩 High weather impact — supply disruption risk</div>}
                      </div>
                    );
                  })()}
                </div>

                {/* Empty state */}
                {!result && !loading && (
                  <div className="card" style={{ minHeight: 180, display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: 12, opacity: .35 }}>
                    <svg width="36" height="36" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.4" strokeLinecap="round" strokeLinejoin="round"><polygon points="13 2 3 14 12 14 11 22 21 10 12 10 13 2" /></svg>
                    <div style={{ fontSize: 12, color: "rgba(255,255,255,.5)", textAlign: "center", lineHeight: 1.6 }}>Configure parameters<br />and run prediction</div>
                  </div>
                )}

                {/* Error state */}
                {result?.error && (
                  <div className="card si" style={{ border: "1px solid rgba(255,107,107,.3)", padding: 20 }}>
                    <div style={{ fontSize: 12, color: "#ff8080", fontWeight: 600, marginBottom: 8 }}>Prediction failed</div>
                    <div style={{ fontSize: 12, color: "rgba(255,255,255,.5)", lineHeight: 1.6 }}>{result.error}</div>
                    <div style={{ marginTop: 12, fontSize: 11, color: "rgba(255,255,255,.3)" }}>Go to <strong style={{ color: "#a78bfa", cursor: "pointer" }} onClick={() => setTab("setup")}>Setup & API</strong> for instructions.</div>
                  </div>
                )}

                {/* Result */}
                {result && !result.error && (
                  <div className="card si" style={{ border: `1px solid ${rc(result.risk_percent)}30`, position: "relative", overflow: "hidden", padding: 22 }}>
                    <div style={{ position: "absolute", top: -40, right: -40, width: 130, height: 130, background: `radial-gradient(circle,${rc(result.risk_percent)}12,transparent 70%)`, pointerEvents: "none" }} />

                    {/* Model source badge */}
                    <div style={{ display: "inline-flex", alignItems: "center", gap: 5, padding: "3px 10px", borderRadius: 20, background: "rgba(62,207,142,.1)", border: "1px solid rgba(62,207,142,.2)", marginBottom: 14 }}>
                      <div style={{ width: 5, height: 5, borderRadius: "50%", background: "#3ecf8e" }} />
                      <span style={{ fontSize: 10, color: "#3ecf8e", fontWeight: 600 }}>Real LightGBM prediction · {result.ts}</span>
                    </div>

                    <div style={{ display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: 14 }}>
                      <div>
                        <div style={{ display: "flex", alignItems: "center", gap: 9, marginBottom: 4 }}>
                          <div style={{ width: 9, height: 9, borderRadius: "50%", background: rc(result.risk_percent), boxShadow: `0 0 10px ${rc(result.risk_percent)}` }} />
                          <span style={{ fontSize: 16, fontWeight: 700, color: rc(result.risk_percent) }}>{rl(result.risk_percent)} Risk</span>
                        </div>
                        <div style={{ fontSize: 12, color: "rgba(255,255,255,.4)" }}>
                          Predicted stockout: <strong style={{ color: result.predicted_label === "Yes" ? "#ff6b6b" : "#3ecf8e" }}>{result.predicted_label}</strong>
                        </div>
                        <div style={{ fontSize: 11, color: "rgba(255,255,255,.28)", marginTop: 3 }}>
                          Probability: <span style={{ fontFamily: "'Space Mono',monospace", color: rc(result.risk_percent) }}>{(result.probability * 100).toFixed(2)}%</span>
                          {" · "}{result.dos}d supply
                        </div>
                      </div>
                      <Gauge score={Math.round(result.risk_percent)} />
                    </div>

                    {result.factors?.length > 0 && (
                      <div style={{ marginBottom: 14 }}>
                        <div style={{ fontSize: 9, color: "rgba(255,255,255,.3)", letterSpacing: ".12em", textTransform: "uppercase", marginBottom: 8 }}>Risk factors</div>
                        <div style={{ display: "flex", flexWrap: "wrap", gap: 6 }}>
                          {result.factors.map(f => (
                            <span key={f} className="pill" style={{ background: "rgba(255,107,107,.1)", color: "#ff9090", border: "1px solid rgba(255,107,107,.18)", padding: "3px 10px" }}>{f}</span>
                          ))}
                        </div>
                      </div>
                    )}

                    {/* Raw output */}
                    <div className="code-box">
                      {`{\n  "probability":     ${result.probability},\n  "risk_percent":    ${result.risk_percent},\n  "predicted_label": "${result.predicted_label}",\n  "risk_level":      "${result.risk_level}"\n}`}
                    </div>
                  </div>
                )}

                {/* Prediction history */}
                {history.length > 0 && (
                  <div className="card" style={{ padding: 16 }}>
                    <div style={{ fontSize: 10, color: "rgba(255,255,255,.3)", letterSpacing: ".12em", textTransform: "uppercase", marginBottom: 12 }}>Recent predictions</div>
                    <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
                      {history.slice(0, 5).map((h, i) => (
                        <div key={i} className="history-pill">
                          <span style={{ fontFamily: "'Space Mono',monospace", fontSize: 11, color: "#a78bfa" }}>{h.inputs.product_id}</span>
                          <span style={{ fontSize: 10, color: "rgba(255,255,255,.3)" }}>{h.inputs.store_id}</span>
                          <span className="pill" style={{ background: rb(h.risk_percent), color: rc(h.risk_percent), marginLeft: "auto" }}>{h.risk_percent}%</span>
                          <span style={{ fontSize: 10, color: h.predicted_label === "Yes" ? "#ff6b6b" : "#3ecf8e", fontWeight: 600 }}>{h.predicted_label === "Yes" ? "⚠" : "✓"}</span>
                          <span style={{ fontSize: 10, color: "rgba(255,255,255,.2)" }}>{h.ts}</span>
                        </div>
                      ))}
                    </div>
                  </div>
                )}
              </div>
            </div>
          </div>
        )}

        {/* ══ PRODUCTS ══ */}
        {tab === "products" && (
          <div>
            <div style={{ marginBottom: 24 }} className="fu">
              <div style={{ fontSize: 10, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase", marginBottom: 7 }}>Inventory · {products.length} products</div>
              <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-.02em" }}>Product <span style={{ color: "#a78bfa" }}>Monitor</span></h1>
            </div>
            <div style={{ display: "flex", alignItems: "center", gap: 8, marginBottom: 16, flexWrap: "wrap" }}>
              {[{ f: "All", n: products.length }, { f: "High", n: products.filter(p => p.risk > 65).length }, { f: "Medium", n: products.filter(p => p.risk > 40 && p.risk <= 65).length }, { f: "Low", n: products.filter(p => p.risk <= 40).length }].map(({ f, n }) => (
                <button key={f} className={`fb${filter === f ? " act" : ""}`} onClick={() => setFilter(f)}>{f} <span style={{ opacity: .55 }}>({n})</span></button>
              ))}
              <div style={{ marginLeft: "auto", fontSize: 10, color: "rgba(255,255,255,.25)", display: "flex", alignItems: "center", gap: 5 }}>click headers to sort</div>
            </div>
            <div className="card fu" style={{ padding: 0, overflow: "hidden" }}>
              <table style={{ width: "100%", borderCollapse: "collapse" }}>
                <thead><tr>
                  {[["id", "Product"], ["store", "Store"], ["stock", "Stock"], ["demand", "Demand"], ["lead", "Lead"], ["reliability", "Reliability"], ["weather", "Weather"], ["promo", "Promo"], ["risk", "Risk Score"], ["predicted", "Status"]].map(([col, lbl]) => (
                    <th key={col} onClick={() => toggleSort(col)} style={{ padding: "12px 16px" }}>
                      {lbl}{sort.col === col ? <span style={{ marginLeft: 4, color: "#a78bfa" }}>{sort.dir === 1 ? "↑" : "↓"}</span> : null}
                    </th>
                  ))}
                </tr></thead>
                <tbody>
                  {filtered.map(p => (
                    <tr key={p.id} className="tr-h">
                      <td style={{ padding: "11px 16px" }}><span style={{ fontFamily: "'Space Mono',monospace", fontSize: 12, fontWeight: 700, color: "#a78bfa" }}>{p.id}</span></td>
                      <td style={{ padding: "11px 16px" }}><span style={{ fontFamily: "'Space Mono',monospace", fontSize: 11, color: "rgba(255,255,255,.38)" }}>{p.store}</span></td>
                      <td style={{ padding: "11px 16px", color: "rgba(255,255,255,.55)" }}>{p.stock}</td>
                      <td style={{ padding: "11px 16px", color: "rgba(255,255,255,.45)" }}>{p.demand}/d</td>
                      <td style={{ padding: "11px 16px", color: "rgba(255,255,255,.45)" }}>{p.lead}d</td>
                      <td style={{ padding: "11px 16px" }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 7 }}>
                          <div style={{ width: 38, height: 3, background: "rgba(255,255,255,.08)", borderRadius: 2, overflow: "hidden" }}>
                            <div style={{ height: "100%", width: p.reliability + "%", background: p.reliability < 65 ? "#ff6b6b" : p.reliability < 80 ? "#ffaa3b" : "#3ecf8e", borderRadius: 2 }} />
                          </div>
                          <span style={{ fontSize: 12, color: p.reliability < 65 ? "#ff6b6b" : "rgba(255,255,255,.45)" }}>{p.reliability}%</span>
                        </div>
                      </td>
                      <td style={{ padding: "11px 16px" }}><span className="pill" style={{ background: p.weather === "High" ? "rgba(255,107,107,.1)" : p.weather === "Medium" ? "rgba(255,170,59,.1)" : "rgba(62,207,142,.1)", color: p.weather === "High" ? "#ff8080" : p.weather === "Medium" ? "#ffbb5c" : "#3ecf8e" }}>{p.weather}</span></td>
                      <td style={{ padding: "11px 16px" }}><span className="pill" style={{ background: p.promo ? "rgba(167,139,250,.12)" : "rgba(255,255,255,.05)", color: p.promo ? "#c4b5fd" : "rgba(255,255,255,.25)" }}>{p.promo ? "Active" : "—"}</span></td>
                      <td style={{ padding: "11px 16px" }}>
                        <div style={{ display: "flex", alignItems: "center", gap: 8 }}>
                          <div style={{ width: 50, height: 4, background: "rgba(255,255,255,.07)", borderRadius: 2, overflow: "hidden" }}>
                            <div style={{ height: "100%", width: p.risk + "%", background: rc(p.risk), borderRadius: 2 }} />
                          </div>
                          <span style={{ fontSize: 12, fontWeight: 700, color: rc(p.risk), fontFamily: "'Space Mono',monospace" }}>{p.risk}%</span>
                        </div>
                      </td>
                      <td style={{ padding: "11px 16px" }}><span className="pill" style={{ background: p.predicted === "Yes" ? "rgba(255,107,107,.11)" : "rgba(62,207,142,.11)", color: p.predicted === "Yes" ? "#ff8080" : "#3ecf8e", border: `1px solid ${p.predicted === "Yes" ? "rgba(255,107,107,.2)" : "rgba(62,207,142,.2)"}`, padding: "3px 10px" }}>{p.predicted === "Yes" ? "⚠ Stockout" : "✓ Safe"}</span></td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
          </div>
        )}

        {/* ══ SETUP ══ */}
        {tab === "setup" && (
          <div style={{ maxWidth: 700 }}>
            <div style={{ marginBottom: 28 }} className="fu">
              <div style={{ fontSize: 10, color: "rgba(255,255,255,.3)", letterSpacing: ".14em", textTransform: "uppercase", marginBottom: 7 }}>Integration guide</div>
              <h1 style={{ fontSize: 26, fontWeight: 700, letterSpacing: "-.02em" }}>Setup <span style={{ color: "#a78bfa" }}>& API</span></h1>
            </div>

            {/* Current status */}
            <div className="card fu" style={{ marginBottom: 16, padding: "18px 20px" }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 12 }}>API connection status</div>
              <div style={{ display: "flex", alignItems: "center", gap: 14, padding: "14px", background: "rgba(255,255,255,.04)", borderRadius: 10 }}>
                <StatusBadge status={apiStatus} />
                <span style={{ fontSize: 12, color: "rgba(255,255,255,.4)" }}>{API_URL}/predict</span>
                <button onClick={() => { setApiStatus("checking"); fetch(`${API_URL}/health`, { signal: AbortSignal.timeout(4000) }).then(r => r.ok ? setApiStatus("connected") : setApiStatus("disconnected")).catch(() => setApiStatus("disconnected")); }} style={{ marginLeft: "auto", padding: "5px 14px", borderRadius: 8, border: "1px solid rgba(255,255,255,.15)", background: "transparent", color: "rgba(255,255,255,.5)", fontSize: 12, cursor: "pointer", fontFamily: "'Sora',sans-serif" }}>Retry</button>
              </div>
            </div>

            {/* Steps */}
            {[
              {
                num: "01", title: "Download the two files",
                body: "You need app.py (the Flask server) and model_data.json (the extracted LightGBM model). Both were generated alongside this app.",
                code: null,
              },
              {
                num: "02", title: "Install dependencies",
                body: "Flask is the only requirement. The model predictor is pure Python with no sklearn or LightGBM needed at runtime.",
                code: "pip install flask",
              },
              {
                num: "03", title: "Place files in the same folder",
                body: "Put app.py and model_data.json in the same directory, then start the server:",
                code: "python app.py",
              },
              {
                num: "04", title: "Verify it's running",
                body: "Test the health endpoint:",
                code: `curl http://localhost:5000/health\n# → {"status":"ok","trees":300,"features":2272}`,
              },
              {
                num: "05", title: "Send a prediction",
                body: "POST JSON to /predict with all 11 input fields:",
                code: `curl -X POST http://localhost:5000/predict \\\n  -H "Content-Type: application/json" \\\n  -d '{\n    "product_id": "P1009",\n    "store_id": "S11",\n    "promotion_active": "No",\n    "weather_impact": "High",\n    "current_stock": 231,\n    "daily_demand": 29,\n    "lead_time_days": 12,\n    "supplier_reliability_score": 91,\n    "month": 6,\n    "day_of_week": 3,\n    "day": 15\n  }'`,
              },
            ].map((step, i) => (
              <div key={step.num} className="card fu" style={{ animationDelay: `${i * .06}s`, marginBottom: 12, padding: "18px 20px" }}>
                <div style={{ display: "flex", gap: 16, alignItems: "flex-start" }}>
                  <div style={{ width: 32, height: 32, borderRadius: 8, background: "rgba(167,139,250,.15)", border: "1px solid rgba(167,139,250,.25)", display: "flex", alignItems: "center", justifyContent: "center", flexShrink: 0 }}>
                    <span style={{ fontSize: 11, fontWeight: 700, color: "#a78bfa", fontFamily: "'Space Mono',monospace" }}>{step.num}</span>
                  </div>
                  <div style={{ flex: 1 }}>
                    <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 6 }}>{step.title}</div>
                    <div style={{ fontSize: 12, color: "rgba(255,255,255,.45)", lineHeight: 1.7, marginBottom: step.code ? 12 : 0 }}>{step.body}</div>
                    {step.code && <div className="code-box" style={{ whiteSpace: "pre" }}>{step.code}</div>}
                  </div>
                </div>
              </div>
            ))}

            {/* API reference */}
            <div className="card fu" style={{ animationDelay: ".32s", padding: "18px 20px" }}>
              <div style={{ fontSize: 13, fontWeight: 600, marginBottom: 14 }}>API response format</div>
              <div className="code-box" style={{ whiteSpace: "pre" }}>{`{\n  "probability":     0.5927,      // raw sigmoid output [0–1]\n  "risk_percent":    59.27,       // probability × 100\n  "predicted_label": "Yes",       // "Yes" if prob ≥ 0.5\n  "risk_level":      "Moderate"   // High / Moderate / Low\n}`}</div>
              <div style={{ marginTop: 14, fontSize: 12, color: "rgba(255,255,255,.35)", lineHeight: 1.7 }}>
                The model is a 300-tree LightGBM classifier trained with <code style={{ fontFamily: "'Space Mono',monospace", color: "#a78bfa" }}>class_weight="balanced"</code>.
                It operates on a 2272-dimensional one-hot + scaled feature vector (2240 products × 20 stores × 2 promos × 3 weathers + 7 numeric).
                The prediction threshold is 0.5.
              </div>
            </div>
          </div>
        )}
      </main>
    </div>
  );
}


const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<App />);
