/* eslint-disable */
const { useState, useEffect, useMemo, useRef } = React;

/* =====================================================================
   PLACEHOLDER DATA — replace with API fetch in Claude Code step
   --------------------------------------------------------------------
   All rendering is driven off these constants. To wire to a real
   backend, swap each constant for the result of `await fetch(...)`.
   ===================================================================== */

const HOST = {
  name: "martigserver",
  os: "Ubuntu 22.04.4 LTS",
  kernel: "Linux 5.15.0-101-generic x86_64",
  cpuModel: "AMD Ryzen 5 3600 6-Core @ 3.6GHz",
  uptimeSec: 14 * 86400 + 6 * 3600 + 22 * 60 + 11,
};

const HEALTH = {
  allNominal: true,    // flip to false to show down-state banner
  downCount: 0,
};

const SYSTEM_METRICS = {
  cpu: {
    percent: 23,
    cores: 12,           // 6c / 12t
    loadAvg: [0.84, 0.91, 0.77],
    tempC: 54,
  },
  ram: {
    usedGB: 14.2,
    totalGB: 24.0,
    swapUsedGB: 0.4,
    swapTotalGB: 8.0,
  },
  disks: [
    { mount: "/",          label: "OS",         usedGB: 38.2,  totalGB: 256.0,  fs: "ext4" },
    { mount: "/mnt/media", label: "MEDIA",      usedGB: 7340,  totalGB: 8000,   fs: "ext4" },
    { mount: "/mnt/data",  label: "DATA",       usedGB: 1820,  totalGB: 4000,   fs: "ext4" },
    { mount: "/mnt/backup",label: "BACKUP",     usedGB: 920,   totalGB: 2000,   fs: "btrfs" },
  ],
  net: {
    iface: "enp4s0",
    rxMbps: 4.21,
    txMbps: 1.07,
    publicIp: "73.211.xxx.xxx",
    lanIp: "192.168.1.42",
  },
};

const SERVICES = [
  // MEDIA / ARR
  { name: "Jellyfin",        url: "https://jellyfin.marti.house",         category: "MEDIA / ARR STACK", status: "up",   responseMs:  41, lanOnly: false, note: "media server" },
  { name: "Sonarr",          url: "https://sonarr.marti.house",           category: "MEDIA / ARR STACK", status: "up",   responseMs:  62, lanOnly: false, note: "tv" },
  { name: "Radarr",          url: "https://radarr.marti.house",           category: "MEDIA / ARR STACK", status: "up",   responseMs:  58, lanOnly: false, note: "movies" },
  { name: "Prowlarr",        url: "https://prowlarr.marti.house",         category: "MEDIA / ARR STACK", status: "down", responseMs:  -1, lanOnly: false, note: "indexer mgr" },
  { name: "qBittorrent",     url: "http://192.168.1.42:8080",             category: "MEDIA / ARR STACK", status: "up",   responseMs:  12, lanOnly: true,  note: "client" },
  { name: "Audiobookshelf",  url: "https://audiobookshelf.marti.house",   category: "MEDIA / ARR STACK", status: "up",   responseMs:  73, lanOnly: false, note: "books" },

  // GAME SERVERS
  { name: "Minecraft",       url: "minecraft.marti.house:25566",          category: "GAME SERVERS",      status: "up",   responseMs:  24, lanOnly: false, players: 3, max: 20, version: "Fabric 1.21.11" },
  { name: "BlueMap",         url: "https://bluemap.marti.house",          category: "GAME SERVERS",      status: "up",   responseMs:  88, lanOnly: false, note: "live map" },
  { name: "Satisfactory",    url: "satisfactory.marti.house:7777",        category: "GAME SERVERS",      status: "checking", responseMs: -1, lanOnly: false, note: "dedicated" },

  // SYSTEM / ADMIN
  { name: "MC Server Dashboard", url: "https://mcadmin.marti.house",      category: "SYSTEM / ADMIN",    status: "up",   responseMs:  31, lanOnly: false, note: "admin panel" },
];

