/* global React */
const { useState, useMemo, useEffect } = React;

// ---------- Mock PDU data ----------
const PDUS = [
  { id: "pdu-b02-a", rack: "mars-04", room: "B", side: "A", name: "PDU-A", load_w: 4180, load_a: 18.2, max_w: 6400, voltage: 230, temp: 24, status: "ok", trend: "up" },
  { id: "pdu-b02-b", rack: "mars-04", room: "B", side: "B", name: "PDU-B", load_w: 3920, load_a: 17.0, max_w: 6400, voltage: 229, temp: 24, status: "ok", trend: "stable" },
  { id: "pdu-b03-a", rack: "mars-05", room: "B", side: "A", name: "PDU-A", load_w: 5680, load_a: 24.7, max_w: 6400, voltage: 230, temp: 27, status: "warn", trend: "up" },
  { id: "pdu-b03-b", rack: "mars-05", room: "B", side: "B", name: "PDU-B", load_w: 5450, load_a: 23.7, max_w: 6400, voltage: 230, temp: 27, status: "warn", trend: "up" },
  { id: "pdu-b04-a", rack: "mars-07", room: "B", side: "A", name: "PDU-A", load_w: 2780, load_a: 12.1, max_w: 6400, voltage: 230, temp: 23, status: "ok", trend: "stable" },
  { id: "pdu-b04-b", rack: "mars-07", room: "B", side: "B", name: "PDU-B", load_w: 2560, load_a: 11.2, max_w: 6400, voltage: 230, temp: 23, status: "ok", trend: "stable" },
  { id: "pdu-d03-a", rack: "titan-33", room: "B", side: "A", name: "PDU-A", load_w: 5920, load_a: 25.7, max_w: 6400, voltage: 228, temp: 31, status: "crit", trend: "up" },
  { id: "pdu-d03-b", rack: "titan-33", room: "B", side: "B", name: "PDU-B", load_w: 5710, load_a: 24.8, max_w: 6400, voltage: 229, temp: 31, status: "warn", trend: "up" },
  { id: "pdu-a01-a", rack: "mercury-11", room: "A", side: "A", name: "PDU-A", load_w: 3240, load_a: 14.1, max_w: 6400, voltage: 230, temp: 22, status: "ok", trend: "stable" },
  { id: "pdu-a01-b", rack: "mercury-11", room: "A", side: "B", name: "PDU-B", load_w: 3120, load_a: 13.6, max_w: 6400, voltage: 230, temp: 22, status: "ok", trend: "stable" },
  { id: "pdu-a05-a", rack: "mercury-15", room: "A", side: "A", name: "PDU-A", load_w: 0, load_a: 0, max_w: 6400, voltage: 0, temp: 0, status: "off", trend: "stable" },
  { id: "pdu-a05-b", rack: "mercury-15", room: "A", side: "B", name: "PDU-B", load_w: 4120, load_a: 17.9, max_w: 6400, voltage: 230, temp: 24, status: "warn", trend: "up" },
];

// Sbykline (1h, 12 points) per pdu
function sbykline(seed, base, vol = 0.1) {
  return Array.from({ length: 24 }, (_, i) => {
    const r = Math.sin(seed * 1.3 + i * 0.7) * vol + Math.cos(seed + i * 0.3) * vol * 0.5;
    return Math.max(0, base * (1 + r));
  });
}

const ratioColor = (r) => {
  if (r < 0.5) return `oklch(0.72 0.14 ${145 - r * 40})`;
  if (r < 0.7) return `oklch(0.78 0.15 95)`;
  if (r < 0.85) return `oklch(0.72 0.17 60)`;
  return `oklch(0.62 0.20 28)`;
};

// ---------- Sbykline component ----------
function Sbykline({ data, color, height = 40, fill = true }) {
  const max = Math.max(...data);
  const min = Math.min(...data);
  const range = max - min || 1;
  const w = 100;
  const pts = data.map((v, i) => `${(i / (data.length - 1)) * w},${height - ((v - min) / range) * (height - 4) - 2}`).join(" ");
  const areaPts = `0,${height} ${pts} ${w},${height}`;
  return (
    <svg width="100%" height={height} viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none" className="sbyk">
      {fill && <polygon points={areaPts} fill={color} fillOpacity="0.15"/>}
      <polyline points={pts} fill="none" stroke={color} strokeWidth="1.5" strokeLinejoin="round" strokeLinecap="round"/>
      <circle cx={w} cy={height - ((data[data.length - 1] - min) / range) * (height - 4) - 2} r="2" fill={color}/>
    </svg>
  );
}

