// terminal.jsx — typewriter terminal for hero & demos

function useTypewriter(lines, { speed = 14, linePause = 160, loop = false, restartPause = 2200 } = {}) {
  const [out, setOut] = React.useState([]);
  const [done, setDone] = React.useState(false);

  React.useEffect(() => {
    let cancel = false;
    let li = 0, ci = 0;
    const buf = [];
    const tick = () => {
      if (cancel) return;
      if (li >= lines.length) {
        setDone(true);
        if (loop) {
          setTimeout(() => {
            if (cancel) return;
            li = 0; ci = 0; buf.length = 0; setOut([]); setDone(false);
            setTimeout(tick, 200);
          }, restartPause);
        }
        return;
      }
      const cur = lines[li];
      // 'instant' lines render whole
      if (cur.instant) {
        buf[li] = cur;
        setOut([...buf]);
        li++; ci = 0;
        setTimeout(tick, linePause);
        return;
      }
      const text = cur.text;
      if (ci === 0) { buf[li] = { ...cur, text: '' }; }
      buf[li] = { ...cur, text: text.slice(0, ci + 1) };
      setOut([...buf]);
      ci++;
      if (ci >= text.length) {
        li++; ci = 0;
        setTimeout(tick, linePause);
      } else {
        setTimeout(tick, speed + Math.random() * 8);
      }
    };
    tick();
    return () => { cancel = true };
  }, []);

  return { out, done };
}

function Terminal({ script, loop = true, height = 360 }) {
  const { out, done } = useTypewriter(script, { speed: 18, linePause: 280, loop, restartPause: 2600 });
  const showCursor = !done || loop;
  return (
    <div className="panel">
      <div className="panel-hd">
        <span className="dot-r r" /><span className="dot-r y" /><span className="dot-r g" />
        <span style={{ marginLeft: 8, opacity: .7 }}>~/dev — gr</span>
      </div>
      <div className="term" style={{ minHeight: height }}>
        {out.map((l, i) => {
          const isLast = i === out.length - 1;
          if (l.kind === 'cmd') return (
            <div key={i}><span className="prompt">$ </span><span dangerouslySetInnerHTML={{ __html: l.text }} />{isLast && showCursor && <span className="cursor" />}</div>
          );
          return <div key={i} className={l.kind} dangerouslySetInnerHTML={{ __html: l.text }} />;
        })}
      </div>
    </div>
  );
}

Object.assign(window, { Terminal });