const CONTAINERS = [
  { name: "jellyfin",       image: "lscr.io/linuxserver/jellyfin",      state: "up",        uptime: "UP 14d",   cpu: 8.4,  mem: "1.2G" },
  { name: "sonarr",         image: "lscr.io/linuxserver/sonarr",        state: "up",        uptime: "UP 14d",   cpu: 0.3,  mem: "248M" },
  { name: "radarr",         image: "lscr.io/linuxserver/radarr",        state: "up",        uptime: "UP 14d",   cpu: 0.4,  mem: "264M" },
  { name: "prowlarr",       image: "lscr.io/linuxserver/prowlarr",      state: "restarting",uptime: "RESTART 4x",cpu: 0.0,  mem: "—" },
  { name: "qbittorrent",    image: "lscr.io/linuxserver/qbittorrent",   state: "up",        uptime: "UP 6d",    cpu: 2.1,  mem: "412M" },
  { name: "audiobookshelf", image: "advplyr/audiobookshelf",            state: "up",        uptime: "UP 14d",   cpu: 0.2,  mem: "188M" },
  { name: "minecraft",      image: "itzg/minecraft-server:java21",      state: "up",        uptime: "UP 2d 11h",cpu:11.2,  mem: "6.4G" },
  { name: "bluemap",        image: "ghcr.io/blue-map/cli:latest",       state: "up",        uptime: "UP 2d 11h",cpu: 0.1,  mem: "412M" },
  { name: "nginx",          image: "nginx:1.27-alpine",                 state: "up",        uptime: "UP 14d",   cpu: 0.0,  mem: " 24M" },
  { name: "tailscale",      image: "tailscale/tailscale:stable",        state: "up",        uptime: "UP 14d",   cpu: 0.1,  mem: " 38M" },
  { name: "watchtower",     image: "containrrr/watchtower",             state: "exited",    uptime: "EXIT 130",  cpu: 0.0,  mem: "—" },
];

const CERTS = [
  { domain: "*.marti.house",            issuer: "Let's Encrypt R3", daysLeft: 87 },
  { domain: "jellyfin.marti.house",     issuer: "Let's Encrypt R3", daysLeft: 87 },
  { domain: "audiobookshelf.marti.house",issuer: "Let's Encrypt R3", daysLeft: 64 },
  { domain: "mcadmin.marti.house",      issuer: "Let's Encrypt R3", daysLeft: 12 },
  { domain: "bluemap.marti.house",      issuer: "Let's Encrypt R3", daysLeft: 87 },
];

const RECENT_LOG = [
  { t: "06:14:22", lvl: "INFO",  src: "systemd",   msg: "jellyfin.service: active (running)" },
  { t: "06:14:11", lvl: "WARN",  src: "docker",    msg: "container prowlarr restart count = 4 (last 1h)" },
  { t: "06:13:58", lvl: "INFO",  src: "nginx",     msg: "reload OK — 12 upstreams healthy" },
  { t: "06:12:40", lvl: "INFO",  src: "cron",      msg: "borg backup /mnt/data → completed (28.4GB delta)" },
  { t: "06:10:02", lvl: "ERROR", src: "prowlarr",  msg: "indexer 'nyaa' returned 503; backing off 5m" },
  { t: "06:08:55", lvl: "INFO",  src: "tailscale", msg: "peer iphone-marti reconnected from 73.x.x.x" },
];

/* ===================================================================== */
/*  Helpers                                                              */
/* ===================================================================== */

function fmtUptime(sec){
  const d = Math.floor(sec/86400);
  const h = Math.floor((sec%86400)/3600);
  const m = Math.floor((sec%3600)/60);
  return `${d}d ${h}h ${m}m`;
}
function pad(n, w=2){ return String(n).padStart(w,"0"); }
function fmtBytesGB(g){
  if (g >= 1000) return `${(g/1000).toFixed(2)}TB`;
  return `${g.toFixed(1)}GB`;
}
function pct(used, total){ return total === 0 ? 0 : (used/total)*100; }

// Block bar made of ASCII blocks. Returns the bar string.
// uses ░ ▒ ▓ █ for added texture, but mainly █ vs ░ for legibility
function blockBar(p, width=24){
  const filled = Math.round((p/100) * width);
  return "█".repeat(Math.max(0,Math.min(width,filled))) + "░".repeat(Math.max(0, width - filled));
}

function severityClass(p){
  if (p >= 90) return "alert";
  if (p >= 75) return "warn";
  return "ok";
}

/* ===================================================================== */
/*  Components                                                           */
/* ===================================================================== */

// ── Box-drawing panel ───────────────────────────────────────────────
function Panel({ title, tag, children, style }){
  return (
    <div className="panel" style={style}>
      <span className="corn tl">┌</span><span className="corn tr">┐</span>
      <span className="corn bl">└</span><span className="corn br">┘</span>
      {title && <div className="ptitle">{title}</div>}
      {tag && <div className="ptag">{tag}</div>}
      <div>{children}</div>
    </div>
  );
}