// ---------- Big chart ----------
function BigChart({ data, color, height = 220, label, unit, threshold }) {
  const max = Math.max(...data, threshold || 0) * 1.1;
  const min = 0;
  const range = max - min || 1;
  const w = 800;
  const pts = data.map((v, i) => `${(i / (data.length - 1)) * w},${height - ((v - min) / range) * (height - 30) - 15}`).join(" ");
  const areaPts = `0,${height - 15} ${pts} ${w},${height - 15}`;
  const lastY = height - ((data[data.length - 1] - min) / range) * (height - 30) - 15;
  // Y ticks
  const ticks = [0, 0.25, 0.5, 0.75, 1].map(t => max * t);
  return (
    <div className="big-chart">
      <div className="bc-head">
        <div className="bc-label">{label}</div>
        <div className="bc-now" style={{ color }}>{data[data.length - 1].toFixed(1)}<span>{unit}</span></div>
      </div>
      <svg width="100%" height={height} viewBox={`0 0 ${w} ${height}`} preserveAspectRatio="none" className="bc-svg">
        {/* Grid */}
        {ticks.map((t, i) => {
          const y = height - ((t - min) / range) * (height - 30) - 15;
          return (
            <g key={i}>
              <line x1="0" y1={y} x2={w} y2={y} stroke="var(--border)" strokeWidth="1" strokeDasharray={i === 0 ? "" : "2 3"}/>
              <text x="4" y={y - 3} fontSize="9" fontFamily="JetBrains Mono, monospace" fill="var(--text-dim)">{t.toFixed(0)}{unit}</text>
            </g>
          );
        })}
        {threshold && (
          <g>
            <line x1="0" y1={height - ((threshold - min) / range) * (height - 30) - 15} x2={w} y2={height - ((threshold - min) / range) * (height - 30) - 15} stroke="oklch(0.62 0.20 28)" strokeWidth="1" strokeDasharray="4 4"/>
            <text x={w - 60} y={height - ((threshold - min) / range) * (height - 30) - 19} fontSize="9" fontFamily="JetBrains Mono, monospace" fill="oklch(0.62 0.20 28)">crit {threshold}{unit}</text>
          </g>
        )}
        <polygon points={areaPts} fill={color} fillOpacity="0.18"/>
        <polyline points={pts} fill="none" stroke={color} strokeWidth="1.8" strokeLinejoin="round"/>
        <circle cx={w} cy={lastY} r="3" fill={color}/>
        <circle cx={w} cy={lastY} r="6" fill={color} fillOpacity="0.3"/>
      </svg>
      <div className="bc-x-labels">
        <span>-1h</span><span>-45m</span><span>-30m</span><span>-15m</span><span>maintenant</span>
      </div>
    </div>
  );
}

// ---------- PDU card ----------
function PduCard({ pdu, onClick, selected }) {
  const pct = pdu.load_w / pdu.max_w;
  const off = pdu.status === "off";
  const color = off ? "oklch(0.5 0.005 240)" : ratioColor(pct);
  const data = sbykline(pdu.id.charCodeAt(4), pdu.load_w, 0.08);
  return (
    <div className={`pdu-card ${selected ? "selected" : ""} status-${pdu.status}`} onClick={onClick}>
      <div className="pc-head">
        <div className="pc-id">
          <span className="pc-rack">{pdu.rack}</span>
          <span className="pc-side">{pdu.name}</span>
        </div>
        <div className={`pc-conn ${off ? "off" : "on"}`}>
          <span className="conn-dot"/>
          {off ? "SNMP timeout" : "SNMP OK"}
        </div>
      </div>

      {off ? (
        <div className="pc-off">
          <div className="off-label">Offline</div>
          <div className="off-sub">Last value · 14 min</div>
        </div>
      ) : (
        <>
          <div className="pc-main">
            <div className="pc-val">{pdu.load_w}<span>W</span></div>
            <div className="pc-amps">{pdu.load_a.toFixed(1)} A · {pdu.voltage}V</div>
          </div>
          <div className="pc-bar">
            <div className="pc-bar-fill" style={{ width: `${pct * 100}%`, background: color }}/>
            <div className="pc-bar-tick" style={{ left: "70%" }}/>
            <div className="pc-bar-tick crit" style={{ left: "85%" }}/>
          </div>
          <div className="pc-meta">
            <span>{Math.round(pct * 100)}% de {(pdu.max_w / 1000).toFixed(1)}kW</span>
            <span className={`trend trend-${pdu.trend}`}>
              {pdu.trend === "up" ? "▲" : pdu.trend === "down" ? "▼" : "—"} 1h
            </span>
          </div>

          <div className="pc-sbyk">
            <Sbykline data={data} color={color} height={36}/>
          </div>

          <div className="pc-foot">
            <div className="foot-block">
              <span className="foot-label">TEMP</span>
              <span className="foot-val" style={{ color: pdu.temp > 28 ? "oklch(0.62 0.20 28)" : pdu.temp > 25 ? "oklch(0.78 0.15 75)" : "var(--text)" }}>{pdu.temp}°C</span>
            </div>
            <div className="foot-block">
              <span className="foot-label">PRISES</span>
              <span className="foot-val">18<span>/24</span></span>
            </div>
            <div className="foot-block">
              <span className="foot-label">SALLE</span>
              <span className="foot-val">{pdu.room}</span>
            </div>
          </div>
        </>
      )}
    </div>
  );
}

