// ============================================================
// Shared UI primitives + HUD shell
// ============================================================
const { useState, useEffect, useRef, useMemo, useCallback } = React;

function useInterval(cb, ms) {
  const ref = useRef(cb);
  useEffect(() => { ref.current = cb; }, [cb]);
  useEffect(() => {
    if (ms == null) return;
    const id = setInterval(() => ref.current(), ms);
    return () => clearInterval(id);
  }, [ms]);
}

function useTick(speed = 1) {
  const [t, setT] = useState(0);
  const raf = useRef(0);
  const last = useRef(performance.now());
  useEffect(() => {
    let alive = true;
    const step = (now) => {
      if (!alive) return;
      const dt = (now - last.current) / 1000;
      last.current = now;
      setT((tt) => tt + dt * speed);
      raf.current = requestAnimationFrame(step);
    };
    raf.current = requestAnimationFrame(step);
    return () => { alive = false; cancelAnimationFrame(raf.current); };
  }, [speed]);
  return t;
}

function Corners() {
  return (
    <>
      <div className="bp-corner tl"></div>
      <div className="bp-corner tr"></div>
      <div className="bp-corner bl"></div>
      <div className="bp-corner br"></div>
    </>
  );
}

function BrandMark() {
  return (
    <svg width="22" height="22" viewBox="0 0 22 22" fill="none">
      <rect x="2.5" y="2.5" width="17" height="17" stroke="currentColor" strokeWidth="1"/>
      <rect x="6" y="6" width="10" height="10" stroke="currentColor" strokeWidth="0.8" opacity="0.6"/>
      <rect x="9.5" y="9.5" width="3" height="3" fill="currentColor"/>
      <line x1="0" y1="11" x2="2.5" y2="11" stroke="currentColor" strokeWidth="0.8"/>
      <line x1="19.5" y1="11" x2="22" y2="11" stroke="currentColor" strokeWidth="0.8"/>
      <line x1="11" y1="0" x2="11" y2="2.5" stroke="currentColor" strokeWidth="0.8"/>
      <line x1="11" y1="19.5" x2="11" y2="22" stroke="currentColor" strokeWidth="0.8"/>
    </svg>
  );
}

function Icon({ kind, size = 16 }) {
  const s = size;
  const common = { width: s, height: s, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 1.4, strokeLinecap: "round", strokeLinejoin: "round" };
  switch (kind) {
    case 'floor':
      return (
        <svg {...common}>
          <rect x="3" y="3" width="18" height="18" />
          <path d="M3 9h18M3 15h18M9 3v18M15 3v18" opacity="0.5" />
          <rect x="5" y="5" width="3" height="3" fill="currentColor" stroke="none" />
        </svg>
      );
    case 'rack':
      return (
        <svg {...common}>
          <rect x="5" y="3" width="14" height="18" />
          <path d="M7 7h10M7 11h10M7 15h10M7 19h10" />
        </svg>
      );
    case 'cfg':
      return (
        <svg {...common}>
          <circle cx="12" cy="12" r="3" />
          <path d="M12 2v3M12 19v3M2 12h3M19 12h3M5 5l2 2M17 17l2 2M5 19l2-2M17 7l2-2" />
        </svg>
      );
    case 'back':
      return (<svg {...common}><path d="M15 6l-6 6 6 6" /></svg>);
    case 'export':
      return (<svg {...common}><path d="M12 3v12M6 9l6-6 6 6M4 21h16" /></svg>);
    case 'import':
      return (<svg {...common}><path d="M12 21V9M6 15l6 6 6-6M4 3h16" /></svg>);
    case 'save':
      return (<svg {...common}><path d="M5 3h11l3 3v15H5z" /><path d="M8 3v5h8V3M8 21v-7h8v7" /></svg>);
    case 'reset':
      return (<svg {...common}><path d="M3 12a9 9 0 1 0 3-6.7L3 8" /><path d="M3 3v5h5" /></svg>);
    case 'add':
      return (<svg {...common}><path d="M12 5v14M5 12h14" /></svg>);
    case 'trash':
      return (<svg {...common}><path d="M4 7h16M9 7V4h6v3M6 7l1 13h10l1-13" /></svg>);
    default: return null;
  }
}