// ── Bar component (uses block chars + numeric) ──────────────────────
function Bar({ percent, width=28, suffix }){
  const sev = severityClass(percent);
  const bar = blockBar(percent, width);
  return (
    <div className="bar tab" style={{display:"flex", alignItems:"baseline", gap:8, fontSize:22}}>
      <span className={sev} style={{letterSpacing:"-0.06em"}}>{bar}</span>
      <span className={"tab " + sev} style={{minWidth:64}}>{percent.toFixed(0)}%</span>
      {suffix && <span className="dim mono-thin">{suffix}</span>}
    </div>
  );
}

// ── Live clock ──────────────────────────────────────────────────────
function useClock(){
  const [now, setNow] = useState(()=>new Date());
  useEffect(()=>{
    const id = setInterval(()=>setNow(new Date()), 1000);
    return ()=>clearInterval(id);
  },[]);
  return now;
}

function fmtTs(d){
  return `${d.getFullYear()}-${pad(d.getMonth()+1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
}

// ── Header bar ──────────────────────────────────────────────────────
function HeaderBar({ uptimeSec }){
  const now = useClock();
  return (
    <div style={{display:"flex", alignItems:"baseline", justifyContent:"space-between", padding:"4px 6px 14px"}}>
      <div style={{fontSize:30, letterSpacing:".06em"}} className="bright">
        ▓▒░ MARTIGSERVER · MONITORING TERMINAL ░▒▓
      </div>
      <div className="mono-thin dim" style={{textAlign:"right", lineHeight:1.5}}>
        <div><span className="dimmer">SYS_TIME</span> &nbsp; {fmtTs(now)}</div>
        <div><span className="dimmer">UPTIME</span> &nbsp;&nbsp;&nbsp; {fmtUptime(uptimeSec + Math.floor((Date.now() - __MOUNT_T)/1000))}</div>
      </div>
    </div>
  );
}
const __MOUNT_T = Date.now();

// ── Health banner ───────────────────────────────────────────────────
function HealthBanner({ services, containers }){
  const downSvcs = services.filter(s=>s.status==="down");
  const restarting = containers.filter(c=>c.state!=="up" && c.state!=="exited");
  const exited = containers.filter(c=>c.state==="exited");
  const downCount = downSvcs.length + restarting.length;
  const ok = downCount === 0;

  return (
    <Panel tag="[ HEALTH / OVERVIEW ]">
      <div style={{display:"flex", alignItems:"center", justifyContent:"space-between", gap:24, flexWrap:"wrap"}}>
        <div style={{fontSize:42, lineHeight:1.05, letterSpacing:".04em"}} className={ok? "ok" : "alert"}>
          {ok
            ? <>[ ALL&nbsp;SYSTEMS&nbsp;NOMINAL ]</>
            : <>[ !! {downCount}&nbsp;{downCount===1?"SERVICE":"SERVICES"}&nbsp;DEGRADED !! ]</>
          }
          <span className="cur" />
        </div>
        <div style={{display:"flex", gap:28}}>
          <Stat label="SERVICES UP"   value={`${services.filter(s=>s.status==="up").length}/${services.length}`} tone={ok?"ok":"warn"} />
          <Stat label="CONTAINERS"    value={`${containers.filter(c=>c.state==="up").length}/${containers.length}`} tone={ok?"ok":"warn"} />
          <Stat label="ALERTS"        value={downCount.toString()} tone={ok?"ok":"alert"} />
          <Stat label="LOAD AVG"      value={SYSTEM_METRICS.cpu.loadAvg.join(" ")} />
        </div>
      </div>
      {!ok && (
        <div className="mono-thin alert" style={{marginTop:14, paddingTop:10, borderTop:"1px dashed var(--alert-dim)"}}>
          ▶ DEGRADED: {downSvcs.map(s=>s.name).concat(restarting.map(c=>c.name+" (container)")).join("  ·  ")}
        </div>
      )}
    </Panel>
  );
}

function Stat({ label, value, tone }){
  return (
    <div style={{textAlign:"left", minWidth:90}}>
      <div className="dimmer mono-thin" style={{fontSize:12, letterSpacing:".08em"}}>{label}</div>
      <div className={"tab " + (tone||"bright")} style={{fontSize:26}}>{value}</div>
    </div>
  );
}

// ── Metric cards ────────────────────────────────────────────────────
function MetricsRow({ m }){
  const ramPct = pct(m.ram.usedGB, m.ram.totalGB);
  const swapPct = pct(m.ram.swapUsedGB, m.ram.swapTotalGB);
  return (
    <div className="grid-3" style={{display:"grid", gridTemplateColumns:"1fr 1fr 1.4fr", gap:14}}>
      <Panel title="CPU" tag="ryzen 5 3600">
        <Bar percent={m.cpu.percent} width={22} suffix={`${m.cpu.cores} threads`} />
        <div className="rule" style={{margin:"8px 0"}}>{"─".repeat(60)}</div>
        <div className="mono-thin" style={{display:"grid", gridTemplateColumns:"auto 1fr", rowGap:4, columnGap:14}}>
          <span className="dimmer">load.avg</span>
          <span className="tab">{m.cpu.loadAvg.map(n=>n.toFixed(2)).join("  ")}  <span className="dim">(1m 5m 15m)</span></span>
          <span className="dimmer">temp</span>
          <span className="tab">{m.cpu.tempC}°C <span className="dim">/ nominal</span></span>
          <span className="dimmer">model</span>
          <span className="tab">AMD Ryzen 5 3600 6c/12t</span>
        </div>
      </Panel>

      <Panel title="MEMORY" tag="24GB DDR4">
        <Bar percent={ramPct} width={22} suffix={`${m.ram.usedGB.toFixed(1)} / ${m.ram.totalGB.toFixed(1)} GB`} />
        <div className="rule" style={{margin:"8px 0"}}>{"─".repeat(60)}</div>
        <div className="mono-thin" style={{display:"grid", gridTemplateColumns:"auto 1fr", rowGap:4, columnGap:14}}>
          <span className="dimmer">free</span>
          <span className="tab">{(m.ram.totalGB - m.ram.usedGB).toFixed(1)} GB</span>
          <span className="dimmer">swap</span>
          <span className="tab">{m.ram.swapUsedGB.toFixed(1)} / {m.ram.swapTotalGB.toFixed(1)} GB <span className="dim">({swapPct.toFixed(0)}%)</span></span>
          <span className="dimmer">cache</span>
          <span className="tab">3.8 GB <span className="dim">reclaimable</span></span>
        </div>
      </Panel>

      <Panel title="DISKS" tag={`${m.disks.length} mounts`}>
        <div style={{display:"flex", flexDirection:"column", gap:6}}>
          {m.disks.map(d=>{
            const p = pct(d.usedGB, d.totalGB);
            const sev = severityClass(p);
            return (
              <div key={d.mount} style={{display:"grid", gridTemplateColumns:"170px 1fr 110px", alignItems:"baseline", gap:10}}>
                <div className="tab nowrap">
                  <span className={"dim"}>{d.mount}</span>
                </div>
                <div className={"bar tab " + sev} style={{letterSpacing:"-.06em", fontSize:22}}>
                  {blockBar(p, 26)}
                </div>
                <div className={"tab mono-thin " + sev} style={{textAlign:"right"}}>
                  {fmtBytesGB(d.usedGB)}/{fmtBytesGB(d.totalGB)} · {p.toFixed(0)}%
                </div>
              </div>
            );
          })}
        </div>
        <div className="rule" style={{margin:"10px 0 6px"}}>{"─".repeat(80)}</div>
        <div className="mono-thin dim" style={{display:"flex", justifyContent:"space-between"}}>
          <span><span className="dimmer">NET</span> {m.net.iface} · ↓ {m.net.rxMbps.toFixed(2)} Mbps · ↑ {m.net.txMbps.toFixed(2)} Mbps</span>
          <span><span className="dimmer">LAN</span> {m.net.lanIp}  <span className="dimmer">WAN</span> {m.net.publicIp}</span>
        </div>
      </Panel>
    </div>
  );
}

// ── Services panel ──────────────────────────────────────────────────
function ServicesPanel({ services }){
  const grouped = useMemo(()=>{
    const out = {};
    services.forEach(s=>{ (out[s.category] = out[s.category]||[]).push(s); });
    return out;
  },[services]);

  return (
    <Panel title="SERVICE ENDPOINTS" tag="[ click row to open ]">
      <div className="grid-svc" style={{display:"grid", gridTemplateColumns:"1.1fr 1fr 1fr", gap:18}}>
        {Object.entries(grouped).map(([cat, items])=>(
          <div key={cat} style={{display:"flex", flexDirection:"column", gap:6}}>
            <div className="bright" style={{fontSize:18, letterSpacing:".08em"}}>
              ▌ {cat}
            </div>
            <div className="rule">{"─".repeat(40)}</div>
            <div style={{display:"flex", flexDirection:"column", gap:8}}>
              {items.map(s => <ServiceRow key={s.name} s={s} />)}
            </div>
          </div>
        ))}
      </div>
    </Panel>
  );
}

function ServiceRow({ s }){
  const isDown = s.status === "down";
  const isCheck = s.status === "checking";
  const isLan = s.lanOnly;

  const dotCls = isDown? "down" : isCheck? "check" : isLan? "lan" : "up";
  const statusLabel = isDown? "DOWN" : isCheck? "CHECKING" : "UP";
  const statusCls = isDown? "alert" : isCheck? "bright" : "ok";

  const Wrapper = isDown ? "div" : "a";
  const wrapperProps = isDown ? {} : { href: s.url.startsWith("http") ? s.url : `http://${s.url}`, target:"_blank", rel:"noreferrer" };

  return (
    <Wrapper
      {...wrapperProps}
      className={"tlink"}
      style={{
        display:"block",
        padding:"6px 10px",
        border:"1px solid " + (isDown? "var(--alert-dim)" : "var(--p-faint)"),
        textDecoration:"none",
        color:"inherit",
        background: isLan ? "rgba(255,176,0,.025)" : isDown ? "rgba(255,59,31,.06)" : "transparent",
        opacity: isLan ? 0.78 : 1,
        cursor: isDown ? "not-allowed" : "pointer",
      }}
    >
      <div style={{display:"flex", alignItems:"baseline", justifyContent:"space-between", gap:8}}>
        <div style={{display:"flex", alignItems:"baseline", gap:6, minWidth:0}}>
          <span className={"dot " + dotCls} />
          <span className={"bright"} style={{fontSize:22}}>{s.name}</span>
          {s.players != null && (
            <span className="mono-thin dim" style={{marginLeft:6}}>
              [{s.players}/{s.max} players]
            </span>
          )}
          {s.version && <span className="mono-thin dim" style={{marginLeft:6}}>{s.version}</span>}
        </div>
        <div className={"tab mono-thin " + statusCls} style={{whiteSpace:"nowrap"}}>
          {isDown ? "✗ DOWN" : isCheck ? "⌖ CHECK" : `${String(s.responseMs).padStart(3," ")}ms`}
        </div>
      </div>
      <div style={{display:"flex", alignItems:"baseline", justifyContent:"space-between", marginTop:2}}>
        <span className="mono-thin dim" style={{overflow:"hidden", textOverflow:"ellipsis", whiteSpace:"nowrap"}}>
          {s.url}
        </span>
        <span className="mono-thin" style={{whiteSpace:"nowrap", marginLeft:8}}>
          {isLan && <span className="warn" title="Not exposed publicly">[LAN-ONLY]</span>}
          {!isLan && !isDown && !isCheck && <span className="dimmer">[{statusLabel}]</span>}
        </span>
      </div>
    </Wrapper>
  );
}

