// terminal.jsx — Animated developer terminal for the hero.
// Cycles through a short transcript: ssh into oropezas worker, deploy,
// open a quick wrangler tail. Honors `flavor` tweak: shell / build / agent.

function useTerminalTranscript(flavor) {
    return React.useMemo(() => {
        const shell = [
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/clients/casa-mole', cmd: 'npm run deploy', delay: 90 },
            { kind: 'out',  text: '▲ next build · 12 routes · 18.4 kB shared\n✔ Compiled successfully (3.2s)' },
            { kind: 'out',  text: '↗ uploading to cloudflare pages…' },
            { kind: 'out',  text: '✔ casa-mole-slp.pages.dev', cls: 'ok' },
            { kind: 'out',  text: '   → 312 ms TTFB · 1.1 MB · A11y 100', cls: 'dim' },
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/clients/casa-mole', cmd: 'wrangler tail --format pretty', delay: 80 },
            { kind: 'out',  text: 'GET / 200  OK  CDG 41ms', cls: 'out' },
            { kind: 'out',  text: 'POST /api/reservations 201  MX1 88ms', cls: 'out' },
            { kind: 'out',  text: 'GET /menu 200  OK  YYZ 39ms', cls: 'out' },
        ];

        const build = [
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/oropezas.com', cmd: 'cat oropezas.config.ts', delay: 90 },
            { kind: 'code', text: 'export default {\n  edition:   ["mx", "ca"],\n  worker:    "cloudflare",\n  ai:        ["llama-3.3", "flux-1"],\n  payments:  "stripe",\n  push:      true,\n}' },
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/oropezas.com', cmd: 'pnpm test && pnpm deploy', delay: 70 },
            { kind: 'out',  text: 'tests: 142 passed · 0 failed · 1.4s', cls: 'ok' },
            { kind: 'out',  text: '▲ deployed to oropezas.com', cls: 'ok' },
            { kind: 'out',  text: '   workers.dev/oropezas-api · v141', cls: 'dim' },
        ];

        const agent = [
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/agents/concierge', cmd: 'oropezas agent run', delay: 90 },
            { kind: 'out',  text: '◆ booting concierge.v3 (gpt-4.1 · es-MX)', cls: 'dim' },
            { kind: 'out',  text: '✔ context loaded: 14 docs · 3 calendars · 1 menu', cls: 'ok' },
            { kind: 'out',  text: '> Cliente: "¿Tienen lugar para 6 el sábado?"', cls: 'out' },
            { kind: 'out',  text: '↳ agent: revisando reservas.cal…', cls: 'dim' },
            { kind: 'out',  text: '↳ agent: "Sí — sábado 8pm para 6. ¿Lo confirmo?"', cls: 'ok' },
            { kind: 'out',  text: '✓ booking_confirmed#5421 · sms enviado', cls: 'ok' },
            { kind: 'prompt', user: 'oropezas', host: 'dev', path: '~/agents/concierge', cmd: '', delay: 0 },
        ];

        return { shell, build, agent }[flavor] || shell;
    }, [flavor]);
}

function Prompt({ user, host, path, cmd, typed }) {
    return (
        <div className="dev-terminal-line">
            <span className="prompt-user">{user}</span>
            <span className="prompt-sym">@</span>
            <span className="prompt-host">{host}</span>
            <span className="prompt-sym">:</span>
            <span className="prompt-path">{path}</span>
            <span className="prompt-sym"> $</span>
            {' '}
            <span>{typed}</span>
            {cmd && typed.length < cmd.length && <span className="dev-terminal-caret" />}
        </div>
    );
}

function OutLine({ text, cls }) {
    return (
        <div className="dev-terminal-line">
            {text.split('\n').map((ln, i) => (
                <div key={i} className={cls || 'out'}>{ln}</div>
            ))}
        </div>
    );
}