// ---------- KPIs ----------
function MonKpis({ pdus }) {
  const totalLoad = pdus.reduce((a, p) => a + p.load_w, 0);
  const totalMax = pdus.reduce((a, p) => a + p.max_w, 0);
  const onlineN = pdus.filter(p => p.status !== "off").length;
  const alertN = pdus.filter(p => p.status === "warn" || p.status === "crit").length;
  const tempMax = Math.max(...pdus.filter(p => p.status !== "off").map(p => p.temp));

  return (
    <div className="mon-kpis">
      <div className="mk-card">
        <div className="mk-label">TOTAL DRAW</div>
        <div className="mk-row">
          <div className="mk-val">{(totalLoad / 1000).toFixed(1)}<span>/{(totalMax / 1000).toFixed(0)} kW</span></div>
          <Sbykline data={sbykline(99, totalLoad, 0.05)} color="oklch(0.78 0.12 230)" height={28}/>
        </div>
        <div className="mk-bar"><div style={{ width: `${totalLoad/totalMax*100}%`, background: ratioColor(totalLoad/totalMax) }}/></div>
        <div className="mk-sub">Load mediumne · {Math.round(totalLoad/totalMax*100)}%</div>
      </div>
      <div className="mk-card">
        <div className="mk-label">PDU ONLINE</div>
        <div className="mk-val">{onlineN}<span>/{pdus.length}</span></div>
        <div className="mk-sub">{pdus.length - onlineN} offline · polling 30 s</div>
      </div>
      <div className="mk-card">
        <div className="mk-label">TEMP MAX</div>
        <div className="mk-val" style={{ color: tempMax > 28 ? "oklch(0.62 0.20 28)" : tempMax > 25 ? "oklch(0.78 0.15 75)" : "var(--text)" }}>{tempMax}°<span>C</span></div>
        <div className="mk-sub">Probe titan-33 · threshold critical 30°</div>
      </div>
      <div className="mk-card">
        <div className="mk-label">ACTIVE ALERTS</div>
        <div className="mk-val" style={{ color: alertN > 0 ? "oklch(0.62 0.20 28)" : "var(--ok)" }}>{alertN}</div>
        <div className="mk-sub">2 criticals · 3 warnings</div>
      </div>
      <div className="mk-card">
        <div className="mk-label">PUE INSTANTANÉ</div>
        <div className="mk-val">1.42</div>
        <div className="mk-sub">vs target 1.50 · -0.08</div>
      </div>
    </div>
  );
}

// ---------- Outlets grid ----------
function OutletsGrid({ pdu }) {
  const outlets = Array.from({ length: 24 }, (_, i) => {
    const r = Math.sin(pdu.id.charCodeAt(4) + i * 1.7) * 0.5 + 0.5;
    const used = r > 0.25;
    return { idx: i + 1, used, load: used ? Math.round(60 + r * 280) : 0, host: used ? `srv-lyon-${pdu.rack.toLowerCase()}-${i+1}` : null };
  });
  return (
    <div className="outlets">
      <div className="outlets-head">
        <div className="oh-title">Prises ({pdu.name})</div>
        <div className="oh-sub">{outlets.filter(o => o.used).length}/24 usedes</div>
      </div>
      <div className="outlets-grid">
        {outlets.map(o => (
          <div key={o.idx} className={`outlet ${o.used ? "used" : "free"}`} title={o.host || `Prise ${o.idx} free`}>
            <span className="ol-idx">{String(o.idx).padStart(2, "0")}</span>
            <span className={`ol-led ${o.used ? "on" : "off"}`}/>
            <span className="ol-load">{o.used ? `${o.load}W` : "—"}</span>
            {o.used && <span className="ol-host">{o.host}</span>}
          </div>
        ))}
      </div>
    </div>
  );
}

