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

/* =========================================================
   Terminal — types out a realistic mijeraki build pipeline
   ========================================================= */
const TERM_SCRIPT = [
  [{ t: "$ ", c: "dim" }, { t: "mijeraki", c: "accent" }, { t: " init " }, { t: "--target ", c: "dim" }, { t: "https://schreiner-mueller.de", c: "text" }],
  [{ t: "  → scraping site structure............... " }, { t: "✓ done", c: "ok" }, { t: "  (1.2s)", c: "dim" }],
  [{ t: "  → extracting 47 pages, 23 images........ " }, { t: "✓ done", c: "ok" }],
  [{ t: "  → preserving 312 paragraphs of copy..... " }, { t: "✓ done", c: "ok" }],
  [{ t: "" }],
  [{ t: "$ ", c: "dim" }, { t: "mijeraki", c: "accent" }, { t: " design " }, { t: "--variants 3", c: "dim" }],
  [{ t: "  → layout v1 ", c: "" }, { t: "editorial", c: "dim" }, { t: ".................. " }, { t: "✓ done", c: "ok" }],
  [{ t: "  → layout v2 ", c: "" }, { t: "asymmetric", c: "dim" }, { t: "................. " }, { t: "✓ done", c: "ok" }],
  [{ t: "  → layout v3 ", c: "" }, { t: "single-page", c: "dim" }, { t: "................ " }, { t: "✓ done", c: "ok" }],
  [{ t: "" }],
  [{ t: "$ ", c: "dim" }, { t: "mijeraki", c: "accent" }, { t: " ship " }, { t: "--deploy production", c: "dim" }],
  [{ t: "  → building static bundle................ " }, { t: "✓ done", c: "ok" }],
  [{ t: "  → optimizing 23 images.................. " }, { t: "✓ done", c: "ok" }],
  [{ t: "  → lighthouse audit: " }, { t: "98", c: "ok" }, { t: " · " }, { t: "100", c: "ok" }, { t: " · " }, { t: "95", c: "ok" }, { t: " · " }, { t: "97", c: "ok" }],
  [{ t: "  → deploy → mustermann-coburg.de......... " }, { t: "✓ done", c: "ok" }],
  [{ t: "" }],
  [{ t: "✓ Site live in 1.847s", c: "accent" }],
  [{ t: "  eta 10 Werktage → geliefert in 6", c: "dim" }],
];

function Terminal() {
  const [chars, setChars] = useState(0);

  // pre-flatten into char stream
  const stream = React.useMemo(() => {
    const out = [];
    TERM_SCRIPT.forEach((line, li) => {
      line.forEach((seg) => {
        for (let i = 0; i < seg.t.length; i++) {
          out.push({ ch: seg.t[i], c: seg.c || "" });
        }
      });
      out.push({ ch: "\n", c: "", isNewline: true });
    });
    return out;
  }, []);

  useEffect(() => {
    let raf;
    let lastT = performance.now();
    let acc = 0;
    let paused = 0; // wait at end of cycle

    function frame(now) {
      const dt = now - lastT;
      lastT = now;
      if (paused > 0) {
        paused -= dt;
        if (paused <= 0) {
          setChars(0);
          acc = 0;
        }
      } else {
        // ~6 chars per frame at 60fps → fast type, around 4s for full output
        acc += dt * 0.32;
        const step = Math.floor(acc);
        if (step > 0) {
          acc -= step;
          setChars((c) => {
            const next = c + step;
            if (next >= stream.length) {
              paused = 2400;
              return stream.length;
            }
            return next;
          });
        }
      }
      raf = requestAnimationFrame(frame);
    }
    raf = requestAnimationFrame(frame);
    return () => cancelAnimationFrame(raf);
  }, [stream]);

  // Render only chars typed so far, broken into spans by class change & newline
  const slice = stream.slice(0, chars);
  const rendered = [];
  let buf = "";
  let curC = slice[0]?.c ?? "";
  let key = 0;
  const flush = () => {
    if (!buf) return;
    rendered.push(
      curC ? <span key={key++} className={curC}>{buf}</span> : <React.Fragment key={key++}>{buf}</React.Fragment>
    );
    buf = "";
  };
  slice.forEach((item) => {
    if (item.isNewline) {
      flush();
      rendered.push(<br key={key++} />);
      curC = "";
    } else {
      if (item.c !== curC) {
        flush();
        curC = item.c;
      }
      buf += item.ch;
    }
  });
  flush();

  return (
    <div className="terminal" role="img" aria-label="mijeraki build pipeline">
      <div className="terminal-head">
        <div className="dots" aria-hidden="true">
          <span></span><span></span><span></span>
        </div>
        <div className="mark"><img src="assets/logo.png" alt="" /></div>
        <div className="path">
          ~/projects/schreiner-mueller <span className="seg-dim">on</span> main
        </div>
      </div>
      <div className="terminal-body">
        {rendered}
        <span className="cursor"></span>
      </div>
    </div>
  );
}

/* =========================================================
   Hero
   ========================================================= */
function Hero({ t, onCta }) {
  return (
    <section className="hero" id="top">
      <div className="hero-grid" aria-hidden="true"></div>
      <div className="hero-glow" aria-hidden="true"></div>
      <div className="hero-noise" aria-hidden="true"></div>

      <div className="hero-inner">
        <div>
          <div className="eyebrow">{t.hero.eyebrow}</div>
          <h1 className="display">
            {t.hero.headline.map((line, i) => (
              <span className="line" key={i}>
                <span style={{ animationDelay: `${0.15 + i * 0.15}s` }}>
                  {line.parts.map((p, j) =>
                    p.cls ? (
                      <em key={j} className={p.cls}>{p.text}</em>
                    ) : (
                      <React.Fragment key={j}>{p.text}</React.Fragment>
                    )
                  )}
                </span>
              </span>
            ))}
          </h1>
          <p className="hero-sub">{t.hero.sub}</p>
          <div className="hero-ctas">
            <a href="#contact" className="btn btn-primary" onClick={onCta}>
              {t.hero.cta} <span className="arrow">→</span>
            </a>
            <a href="#process" className="btn btn-ghost">
              {t.hero.ctaAlt}
            </a>
          </div>
          <div className="hero-meta">
            {t.hero.meta.map((m, i) => (
              <div key={i}>
                <span className="k">{m.k}</span>
                <span className="v">{m.v}</span>
              </div>
            ))}
          </div>
        </div>

        <div className="hero-visual">
          <Terminal />
        </div>
      </div>
    </section>
  );
}

window.Hero = Hero;