function Clock() {
  const [now, setNow] = useState(new Date());
  useInterval(() => setNow(new Date()), 1000);
  const pad = (n) => String(n).padStart(2, '0');
  const time = `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}`;
  const date = `${now.getFullYear()}.${pad(now.getMonth()+1)}.${pad(now.getDate())}`;
  return (
    <div style={{ display: 'flex', flexDirection: 'column', alignItems: 'flex-end' }}>
      <div className="hud-clock">{time}</div>
      <div className="hud-clock-date">{date} KST</div>
    </div>
  );
}

function TopHUD({ cfg, view }) {
  const health = cfg.groups.map(g => groupHealth(g));
  const totalPorts = health.reduce((s, h) => s + h.ports, 0);
  const susp = health.reduce((s, h) => s + h.susp, 0);
  const powered = health.reduce((s, h) => s + h.on, 0);
  const total = health.reduce((s, h) => s + h.total, 0);
  const uptime = ((total - susp * 0.3) / Math.max(1, total) * 100).toFixed(1);
  return (
    <div className="hud">
      <div className="hud-brand"><BrandMark /></div>
      <div className="hud-center">
        <div className="hud-title">
          <div className="t1">서버실 관제 콘솔 · Server Room NOC</div>
          <div className="t2">SECTOR A-01 · OPS/{view.toUpperCase()}</div>
        </div>
        <div className="hud-stats">
          <div className="hud-stat"><div className="v">{cfg.groups.length}</div><div className="k">Rack Groups</div></div>
          <div className="hud-stat"><div className="v">{powered}/{total}</div><div className="k">Powered</div></div>
          <div className="hud-stat"><div className="v">{totalPorts}</div><div className="k">Ports</div></div>
          <div className="hud-stat" style={{ color: susp ? 'var(--warn)' : 'var(--ok)' }}>
            <div className="v" style={{ color: 'inherit' }}>{susp}</div>
            <div className="k">Suspicious</div>
          </div>
          <div className="hud-stat"><div className="v">{cfg.robots.length}</div><div className="k">Robots</div></div>
          <div className="hud-stat"><div className="v">{uptime}%</div><div className="k">Integrity</div></div>
        </div>
      </div>
      <div className="hud-right">
        <div className="hud-live">LIVE FEED</div>
        <Clock />
      </div>
    </div>
  );
}

function LeftRail({ view, setView }) {
  const items = [
    { k: 'floor', kr: '평면도',   en: 'FLOOR', icon: 'floor' },
    { k: 'rack',  kr: '랙',     en: 'RACK',  icon: 'rack' },
    { k: 'cfg',   kr: '설정',    en: 'CONFIG',icon: 'cfg' },
  ];
  return (
    <nav className="rail">
      {items.map(it => (
        <button key={it.k} className={`rail-btn ${view === it.k ? 'active' : ''}`} onClick={() => setView(it.k)}>
          <Icon kind={it.icon} size={18} />
          <span className="lbl">{it.en}</span>
        </button>
      ))}
      <div className="rail-spacer" />
      <div className="rail-meta">
        v1.0<br/>NOC-KR
      </div>
    </nav>
  );
}

// Tooltip state hook
function useTooltip() {
  const [tip, setTip] = useState(null);
  const show = (data, e) => {
    setTip({ ...data, x: e.clientX + 14, y: e.clientY + 14 });
  };
  const move = (e) => { if (tip) setTip(t => ({ ...t, x: e.clientX + 14, y: e.clientY + 14 })); };
  const hide = () => setTip(null);
  return { tip, show, move, hide };
}

function Tooltip({ tip }) {
  if (!tip) return null;
  return (
    <div className="tip" style={{ left: tip.x, top: tip.y }}>
      {tip.title && <div className="t-k" style={{ marginBottom: 4 }}>{tip.title}</div>}
      {(tip.rows || []).map((r, i) => (
        <div key={i} className="t-row">
          <span className="t-k">{r[0]}</span>
          <span style={{ color: r[2] || 'var(--fg-0)' }}>{r[1]}</span>
        </div>
      ))}
    </div>
  );
}

Object.assign(window, {
  useInterval, useTick, Corners, BrandMark, Icon, Clock, TopHUD, LeftRail, useTooltip, Tooltip,
});