// ── Containers ──────────────────────────────────────────────────────
function ContainersPanel({ containers }){
  return (
    <Panel title="DOCKER CONTAINERS" tag={`${containers.length} running`}>
      <table className="term tab">
        <colgroup>
          <col style={{width:"24px"}} />
          <col style={{width:"22%"}} />
          <col style={{width:"38%"}} />
          <col style={{width:"14%"}} />
          <col style={{width:"8%"}} />
          <col style={{width:"8%"}} />
          <col style={{width:"14%"}} />
        </colgroup>
        <thead>
          <tr>
            <th style={{width:"1%"}}> </th>
            <th>NAME</th>
            <th>IMAGE</th>
            <th>STATE</th>
            <th style={{textAlign:"right"}}>CPU%</th>
            <th style={{textAlign:"right"}}>MEM</th>
            <th>UPTIME</th>
          </tr>
        </thead>
        <tbody>
          {containers.map((c,i)=>{
            const bad = c.state !== "up";
            const dotCls = c.state === "up" ? "up" : c.state === "restarting" ? "check" : "down";
            const stateCls = c.state === "up" ? "ok" : c.state === "restarting" ? "warn" : "alert";
            return (
              <tr key={c.name} className={i%2? "row-alt" : ""}>
                <td><span className={"dot " + dotCls} /></td>
                <td className="bright">{c.name}</td>
                <td className="mono-thin dim">{c.image}</td>
                <td className={stateCls + " upper"}>{c.state}</td>
                <td className="tab" style={{textAlign:"right"}}>{c.cpu.toFixed(1)}</td>
                <td className="tab dim mono-thin" style={{textAlign:"right"}}>{c.mem}</td>
                <td className={"mono-thin " + (bad? stateCls : "dim")}>{c.uptime}</td>
              </tr>
            );
          })}
        </tbody>
      </table>
    </Panel>
  );
}