function CodeLine({ text }) {
    // simple-ish syntax: ", strings, numbers, keys
    const tokens = [];
    let buf = '';
    let i = 0;
    while (i < text.length) {
        const ch = text[i];
        if (ch === '"') {
            if (buf) { tokens.push({ t: buf }); buf = ''; }
            let j = i + 1;
            while (j < text.length && text[j] !== '"') j++;
            tokens.push({ t: text.slice(i, j + 1), c: 'str' });
            i = j + 1;
        } else if (/\d/.test(ch) && (i === 0 || /[\s,:]/.test(text[i-1]))) {
            if (buf) { tokens.push({ t: buf }); buf = ''; }
            let j = i;
            while (j < text.length && /[\d.]/.test(text[j])) j++;
            tokens.push({ t: text.slice(i, j), c: 'num' });
            i = j;
        } else {
            buf += ch;
            i++;
        }
    }
    if (buf) tokens.push({ t: buf });

    return (
        <div className="dev-terminal-line">
            {text.split('\n').map((ln, k) => (
                <div key={k}>
                    {ln.split(/(:|,)/g).map((seg, sIdx) => {
                        // keys before colon
                        if (sIdx % 2 === 0 && /^\s*[a-z_]+\s*$/.test(seg) && ln.includes(':')) {
                            return <span key={sIdx} className="key">{seg}</span>;
                        }
                        // strings
                        return seg.split(/(".*?")/g).map((p, pIdx) => {
                            if (p.startsWith('"')) return <span key={`${sIdx}-${pIdx}`} className="str">{p}</span>;
                            if (/^\s*\d+\s*$/.test(p)) return <span key={`${sIdx}-${pIdx}`} className="num">{p}</span>;
                            return <span key={`${sIdx}-${pIdx}`} className="out">{p}</span>;
                        });
                    })}
                </div>
            ))}
        </div>
    );
}

function DevTerminal({ flavor = 'shell' }) {
    const transcript = useTerminalTranscript(flavor);
    const [step, setStep] = React.useState(0);
    const [typed, setTyped] = React.useState('');
    const [history, setHistory] = React.useState([]);
    const stepRef = React.useRef(step);
    stepRef.current = step;

    // Reset everything when flavor changes
    React.useEffect(() => {
        setStep(0); setTyped(''); setHistory([]);
    }, [flavor]);

    React.useEffect(() => {
        if (step >= transcript.length) {
            // loop after a beat
            const t = setTimeout(() => { setHistory([]); setStep(0); setTyped(''); }, 3000);
            return () => clearTimeout(t);
        }
        const item = transcript[step];

        if (item.kind === 'prompt') {
            // type out the command char-by-char, then push to history
            setTyped('');
            const cmd = item.cmd || '';
            if (cmd.length === 0) {
                // empty prompt = wait then advance to next loop
                const t = setTimeout(() => {
                    if (stepRef.current === step) setStep(step + 1);
                }, 800);
                return () => clearTimeout(t);
            }
            let i = 0;
            const interval = setInterval(() => {
                i += 1;
                setTyped(cmd.slice(0, i));
                if (i >= cmd.length) {
                    clearInterval(interval);
                    setTimeout(() => {
                        setHistory((h) => [...h, { ...item, typed: cmd }]);
                        setTyped('');
                        setStep((s) => s + 1);
                    }, 400);
                }
            }, item.delay || 80);
            return () => clearInterval(interval);
        } else {
            // out / code — show after a delay
            const t = setTimeout(() => {
                setHistory((h) => [...h, item]);
                setStep((s) => s + 1);
            }, 350);
            return () => clearTimeout(t);
        }
    }, [step, transcript]);

    // Auto-scroll latest into view inside the terminal
    const bodyRef = React.useRef(null);
    React.useEffect(() => {
        if (bodyRef.current) bodyRef.current.scrollTop = bodyRef.current.scrollHeight;
    }, [history, typed]);

    const current = transcript[step];
    return (
        <div className="dev-terminal" role="img" aria-label="Animated developer terminal">
            <div className="dev-terminal-chrome">
                <div className="dev-terminal-lights"><span /><span /><span /></div>
                <div className="dev-terminal-title">oropezas@dev — bash</div>
                <div className="dev-terminal-tag">● live</div>
            </div>
            <div className="dev-terminal-body" ref={bodyRef}>
                {history.map((item, i) => {
                    if (item.kind === 'prompt') {
                        return <Prompt key={i} user={item.user} host={item.host} path={item.path} cmd={item.typed} typed={item.typed} />;
                    }
                    if (item.kind === 'code') return <CodeLine key={i} text={item.text} />;
                    return <OutLine key={i} text={item.text} cls={item.cls} />;
                })}
                {current && current.kind === 'prompt' && (
                    <Prompt user={current.user} host={current.host} path={current.path} cmd={current.cmd} typed={typed} />
                )}
            </div>
        </div>
    );
}

window.DevTerminal = DevTerminal;
