/* MAINFRAME — main app */
const { useState, useEffect, useRef } = React;

/* ---------- MATRIX RAIN ---------- */
function MatrixRain() {
  const ref = useRef(null);
  useEffect(() => {
    const canvas = ref.current;
    if (!canvas) return;
    const ctx = canvas.getContext('2d');
    let w = window.innerWidth, h = window.innerHeight;
    const dpr = Math.min(window.devicePixelRatio || 1, 2);
    function resize() {
      w = window.innerWidth; h = window.innerHeight;
      canvas.width = w * dpr; canvas.height = h * dpr;
      ctx.setTransform(1,0,0,1,0,0); ctx.scale(dpr, dpr);
    }
    resize();
    window.addEventListener('resize', resize);
    const fontSize = 14;
    const cols = Math.ceil(w / fontSize);
    const drops = Array.from({ length: cols }, () => Math.random() * -h);
    const chars = "01アイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン0123456789#$%&".split("");
    let raf;
    function tick() {
      ctx.fillStyle = 'rgba(3,8,26,0.10)';
      ctx.fillRect(0, 0, w, h);
      ctx.font = `${fontSize}px IBM Plex Mono, monospace`;
      for (let i = 0; i < drops.length; i++) {
        const ch = chars[Math.floor(Math.random() * chars.length)];
        const x = i * fontSize;
        const y = drops[i];
        ctx.fillStyle = Math.random() > 0.96 ? '#b3e5ff' : 'oklch(0.65 0.16 250)';
        ctx.fillText(ch, x, y);
        drops[i] = (y > h && Math.random() > 0.975) ? 0 : y + fontSize;
      }
      raf = requestAnimationFrame(tick);
    }
    tick();
    return () => { cancelAnimationFrame(raf); window.removeEventListener('resize', resize); };
  }, []);
  return <canvas ref={ref} className="matrix" />;
}

/* ---------- NETWORK TOPOLOGY ---------- */
function NetTopology() {
  // 6 nodes around a center hub
  const nodes = [
    { x: 220, y: 140, lbl: "PRG-01", hub: true },
    { x: 60,  y: 50,  lbl: "FIN-N1" },
    { x: 380, y: 50,  lbl: "CRM-N2" },
    { x: 50,  y: 230, lbl: "AI-N3"  },
    { x: 390, y: 230, lbl: "OPS-N4" },
    { x: 220, y: 30,  lbl: "EDGE"   },
    { x: 220, y: 250, lbl: "DB"     },
  ];
  const hub = nodes[0];
  const [pulse, setPulse] = useState(0);
  useEffect(() => {
    const id = setInterval(() => setPulse(p => (p + 1) % 7), 700);
    return () => clearInterval(id);
  }, []);
  return (
    <svg viewBox="0 0 440 280" xmlns="http://www.w3.org/2000/svg">
      <defs>
        <radialGradient id="hubGlow" cx="50%" cy="50%" r="50%">
          <stop offset="0%" stopColor="oklch(0.88 0.14 215)" stopOpacity="0.6"/>
          <stop offset="100%" stopColor="oklch(0.88 0.14 215)" stopOpacity="0"/>
        </radialGradient>
        <filter id="glow">
          <feGaussianBlur stdDeviation="2.5" result="blur"/>
          <feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
        </filter>
      </defs>

      {/* hub glow */}
      <circle cx={hub.x} cy={hub.y} r="40" fill="url(#hubGlow)" />

      {/* links */}
      {nodes.slice(1).map((n, i) => (
        <line
          key={i}
          x1={hub.x} y1={hub.y}
          x2={n.x} y2={n.y}
          stroke={i + 1 === pulse ? 'oklch(0.88 0.14 215)' : 'oklch(0.74 0.19 255 / 0.5)'}
          strokeWidth={i + 1 === pulse ? 1.4 : 0.6}
          strokeDasharray={i + 1 === pulse ? 'none' : '2 3'}
          filter={i + 1 === pulse ? 'url(#glow)' : undefined}
        />
      ))}

      {/* nodes */}
      {nodes.map((n, i) => (
        <g key={i}>
          <circle
            cx={n.x} cy={n.y}
            r={n.hub ? 12 : 6}
            fill={n.hub ? 'oklch(0.88 0.14 215)' : '#0a1024'}
            stroke={n.hub ? 'oklch(0.88 0.14 215)' : 'oklch(0.74 0.19 255)'}
            strokeWidth={n.hub ? 0 : 1.4}
            filter={n.hub ? 'url(#glow)' : undefined}
          />
          {!n.hub && i === pulse && (
            <circle cx={n.x} cy={n.y} r="10" fill="none"
              stroke="oklch(0.88 0.14 215)" strokeWidth="1" opacity="0.7">
              <animate attributeName="r" from="6" to="14" dur="0.7s" />
              <animate attributeName="opacity" from="0.8" to="0" dur="0.7s" />
            </circle>
          )}
          <text
            x={n.x} y={n.y - 12}
            fill={n.hub ? 'oklch(0.88 0.14 215)' : 'oklch(0.74 0.19 255)'}
            fontFamily="IBM Plex Mono, monospace"
            fontSize="9"
            textAnchor="middle"
            letterSpacing="0.5"
          >{n.lbl}</text>
        </g>
      ))}
    </svg>
  );
}