// ---------- Alerts strip ----------
function AlertsStrip() {
  const alerts = [
    { id: 1, sev: "crit", source: "PDU-A · titan-33", msg: "Load > 90% (5920W / 6400W)", time: "4 min ago", new: true },
    { id: 2, sev: "crit", source: "Probe titan-33", msg: "Temperature 31°C (threshold 30°C)", time: "12 min" },
    { id: 3, sev: "warn", source: "PDU-A · mars-05", msg: "Load > 85% pendant 15 min", time: "22 min" },
    { id: 4, sev: "warn", source: "PDU-B · mercury-15", msg: "Unbalanced A/B > 100%", time: "41 min" },
    { id: 5, sev: "warn", source: "PDU-A · mercury-15", msg: "SNMP timeout · 14 min", time: "14 min" },
  ];
  return (
    <div className="alerts-strip">
      <div className="as-head">
        <div className="as-title">Active alerts <span className="as-count">{alerts.length}</span></div>
        <a href="#" className="as-link">View alles →</a>
      </div>
      <ul className="as-list">
        {alerts.map(a => (
          <li key={a.id} className={`alert-row sev-${a.sev}`}>
            <span className={`sev-dot sev-${a.sev}`}/>
            <span className="al-source">{a.source}</span>
            <span className="al-msg">{a.msg}</span>
            <span className="al-time">{a.time}</span>
            {a.new && <span className="badge-new">NEW</span>}
            <button className="btn ghost ack">Acknowledge</button>
          </li>
        ))}
      </ul>
    </div>
  );
}

