'use client';
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
import { useEffect, useRef, useState } from 'react';
import { Button } from '../ui/button.js';
import { Textarea } from '../ui/textarea.js';
import { Alert, AlertDescription } from '../ui/alert.js';
import { Send, Square } from 'lucide-react';
let nextMessageId = 0;
function newMessageId() {
    nextMessageId += 1;
    return `msg-${nextMessageId}`;
}
export function AgentPlayground({ agentType, promptId, inlinePromptBody, fetchOverride, }) {
    const [input, setInput] = useState('');
    const [messages, setMessages] = useState([]);
    const [streaming, setStreaming] = useState(false);
    const [error, setError] = useState(null);
    const abortRef = useRef(null);
    const transcriptRef = useRef(null);
    useEffect(() => {
        transcriptRef.current?.scrollTo({ top: transcriptRef.current.scrollHeight });
    }, [messages]);
    async function send(prompt) {
        if (!prompt.trim() || streaming)
            return;
        setError(null);
        const nextMessages = [
            ...messages,
            { id: newMessageId(), role: 'user', content: prompt },
            { id: newMessageId(), role: 'assistant', content: '' },
        ];
        setMessages(nextMessages);
        setInput('');
        setStreaming(true);
        const controller = new AbortController();
        abortRef.current = controller;
        try {
            const fetcher = fetchOverride ?? fetch;
            const res = await fetcher('/api/agents/playground', {
                method: 'POST',
                headers: { 'content-type': 'application/json' },
                body: JSON.stringify({
                    agentType,
                    promptId,
                    ...(inlinePromptBody && { promptBody: inlinePromptBody }),
                    messages: nextMessages.slice(0, -1).map((m) => ({ role: m.role, content: m.content })),
                }),
                signal: controller.signal,
            });
            if (!res.ok || !res.body) {
                const message = `Playground request failed (${res.status})`;
                setError(message);
                setStreaming(false);
                return;
            }
            const reader = res.body.getReader();
            const decoder = new TextDecoder();
            let buffer = '';
            while (true) {
                const { value, done } = await reader.read();
                if (done)
                    break;
                buffer += decoder.decode(value, { stream: true });
                const events = buffer.split('\n\n');
                buffer = events.pop() ?? '';
                for (const block of events) {
                    const line = block.trim();
                    if (!line.startsWith('data:'))
                        continue;
                    const payload = line.slice(5).trim();
                    if (!payload)
                        continue;
                    try {
                        const event = JSON.parse(payload);
                        if (event.type === 'delta') {
                            setMessages((prev) => appendDelta(prev, event.content));
                        }
                        else if (event.type === 'error') {
                            setError(event.content);
                        }
                    }
                    catch {
                        // ignore malformed line
                    }
                }
            }
        }
        catch (err) {
            if (err?.name !== 'AbortError') {
                setError(err instanceof Error ? err.message : String(err));
            }
        }
        finally {
            setStreaming(false);
            abortRef.current = null;
        }
    }
    function stop() {
        abortRef.current?.abort();
        abortRef.current = null;
        setStreaming(false);
    }
    return (_jsxs("div", { className: "flex flex-col gap-3 rounded-lg border p-4", "data-testid": "agent-playground", children: [_jsxs("header", { className: "flex items-center justify-between gap-2", children: [_jsxs("div", { className: "flex flex-col", children: [_jsx("p", { className: "text-sm font-semibold", children: "Playground" }), _jsxs("p", { className: "text-muted-foreground text-xs", children: ["Streaming against ", agentType, " \u00B7 ", promptId, inlinePromptBody ? ' (inline override)' : ''] })] }), messages.length > 0 ? (_jsx(Button, { type: "button", variant: "ghost", size: "sm", onClick: () => setMessages([]), disabled: streaming, children: "Clear" })) : null] }), _jsx("div", { ref: transcriptRef, className: "bg-muted/20 flex h-72 flex-col gap-2 overflow-y-auto rounded border p-3", "data-testid": "playground-transcript", children: messages.length === 0 ? (_jsx("p", { className: "text-muted-foreground text-xs", children: "Send a message to test this prompt against the configured executor." })) : (messages.map((m, i) => (_jsx("div", { className: m.role === 'user'
                        ? 'bg-primary text-primary-foreground max-w-[85%] self-end rounded-lg px-3 py-2 text-sm'
                        : 'bg-card max-w-[85%] self-start rounded-lg border px-3 py-2 text-sm whitespace-pre-wrap', "data-testid": `playground-msg-${i}-${m.role}`, children: m.content || (streaming && i === messages.length - 1 ? '…' : '') }, m.id)))) }), error ? (_jsx(Alert, { variant: "destructive", "data-testid": "playground-error", children: _jsx(AlertDescription, { children: error }) })) : null, _jsxs("form", { className: "flex items-end gap-2", onSubmit: (e) => {
                    e.preventDefault();
                    void send(input);
                }, children: [_jsx(Textarea, { value: input, onChange: (e) => setInput(e.target.value), rows: 2, placeholder: "Try a prompt\u2026", className: "font-mono text-xs", "data-testid": "playground-input", disabled: streaming, onKeyDown: (e) => {
                            if (e.key === 'Enter' && (e.metaKey || e.ctrlKey)) {
                                e.preventDefault();
                                void send(input);
                            }
                        } }), streaming ? (_jsxs(Button, { type: "button", variant: "secondary", onClick: stop, "data-testid": "playground-stop", children: [_jsx(Square, { className: "size-3" }), "Stop"] })) : (_jsxs(Button, { type: "submit", disabled: !input.trim(), "data-testid": "playground-send", children: [_jsx(Send, { className: "size-3" }), "Send"] }))] })] }));
}
function appendDelta(prev, delta) {
    if (prev.length === 0)
        return prev;
    const last = prev[prev.length - 1];
    if (last?.role !== 'assistant')
        return prev;
    const next = [...prev];
    next[next.length - 1] = { ...last, content: last.content + delta };
    return next;
}