/* ---------- NAV ---------- */
function Nav({ copy, lang, setLang }) {
  const c = copy.nav;
  const [time, setTime] = useState(() => new Date().toLocaleTimeString('cs', { hour: '2-digit', minute: '2-digit', second: '2-digit' }));
  useEffect(() => {
    const id = setInterval(() => setTime(new Date().toLocaleTimeString('cs', { hour: '2-digit', minute: '2-digit', second: '2-digit' })), 1000);
    return () => clearInterval(id);
  }, []);
  return (
    <nav className="nav">
      <div className="container">
        <div className="nav-inner">
          <a href="#top" className="nav-cell brand">OVHL<span className="x">/</span>MAINFRAME</a>
          <a href="#expertise" className="nav-cell">01 · {c.expertise}</a>
          <a href="#process" className="nav-cell">02 · {c.process}</a>
          <a href="#careers" className="nav-cell">03 · {c.careers}</a>
          <div className="nav-spacer"><span className="ok">◉</span> uptime 99.97% · {time}</div>
          <div className="nav-cell lang">
            <button className={lang === 'cs' ? 'active' : ''} onClick={() => setLang('cs')}>CS</button>
            <button className={lang === 'en' ? 'active' : ''} onClick={() => setLang('en')}>EN</button>
          </div>
          <a href="#contact" className="nav-cell cta">{c.cta} →</a>
        </div>
      </div>
    </nav>
  );
}

/* ---------- HERO ---------- */
function Hero({ copy }) {
  const h = copy.hero;
  return (
    <section className="hero" id="top">
      <div className="container">
        <div className="hero-inner">
          <div className="hero-main">
            <div className="hero-conn">
              <span className="pre">$ {h.conn_pre}</span>
              <span>{h.conn_user}</span>
              <span className="sep">·</span>
              <span className="ok">{h.conn_ok}</span>
            </div>
            <pre className="hero-ascii">{h.ascii}</pre>
            <h1>
              {h.h1.map((l, i) => (
                <span className="ln" key={i}>
                  {l.t} {l.em ? <em>{l.em}</em> : <span className="blue">{l.blue}</span>}
                  {l.punct ? <span className="punct">{l.punct}</span> : null}
                  {l.caret ? <span className="caret" /> : null}
                </span>
              ))}
            </h1>
            <p className="hero-sub">
              {h.sub_a}<b>{h.sub_b}</b>{h.sub_c}
            </p>
            <div className="hero-cta">
              <a href="#contact" className="btn-block prim">{h.cta1} →</a>
              <a href="#expertise" className="btn-block">{h.cta2}</a>
              <a href="mailto:ahoj@overheadlabs.com" className="btn-block cyan">{h.cta3} ↗</a>
            </div>
          </div>
          <NetPanel netpanel={copy.netpanel} />
        </div>
        <div className="hero-stats">
          {h.stats.map((s, i) => (
            <div key={i}>
              <div className="l">{s.l}</div>
              <div className="v">{s.em ? <em>{s.v}</em> : s.v}</div>
            </div>
          ))}
        </div>
      </div>
    </section>
  );
}