// ---------- Main monitoring view ----------
function VueMonitoring() {
  const [scope, setScope] = useState("all");
  const [view, setView] = useState("grid");
  const [selected, setSelected] = useState(PDUS[6]); // titan-33-A by default (critical)
  const [search, setSearch] = useState("");

  const filtered = useMemo(() => {
    return PDUS.filter(p => {
      if (scope !== "all" && p.room !== scope) return false;
      if (search && !`${p.rack} ${p.name}`.toLowerCase().includes(search.toLowerCase())) return false;
      return true;
    });
  }, [scope, search]);

  const sel = selected;

  return (
    <div className="mon-view" data-screen-label="Monitoring PDU & energy">
      {/* Head */}
      <div className="mon-head">
        <div className="mon-title-block">
          <div className="mon-bc">
            <a href="room.html">Site mars-7</a>
            <span>›</span>
            <span className="bc-current">Monitoring PDU & energy</span>
          </div>
          <h1>Real-time monitoring</h1>
          <div className="mon-meta">
            <span className="dot-pulse"/>
            <span>SNMP active · refresh 5s</span>
            <span className="meta-sep">·</span>
            <span>12 PDU monitored</span>
            <span className="meta-sep">·</span>
            <span>last update : <b>2 s</b></span>
          </div>
        </div>
        <div className="mon-actions">
          <div className="seg">
            <button className={scope === "all" ? "active" : ""} onClick={() => setScope("all")}>All</button>
            <button className={scope === "A" ? "active" : ""} onClick={() => setScope("A")}>Hall A</button>
            <button className={scope === "B" ? "active" : ""} onClick={() => setScope("B")}>Hall B</button>
          </div>
          <div className="seg">
            <button className={view === "grid" ? "active" : ""} onClick={() => setView("grid")}>Grid</button>
            <button className={view === "list" ? "active" : ""} onClick={() => setView("list")}>List</button>
          </div>
          <input className="mon-search" placeholder="Filter rack / PDU…" value={search} onChange={e => setSearch(e.target.value)}/>
          <button className="btn">Configure thresholds</button>
          <button className="btn primary">Export CSV</button>
        </div>
      </div>

      <MonKpis pdus={filtered}/>

      <AlertsStrip/>

      <div className="mon-body">
        <div className="mon-left">
          <div className="ml-head">
            <div className="ml-title">PDU monitored</div>
            <div className="ml-sub">{filtered.length} units</div>
          </div>
          {view === "grid" ? (
            <div className="pdu-grid">
              {filtered.map(p => (
                <PduCard key={p.id} pdu={p} selected={sel?.id === p.id} onClick={() => setSelected(p)}/>
              ))}
            </div>
          ) : (
            <table className="pdu-table">
              <thead>
                <tr>
                  <th>Rack</th><th>PDU</th><th>Load</th><th>%</th><th>Amps</th><th>Volt</th><th>Temp</th><th>État</th><th></th>
                </tr>
              </thead>
              <tbody>
                {filtered.map(p => {
                  const pct = p.load_w / p.max_w;
                  return (
                    <tr key={p.id} className={sel?.id === p.id ? "selected" : ""} onClick={() => setSelected(p)}>
                      <td><b>{p.rack}</b></td>
                      <td>{p.name}</td>
                      <td><b>{p.load_w}W</b></td>
                      <td>
                        <div className="row-bar"><div style={{ width: `${pct*100}%`, background: p.status === "off" ? "oklch(0.5 0.005 240)" : ratioColor(pct) }}/></div>
                      </td>
                      <td>{p.load_a.toFixed(1)} A</td>
                      <td>{p.voltage}V</td>
                      <td style={{ color: p.temp > 28 ? "oklch(0.62 0.20 28)" : "" }}>{p.status === "off" ? "—" : `${p.temp}°C`}</td>
                      <td><span className={`pill pill-${p.status}`}>{p.status === "ok" ? "OK" : p.status === "warn" ? "WARN" : p.status === "crit" ? "CRIT" : "OFF"}</span></td>
                      <td><button className="btn ghost xs">Detail</button></td>
                    </tr>
                  );
                })}
              </tbody>
            </table>
          )}
        </div>

        {/* Right: detail PDU */}
        <aside className="mon-right">
          {sel && (
            <>
              <div className="mr-head">
                <div>
                  <div className="mr-title">{sel.rack} · {sel.name}</div>
                  <div className="mr-sub">Eaton ePDU G3 · 32A single-phase · firmware 4.2.1</div>
                </div>
                <span className={`pill pill-${sel.status} lg`}>{sel.status === "ok" ? "OK" : sel.status === "warn" ? "WARN" : sel.status === "crit" ? "CRITIQUE" : "OFFLINE"}</span>
              </div>

              <div className="mr-tabs">
                <button className="active">Overview</button>
                <button>History</button>
                <button>Prises</button>
                <button>Alerts</button>
              </div>

              <div className="mr-charts">
                <BigChart label="Load (W)" data={sbykline(sel.id.charCodeAt(4), sel.load_w || 100, 0.08)} color={ratioColor(sel.load_w / sel.max_w)} unit="W" threshold={5440}/>
                <div className="chart-row">
                  <BigChart label="Current (A)" data={sbykline(sel.id.charCodeAt(4) + 3, sel.load_a || 1, 0.06)} color="oklch(0.78 0.14 290)" height={140} unit="A"/>
                  <BigChart label="Temperature (°C)" data={sbykline(sel.id.charCodeAt(4) + 7, sel.temp || 20, 0.04)} color={sel.temp > 28 ? "oklch(0.62 0.20 28)" : "oklch(0.78 0.16 145)"} height={140} unit="°C" threshold={30}/>
                </div>
              </div>

              <OutletsGrid pdu={sel}/>

              <div className="mr-bottom">
                <div className="mr-info">
                  <div className="mr-info-title">Login</div>
                  <ul className="mr-kv">
                    <li><span>IP</span><b>10.42.{sel.room === "A" ? "1" : "2"}.{sel.rack.slice(-2)}</b></li>
                    <li><span>SNMP</span><b>v3 · authPriv</b></li>
                    <li><span>Polling</span><b>30 s</b></li>
                    <li><span>Last response</span><b>2 s</b></li>
                  </ul>
                  <button className="btn">Tester la connection</button>
                </div>
                <div className="mr-info">
                  <div className="mr-info-title">Thresholds configured</div>
                  <ul className="mr-kv">
                    <li><span>Load warning</span><b>70%</b></li>
                    <li><span>Load critical</span><b>85%</b></li>
                    <li><span>Temp warning</span><b>27°C</b></li>
                    <li><span>Temp critical</span><b>30°C</b></li>
                  </ul>
                  <button className="btn">Edit thresholds</button>
                </div>
              </div>
            </>
          )}
        </aside>
      </div>
    </div>
  );
}

window.VueMonitoring = VueMonitoring;
