/* ========================================================================
   LUMINA — Performance Tachometer (FPS gauge + warnings + quick fixes)
   Self-mounting floating panel. Click to expand for per-FX breakdown.
   ======================================================================== */
(function () {
  const { useState, useEffect, useRef } = React;

  function PerfGauge() {
    const [open, setOpen] = useState(false);
    const [autoProtect, setAutoProtect] = useState(false);
    const [, tick] = useState(0);
    const lastWarn = useRef(0);
    const dismissed = useRef(false);

    useEffect(() => {
      const id = setInterval(() => tick(n => n + 1), 200);
      return () => clearInterval(id);
    }, []);

    // auto-protect: when FPS drops, disable heaviest FX
    useEffect(() => {
      if (!autoProtect) return;
      const id = setInterval(() => {
        const P = window.Perf, Prog = window.Prog;
        if (!P || !Prog) return;
        if (P.fps < 28 && performance.now() - lastWarn.current > 2000) {
          const worst = P.worstFX();
          if (worst) {
            const fxId = worst[0].split("|")[0];
            const fx = Prog.fxChain.find(f => f.id === fxId);
            if (fx && fx.enabled) {
              Prog.updateFX(fxId, { enabled: false });
              lastWarn.current = performance.now();
            }
          }
        }
      }, 500);
      return () => clearInterval(id);
    }, [autoProtect]);

    const P = window.Perf;
    if (!P) return null;
    const fps = P.fps || 60;
    const status = fps >= 55 ? "good" : fps >= 35 ? "warn" : "bad";
    const color = status === "good" ? "#7cff4f" : status === "warn" ? "#ffae3a" : "#ff3b3b";
    const ringPct = Math.min(1, fps / 60);

    // Compact gauge — small + dismissed unless trouble
    if (!open) {
      // Hidden by default when FPS is healthy; only shows when FPS drops
      if (status === "good" && dismissed.current) return null;
      return (
        <button
          onClick={() => setOpen(true)}
          style={{
            position: "fixed", top: 80, left: 18, zIndex: 597,
            padding: "5px 10px", border: "none", borderRadius: 6,
            background: status === "good"
              ? "linear-gradient(180deg, var(--panel-hi), var(--panel))"
              : `linear-gradient(180deg, ${color}40, ${color}20)`,
            color, cursor: "pointer",
            fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 11,
            boxShadow: status === "good"
              ? "var(--nshadow-out-sm)"
              : `0 0 0 1px ${color}66, 0 0 10px ${color}33`,
            textShadow: `0 0 4px ${color}80`,
            display: "flex", alignItems: "center", gap: 6,
          }}
          title={`${fps.toFixed(0)} FPS · click for details${status !== "good" ? " · performance issue" : ""}`}>
          <span style={{
            width: 6, height: 6, borderRadius: "50%",
            background: color, boxShadow: `0 0 6px ${color}`,
            animation: status === "bad" ? "pulse 0.8s infinite" : "none",
          }} />
          {fps.toFixed(0)} fps
          {status !== "good" && (
            <button onClick={(e) => { e.stopPropagation(); dismissed.current = true; tick(n => n+1); }}
              style={{ border: "none", background: "transparent", color, cursor: "pointer",
                fontSize: 11, padding: 0, marginLeft: 4, opacity: 0.6 }}>×</button>
          )}
        </button>
      );
    }

    // Expanded panel
    const fxBreakdown = Object.entries(P.fxTimes || {}).sort((a, b) => b[1] - a[1]).slice(0, 8);
    const totalFX = fxBreakdown.reduce((sum, [, ms]) => sum + ms, 0);

    return (
      <div style={{
        position: "fixed", top: 80, left: 18, zIndex: 597,
        width: 280,
        background: "linear-gradient(180deg, var(--panel-hi), var(--panel-lo))",
        borderRadius: 10,
        boxShadow: `0 20px 50px rgba(0,0,0,0.7), 0 0 0 2px ${color}, 0 0 18px ${color}44`,
      }}>
        {/* Header */}
        <div style={{
          padding: "10px 12px",
          display: "flex", alignItems: "center", gap: 10,
          borderBottom: "1px solid rgba(255,255,255,0.06)",
          background: `linear-gradient(180deg, ${color}22, transparent)`,
        }}>
          <div style={{ position: "relative", width: 44, height: 44 }}>
            <svg width="44" height="44" viewBox="0 0 56 56">
              <circle cx="28" cy="28" r="22" fill="none"
                stroke="rgba(0,0,0,0.6)" strokeWidth="6" />
              <circle cx="28" cy="28" r="22" fill="none"
                stroke={color} strokeWidth="6" strokeLinecap="round"
                strokeDasharray={`${ringPct * 138.2} 138.2`}
                transform="rotate(-90 28 28)"
                style={{ filter: `drop-shadow(0 0 6px ${color})` }} />
            </svg>
            <div style={{
              position: "absolute", inset: 0,
              display: "grid", placeItems: "center",
              fontFamily: "var(--font-mono)", fontWeight: 700, fontSize: 11,
              color, textShadow: `0 0 6px ${color}`,
            }}>
              {fps.toFixed(0)}
            </div>
          </div>
          <div style={{ flex: 1 }}>
            <div style={{
              fontFamily: "var(--font-display)", fontWeight: 800, fontSize: 11,
              letterSpacing: "0.18em", textTransform: "uppercase", color,
              textShadow: `0 0 4px ${color}80`,
            }}>Performance</div>
            <div style={{
              fontFamily: "var(--font-mono)", fontSize: 9, color: "var(--ink-dim)",
              marginTop: 2,
            }}>
              {P.frameTime?.toFixed(1)} ms/frame · {status === "good" ? "smooth" :
                status === "warn" ? "marginal" : "stuttering"}
            </div>
          </div>
          <button data-lum-close="1" className="nbtn compact" onClick={() => setOpen(false)} style={{ padding: "3px 7px" }}>×</button>
        </div>

        {/* Warning banner */}
        {status !== "good" && (
          <div style={{
            padding: "8px 12px", margin: 8,
            background: status === "bad" ? "rgba(255,59,59,0.12)" : "rgba(255,174,58,0.1)",
            border: `1px solid ${color}66`,
            borderRadius: 6,
            display: "flex", alignItems: "center", gap: 8,
            fontSize: 10, color: "var(--ink-dim)", lineHeight: 1.4,
          }}>
            <span style={{ fontSize: 16, color }}>⚠</span>
            <div>
              <b style={{ color }}>
                {status === "bad" ? "Performance critical" : "Performance marginal"}
              </b>
              <br/>
              {fxBreakdown.length > 0 ? `Heaviest: ${fxBreakdown[0][0].split("|")[1]}` : "Reduce effects or density"}
            </div>
          </div>
        )}

        {/* FX breakdown */}
        <div style={{ padding: "0 12px 8px" }}>
          <div className="cap" style={{ marginBottom: 4 }}>FX Cost (ms / frame)</div>
          {fxBreakdown.length === 0 && (
            <div style={{ fontSize: 9, color: "var(--ink-faint)", padding: "8px 0" }}>
              No FX active. All time spent in visualizer.
            </div>
          )}
          {fxBreakdown.map(([key, ms]) => {
            const [fxId, fxType] = key.split("|");
            const isBig = ms > 4;
            return (
              <div key={key} style={{
                display: "grid", gridTemplateColumns: "1fr auto 50px auto", gap: 6,
                alignItems: "center", marginBottom: 4,
                padding: "4px 6px", borderRadius: 4,
                background: isBig ? "rgba(255,59,59,0.08)" : "transparent",
              }}>
                <span style={{
                  fontFamily: "var(--font-mono)", fontSize: 10,
                  color: isBig ? "var(--led-red)" : "var(--ink)",
                  whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis",
                }}>{fxType || fxId}</span>
                <div style={{
                  width: 60, height: 4, borderRadius: 2,
                  background: "rgba(0,0,0,0.5)", overflow: "hidden",
                }}>
                  <div style={{
                    width: `${Math.min(100, ms * 10)}%`, height: "100%",
                    background: isBig ? "#ff3b3b" : ms > 2 ? "#ffae3a" : "#7cff4f",
                    boxShadow: `0 0 4px currentColor`,
                  }} />
                </div>
                <span style={{
                  fontFamily: "var(--font-mono)", fontSize: 9,
                  color: isBig ? "var(--led-red)" : "var(--ink-dim)",
                  textAlign: "right",
                }}>{ms.toFixed(1)}ms</span>
                <button className="nbtn compact danger"
                  style={{ padding: "1px 5px", fontSize: 8 }}
                  onClick={() => window.Prog?.updateFX(fxId, { enabled: false })}
                  title="Disable this FX">×</button>
              </div>
            );
          })}
          {totalFX > 0 && (
            <div style={{ fontSize: 9, color: "var(--ink-faint)", marginTop: 4, textAlign: "right" }}>
              Total FX cost: <b style={{ color: "var(--accent)" }}>{totalFX.toFixed(1)}ms</b>
            </div>
          )}
        </div>

        {/* Quick fixes */}
        <div style={{ padding: "0 12px 12px" }}>
          <div className="cap" style={{ marginBottom: 6 }}>Quick Fixes</div>
          <div style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: 4 }}>
            <button className="nbtn compact danger"
              onClick={() => window.Prog && (window.Prog.fxChain.forEach(f => f.enabled = false), window.Prog.emit())}>
              Disable all FX
            </button>
            <button className="nbtn compact"
              onClick={() => {
                if (window.Prog) {
                  window.Prog.behaviors.forEach(b => b.enabled = false);
                  window.Prog.emit();
                }
              }}>
              Disable Behaviors
            </button>
            <button className="nbtn compact"
              onClick={() => {
                if (window.Prog?.cloner) window.Prog.cloner.enabled = false;
                window.Prog?.emit();
              }}>
              Disable Cloner
            </button>
            <button className={`nbtn compact ${autoProtect ? "glow pressed" : ""}`}
              onClick={() => setAutoProtect(v => !v)}>
              Auto-protect {autoProtect ? "ON" : "OFF"}
            </button>
          </div>
        </div>

        {/* Diagnostic line */}
        <div style={{
          padding: "6px 12px",
          background: "linear-gradient(180deg, var(--panel-lo), #0a0a0c)",
          fontFamily: "var(--font-mono)", fontSize: 8.5, color: "var(--ink-faint)",
          textAlign: "center",
          borderTop: "1px solid rgba(255,255,255,0.04)",
        }}>
          Behaviors {window.Prog?.behaviors?.length || 0} · FX {window.Prog?.fxChain?.length || 0} ·
          Cloner {window.Prog?.cloner?.enabled ? "ON" : "off"} · Strobo {window.Strobo?.enabled ? "ON" : "off"}
        </div>
      </div>
    );
  }

  function mount() {
    if (!window.React || !window.ReactDOM) { setTimeout(mount, 100); return; }
    let host = document.getElementById("__perf_panel");
    if (!host) {
      host = document.createElement("div");
      host.id = "__perf_panel";
      document.body.appendChild(host);
    }
    ReactDOM.createRoot(host).render(<PerfGauge />);
  }
  if (document.readyState === "complete" || document.readyState === "interactive") setTimeout(mount, 900);
  else document.addEventListener("DOMContentLoaded", () => setTimeout(mount, 900));
})();