/* ---------- NETWORK PANEL ---------- */
function NetPanel({ netpanel }) {
  return (
    <div className="netpanel">
      <div className="np-head">
        <span className="ok">{netpanel.title}</span>
        <span style={{ color: 'var(--fg-3)' }}>· {netpanel.tag}</span>
        <span className="right">{netpanel.right}</span>
      </div>
      <div className="np-topology"><NetTopology /></div>
      <div className="np-stats">
        {netpanel.stats.map((s, i) => (
          <div key={i}>
            <div className="l">{s.l}</div>
            <div className="v">{s.em ? <em>{s.v}</em> : s.v}</div>
          </div>
        ))}
      </div>
      <div className="np-log">
        {netpanel.log.map((l, i) => (
          <span className="l" key={i}>
            <span className="ts">{l.ts}</span>
            <span className={l.c}>{l.t}</span>
          </span>
        ))}
      </div>
    </div>
  );
}

/* ---------- PACKETS MARQUEE ---------- */
function Packets({ items }) {
  const loop = [...items, ...items];
  return (
    <div className="packets">
      <div className="packets-track">
        {loop.map((it, i) => (
          <span key={i}>
            <span className="pre">▸</span>
            <span>{it}</span>
            <span className="ok">[OK]</span>
          </span>
        ))}
      </div>
    </div>
  );
}

/* ---------- SECTION HEAD ---------- */
function SHead({ sid, h2a, h2_em, h2_blue, sub }) {
  return (
    <div className="s-head">
      <div>
        <div className="s-id">{sid}</div>
        <h2>{h2a}<br/><em>{h2_em}</em> <span className="blue">{h2_blue}</span></h2>
      </div>
      <p>{sub}</p>
    </div>
  );
}

/* ---------- EXPERTISE ---------- */
function Expertise({ copy }) {
  const e = copy.expertise;
  return (
    <section className="section container" id="expertise">
      <SHead sid={e.sid} h2a={e.h2a} h2_em={e.h2_em} h2_blue={e.h2_blue} sub={e.sub} />
      <div className="exp-grid">
        {e.cards.map((card, i) => (
          <article className="exp-block" key={i}>
            <div className="corner">{card.corner}</div>
            <div className="lbl">{card.lbl}</div>
            <h3>{card.title}</h3>
            <p className="desc">{card.desc}</p>
            <div className="stack">{card.stack.map((s, j) => <span key={j}>{s}</span>)}</div>
            <pre className="ascii-num">{card.ascii}</pre>
          </article>
        ))}
      </div>
    </section>
  );
}

/* ---------- PROCESS ---------- */
function Process({ copy }) {
  const p = copy.process;
  return (
    <section className="section container" id="process">
      <SHead sid={p.sid} h2a={p.h2a} h2_em={p.h2_em} h2_blue={p.h2_blue} sub={p.sub} />
      <div className="proc-pipeline">
        {p.rows.map((r, i) => (
          <div className="proc-row" key={i}>
            <div className="step">{r.step}</div>
            <h4>{r.title}</h4>
            <p>{r.desc}</p>
            <div className="meta">
              <span className="dur">{r.dur}</span>
              <span className="out"><span>output → </span>{r.out}</span>
            </div>
          </div>
        ))}
      </div>
    </section>
  );
}

/* ---------- CAREERS ---------- */
function Careers({ copy }) {
  const c = copy.careers;
  return (
    <section className="section container" id="careers">
      <SHead sid={c.sid} h2a={c.h2a} h2_em={c.h2_em} h2_blue={c.h2_blue} sub={c.sub} />
      <div className="jobs">
        {c.rows.map((r, i) => (
          <a href="#contact" className="job" key={i}>
            <div className="id">{r.id}</div>
            <div className="title">{r.title}</div>
            <div className="stack">{r.stack}</div>
            <div className="where">{r.where}</div>
            <div className="arrow">[ APPLY ↗ ]</div>
          </a>
        ))}
      </div>
      <div className="job-footer">{c.footer}</div>
    </section>
  );
}

/* ---------- CONTACT ---------- */
function Contact({ copy }) {
  const c = copy.contact;
  return (
    <section className="section container" id="contact">
      <div className="contact">
        <div className="contact-inner">
          <div className="s-id">{c.sid}</div>
          <h2>{c.h2a} <span className="email-line"><em>{c.h2_em}</em><span className="blue">{c.h2_blue}</span><span className="punct">{c.h2_punct}</span></span></h2>
          <p>{c.sub}</p>
          <div className="contact-grid">
            {c.items.map((it, i) => (
              <a href={it.href} key={i}>
                <div>
                  <div className="lbl">{it.lbl}</div>
                  <div className="v">{it.v}</div>
                </div>
                <span>↗</span>
              </a>
            ))}
          </div>
        </div>
      </div>
    </section>
  );
}