// ── Certs ───────────────────────────────────────────────────────────
function CertsPanel({ certs }){
  return (
    <Panel title="SSL CERTIFICATES" tag="*.marti.house">
      <div style={{display:"flex", flexDirection:"column", gap:6}}>
        {certs.map(c=>{
          const tone = c.daysLeft <= 14 ? "alert" : c.daysLeft <= 30 ? "warn" : "ok";
          const pctLeft = Math.min(100, (c.daysLeft / 90) * 100);
          return (
            <div key={c.domain} style={{display:"grid", gridTemplateColumns:"1fr 110px 90px", alignItems:"baseline", gap:10}}>
              <div className="bright" style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{c.domain}</div>
              <div className={"bar tab " + tone} style={{letterSpacing:"-.06em", fontSize:20}}>
                {blockBar(pctLeft, 12)}
              </div>
              <div className={"tab " + tone} style={{textAlign:"right"}}>
                {c.daysLeft}d {c.daysLeft <= 14 && "‼"}
              </div>
            </div>
          );
        })}
      </div>
      <div className="rule" style={{margin:"8px 0 4px"}}>{"─".repeat(60)}</div>
      <div className="mono-thin dim">Issued by Let's Encrypt · auto-renew via certbot @ 03:00 UTC daily</div>
    </Panel>
  );
}