/* ---------- FOOTER ---------- */
function Footer({ copy }) {
  const f = copy.footer;
  return (
    <footer className="footer">
      <div className="container">
        <div className="footer-grid">
          <div>
            <pre className="ascii-logo">{`╔═══════════════════╗
║  OVHL//MAINFRAME  ║
║  uplink: ready    ║
╚═══════════════════╝`}</pre>
            <div style={{ fontSize: 13, color: 'var(--fg-2)' }}>{f.tag}</div>
            <div style={{ fontSize: 11, color: 'var(--fg-3)', marginTop: 4 }}>{f.addr}</div>
          </div>
          {f.cols.map((col, i) => (
            <div key={i}>
              <h5>{col.h}</h5>
              <ul>{col.l.map((x, j) => <li key={j}><a href="#">{x}</a></li>)}</ul>
            </div>
          ))}
        </div>
        <div className="footer-bottom">
          <span className="ok">{f.ok}</span>
          <span>{f.ver}</span>
          <span>{f.copy}</span>
        </div>
      </div>
    </footer>
  );
}

/* ---------- TWEAKS ---------- */
const MAINFRAME_DEFAULTS = /*EDITMODE-BEGIN*/{
  "blue": "#4d8df6",
  "cyan": "#7dd3fc",
  "matrix": true,
  "scanlines": true,
  "vignette": true,
  "grid": true
}/*EDITMODE-END*/;

const BLUE_SWATCHES = ['#4d8df6', '#6366f1', '#3b82f6', '#0ea5e9', '#22d3ee'];
const CYAN_SWATCHES = ['#7dd3fc', '#67e8f9', '#a5f3fc', '#86efac', '#ddd6fe'];

function App() {
  const [t, setTweak] = useTweaks(MAINFRAME_DEFAULTS);
  const [lang, setLang] = useState('cs');
  const copy = window.MAINFRAME_COPY[lang];

  useEffect(() => {
    const root = document.documentElement;
    root.style.setProperty('--blue', t.blue);
    root.style.setProperty('--blue-2', t.blue + '2e');
    root.style.setProperty('--cyan', t.cyan);
    root.style.setProperty('--cyan-2', t.cyan + '2e');
    document.body.classList.toggle('scanlines', !!t.scanlines);
    document.body.classList.toggle('vignette', !!t.vignette);
    document.body.classList.toggle('no-grid', !t.grid);
    document.body.classList.toggle('no-matrix', !t.matrix);
  }, [t.blue, t.cyan, t.scanlines, t.vignette, t.grid, t.matrix]);

  return (
    <>
      {t.grid && <div className="bg-grid" />}
      {t.matrix && <MatrixRain />}
      <Nav copy={copy} lang={lang} setLang={setLang} />
      <Hero copy={copy} />
      <Packets items={copy.packets} />
      <Expertise copy={copy} />
      <Process copy={copy} />
      <Careers copy={copy} />
      <Contact copy={copy} />
      <Footer copy={copy} />

      <TweaksPanel title="Tweaks · Mainframe">
        <TweakSection label="Accents" />
        <TweakColor label="Blue"  value={t.blue} options={BLUE_SWATCHES} onChange={(v) => setTweak('blue', v)} />
        <TweakColor label="Cyan"  value={t.cyan} options={CYAN_SWATCHES} onChange={(v) => setTweak('cyan', v)} />

        <TweakSection label="FX" />
        <TweakToggle label="Matrix rain"     value={t.matrix}    onChange={(v) => setTweak('matrix', v)} />
        <TweakToggle label="CRT scanlines"   value={t.scanlines} onChange={(v) => setTweak('scanlines', v)} />
        <TweakToggle label="CRT vignette"    value={t.vignette}  onChange={(v) => setTweak('vignette', v)} />
        <TweakToggle label="Background grid" value={t.grid}      onChange={(v) => setTweak('grid', v)} />
      </TweaksPanel>
    </>
  );
}

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