// ── Media Stack Activity ────────────────────────────────────────────
function MediaStackPanel({ mediaData }){
  const { sonarr, radarr, jellyfin } = mediaData || {};
  
  return (
    <Panel title="MEDIA STACK ACTIVITY" tag="sonarr • radarr • jellyfin">
      <div className="grid-3" style={{display:"grid", gridTemplateColumns:"1fr 1fr 1fr", gap:18}}>
        {/* Sonarr */}
        <div>
          <div className="dimmer mono-thin upper" style={{fontSize:11, letterSpacing:".1em", marginBottom:8}}>SONARR QUEUE</div>
          {sonarr ? (
            <div style={{fontSize:14, lineHeight:1.4}}>
              <div className="bright tab" style={{fontSize:20, marginBottom:4}}>
                {sonarr.downloading} downloading
              </div>
              <div className="dim">{sonarr.totalItems} total items</div>
              {sonarr.items.slice(0, 3).map((item, i) => (
                <div key={i} style={{fontSize:12, marginTop:6, paddingTop:6, borderTop:"1px dashed var(--p-faint)"}}>
                  <div className="bright" style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>
                    {item.title}
                  </div>
                  <div className="dim">
                    {item.quality} • {item.progress}% • {item.status}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="dim" style={{fontSize:14}}>API key needed</div>
          )}
        </div>

        {/* Radarr */}
        <div>
          <div className="dimmer mono-thin upper" style={{fontSize:11, letterSpacing:".1em", marginBottom:8}}>RADARR QUEUE</div>
          {radarr ? (
            <div style={{fontSize:14, lineHeight:1.4}}>
              <div className="bright tab" style={{fontSize:20, marginBottom:4}}>
                {radarr.downloading} downloading
              </div>
              <div className="dim">{radarr.totalItems} total items</div>
              {radarr.items.slice(0, 3).map((item, i) => (
                <div key={i} style={{fontSize:12, marginTop:6, paddingTop:6, borderTop:"1px dashed var(--p-faint)"}}>
                  <div className="bright" style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>
                    {item.title}
                  </div>
                  <div className="dim">
                    {item.quality} • {item.progress}% • {item.status}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="dim" style={{fontSize:14}}>API key needed</div>
          )}
        </div>

        {/* Jellyfin */}
        <div>
          <div className="dimmer mono-thin upper" style={{fontSize:11, letterSpacing:".1em", marginBottom:8}}>JELLYFIN SESSIONS</div>
          {jellyfin ? (
            <div style={{fontSize:14, lineHeight:1.4}}>
              <div className="bright tab" style={{fontSize:20, marginBottom:4}}>
                {jellyfin.activeSessions} active
              </div>
              <div className="dim">{jellyfin.totalSessions} total sessions</div>
              {jellyfin.sessions.slice(0, 3).map((session, i) => (
                <div key={i} style={{fontSize:12, marginTop:6, paddingTop:6, borderTop:"1px dashed var(--p-faint)"}}>
                  <div className="bright" style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>
                    {session.content}
                  </div>
                  <div className="dim">
                    {session.user} • {session.progress}% • {session.paused ? 'paused' : 'playing'}
                  </div>
                </div>
              ))}
            </div>
          ) : (
            <div className="dim" style={{fontSize:14}}>API key needed</div>
          )}
        </div>
      </div>
    </Panel>
  );
}

// ── Log tail ────────────────────────────────────────────────────────
function LogPanel({ entries }){
  return (
    <Panel title="JOURNAL — LAST 6" tag="journalctl -f">
      <div className="mono-thin" style={{display:"flex", flexDirection:"column", gap:2, fontSize:14, lineHeight:1.45}}>
        {entries.map((e,i)=>{
          const tone = e.lvl === "ERROR" ? "alert" : e.lvl === "WARN" ? "warn" : "dim";
          return (
            <div key={i} style={{display:"grid", gridTemplateColumns:"70px 60px 110px 1fr", gap:8}}>
              <span className="dimmer tab">{e.t}</span>
              <span className={tone + " upper tab"}>{e.lvl}</span>
              <span className="dim">[{e.src}]</span>
              <span className="bright" style={{whiteSpace:"nowrap", overflow:"hidden", textOverflow:"ellipsis"}}>{e.msg}</span>
            </div>
          );
        })}
        <div className="dimmer" style={{marginTop:4}}>
          $ <span className="cur sm" />
        </div>
      </div>
    </Panel>
  );
}

// ── Footer ──────────────────────────────────────────────────────────
function Footer({ lastRefresh, onRefresh, error, host }){
  const now = useClock();
  return (
    <div className="mono-thin" style={{
      display:"flex", justifyContent:"space-between", alignItems:"center",
      padding:"10px 6px 0", color:"var(--p-dim)", fontSize:13, borderTop:"1px dashed var(--p-faint)", marginTop:6
    }}>
      <div style={{display:"flex", gap:18, flexWrap:"wrap"}}>
        <span><span className="dimmer">host:</span> {host.name}</span>
        <span><span className="dimmer">os:</span> {host.os}</span>
        <span><span className="dimmer">kernel:</span> {host.kernel}</span>
        <span><span className="dimmer">tty:</span> /dev/pts/0</span>
      </div>
      <div style={{display:"flex", gap:14, alignItems:"center"}}>
        {error && <span className="alert"><span className="dimmer">api error:</span> {error}</span>}
        <span><span className="dimmer">last refresh:</span> {fmtTs(lastRefresh)}</span>
        <button onClick={onRefresh} style={{
          background:"transparent", border:"1px solid var(--p-dim)", color:"var(--p)",
          font:"inherit", padding:"4px 12px", cursor:"pointer", textShadow:"var(--glow)",
          letterSpacing:".06em"
        }} onMouseOver={e=>e.currentTarget.style.background="rgba(255,176,0,.1)"}
           onMouseOut={e=>e.currentTarget.style.background="transparent"}>
          [ REFRESH ]
        </button>
        <span className="cur sm" />
      </div>
    </div>
  );
}

/* ===================================================================== */
/*  Boot sequence                                                        */
/* ===================================================================== */

const BOOT_LINES = [
  "MARTIGSERVER BIOS v1.4.7 — POST",
  "  CPU.... AMD Ryzen 5 3600 6C/12T  [OK]",
  "  MEM.... 24576 MB DDR4-3200       [OK]",
  "  NET.... enp4s0 link up @ 1 Gbps  [OK]",
  "  DISK... 4 mounts attached        [OK]",
  "",
  "Loading kernel 5.15.0-101-generic ........ [OK]",
  "Mounting filesystems ..................... [OK]",
  "Starting docker.service .................. [OK]",
  "Starting nginx.service ................... [OK]",
  "Starting tailscaled ...................... [OK]",
  "Reading /proc/stat ....................... [OK]",
  "Initializing display ..................... [OK]",
  "",
  "Welcome to MARTIGSERVER. Connecting monitoring terminal ..."
];

function BootOverlay({ onDone }){
  const [shown, setShown] = useState(0);
  const [dismiss, setDismiss] = useState(false);
  const lineCount = BOOT_LINES.length;

  useEffect(()=>{
    if (dismiss) return;
    if (shown >= lineCount){
      const t = setTimeout(()=>onDone(), 300);
      return ()=>clearTimeout(t);
    }
    const t = setTimeout(()=>setShown(s=>s+1), 80);
    return ()=>clearTimeout(t);
  }, [shown, dismiss, lineCount, onDone]);

  useEffect(()=>{
    const onKey = (e)=>{ if (e.key === "Escape" || e.key === " " || e.key === "Enter"){ setDismiss(true); onDone(); } };
    window.addEventListener("keydown", onKey);
    return ()=>window.removeEventListener("keydown", onKey);
  }, [onDone]);

  return (
    <div id="boot" onClick={()=>{ setDismiss(true); onDone(); }}>
      {BOOT_LINES.slice(0, shown).map((l,i)=>(
        <div key={i}>{l || "\u00a0"}</div>
      ))}
      {shown < lineCount && <div><span className="cur" /></div>}
      <div className="skip">press <kbd>SPACE</kbd> / <kbd>ESC</kbd> to skip</div>
    </div>
  );
}

/* ===================================================================== */
/*  Production Dashboard - No Tweaks                                     */
/* ===================================================================== */

/* ===================================================================== */
/*  Root                                                                 */
/* ===================================================================== */

function App(){
  // Removed tweaks panel - production version
  const [booted, setBooted] = useState(false);
  const [lastRefresh, setLastRefresh] = useState(()=>new Date());
  const [dashboardData, setDashboardData] = useState(null);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState(null);

  // No theme tweaking in production version

  // Fetch data from API
  const fetchData = async () => {
    try {
      setLoading(true);
      const response = await fetch('/api/status');
      if (!response.ok) throw new Error('Failed to fetch status');
      const data = await response.json();
      setDashboardData(data);
      setError(null);
    } catch (err) {
      console.error('Error fetching dashboard data:', err);
      setError(err.message);
      // Fallback to static data if API fails
      setDashboardData({
        HOST,
        HEALTH,
        SYSTEM_METRICS,
        SERVICES,
        CONTAINERS,
        CERTS,
        RECENT_LOG,
        MEDIA_STACK: null // No fallback data for media stack
      });
    } finally {
      setLoading(false);
    }
  };

  // Initial fetch and auto-refresh
  useEffect(() => {
    fetchData();
    const interval = setInterval(fetchData, 30000); // Refresh every 30 seconds
    return () => clearInterval(interval);
  }, []);

  const onRefresh = () => {
    setLastRefresh(new Date());
    fetchData();
  };

  // Use API data or fallbacks
  const hostData = dashboardData?.HOST || HOST;
  const healthData = dashboardData?.HEALTH || HEALTH;
  const systemData = dashboardData?.SYSTEM_METRICS || SYSTEM_METRICS;
  const servicesData = dashboardData?.SERVICES || SERVICES;
  const containersData = dashboardData?.CONTAINERS || CONTAINERS;
  const certsData = dashboardData?.CERTS || CERTS;
  const logData = dashboardData?.RECENT_LOG || RECENT_LOG;
  const mediaData = dashboardData?.MEDIA_STACK;

  // Use real service data (no demo tweaking)
  const services = servicesData;

  if (loading) {
    return (
      <div className="crt-screen">
        <div className="crt">
          <div style={{padding: 40, textAlign: 'center', fontSize: 24}}>
            LOADING DASHBOARD DATA<span className="cur" />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="crt-screen">
      {!booted && <BootOverlay onDone={()=>setBooted(true)} />}
      <div className="crt">
        <HeaderBar uptimeSec={hostData.uptimeSec} />
        <div className="col">
          <HealthBanner services={services} containers={containersData} />
          <MetricsRow m={systemData} />
          <ServicesPanel services={services} />
          <MediaStackPanel mediaData={mediaData} />
          <div className="row twocol">
            <div style={{flex:"1.6 1 0", minWidth:0}}>
              <ContainersPanel containers={containersData} />
            </div>
            <div style={{flex:"1 1 0", minWidth:0, display:"flex", flexDirection:"column", gap:14}}>
              <CertsPanel certs={certsData} />
              <LogPanel entries={logData} />
            </div>
          </div>
          <Footer lastRefresh={lastRefresh} onRefresh={onRefresh} error={error} host={hostData} />
        </div>
      </div>

    </div>
  );
}

ReactDOM.createRoot(document.getElementById("root")).render(<App />);
