import { Dialog, DialogContent, DialogHeader, DialogTitle } from '@/components/ui/dialog';
import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/ui/tooltip';
import { LOG_COLOR } from '@/lib/logColors';
import { Play, Square, TriangleAlert } from 'lucide-react';
import { useEffect, useRef, useState } from 'react';

// Roda a atividade manualmente com log ao vivo (SSE) e botão Parar.
// Usado em integracoes/Edit e integracoes/Show.

type RunPhase = 'idle' | 'running' | 'ok' | 'err' | 'stopped';
type LogLine  = { type: string; msg: string };

function xsrf() {
    return decodeURIComponent(document.cookie.match(/XSRF-TOKEN=([^;]+)/)?.[1] ?? '');
}

export function RunButton({ aodId }: { aodId: number }) {
    const [phase, setPhase] = useState<RunPhase>('idle');
    const [logs,  setLogs]  = useState<LogLine[]>([]);
    const [open,  setOpen]  = useState(false);
    const logsEndRef = useRef<HTMLDivElement>(null);

    useEffect(() => {
        logsEndRef.current?.scrollIntoView({ behavior: 'smooth' });
    }, [logs]);

    async function handleRun() {
        setPhase('running');
        setLogs([]);
        setOpen(true);

        try {
            const res = await fetch(route('activityOrigDest.run', { id: aodId }), {
                method: 'POST',
                headers: { 'X-XSRF-TOKEN': xsrf(), 'Accept': 'text/event-stream' },
            });

            if (!res.ok || !res.body) {
                const err = await res.json().catch(() => ({ message: 'Erro ao iniciar execução.' }));
                setLogs([{ type: 'CRITICAL', msg: err.message ?? 'Erro desconhecido.' }]);
                setPhase('err');
                return;
            }

            const reader  = res.body.getReader();
            const decoder = new TextDecoder();
            let buffer    = '';

            while (true) {
                const { done, value } = await reader.read();
                if (done) break;

                buffer += decoder.decode(value, { stream: true });
                const parts = buffer.split('\n\n');
                buffer = parts.pop() ?? '';

                for (const chunk of parts) {
                    const line = chunk.trim();
                    if (!line.startsWith('data: ')) continue;
                    try {
                        const ev = JSON.parse(line.slice(6)) as { type: string; msg: string };
                        if (ev.type === 'done')    { setPhase('ok');      continue; }
                        if (ev.type === 'stopped') { setPhase('stopped'); continue; }
                        if (ev.type === 'error')   { setPhase('err'); }
                        setLogs(prev => [...prev, ev]);
                    } catch { /* malformed chunk */ }
                }
            }
        } catch {
            setPhase('err');
        }
    }

    async function handleStop() {
        await fetch(route('activityOrigDest.stop', { id: aodId }), {
            method: 'POST',
            headers: { 'X-XSRF-TOKEN': xsrf() },
        });
    }

    const btnClass = [
        'inline-flex items-center gap-1 text-[10px] font-semibold px-2 py-1 rounded-md border transition-colors disabled:opacity-50',
        phase === 'ok'      ? 'border-emerald-300 bg-emerald-50 text-emerald-700 dark:border-emerald-700 dark:bg-emerald-950 dark:text-emerald-400' :
        phase === 'err'     ? 'border-rose-300 bg-rose-50 text-rose-700 dark:border-rose-700 dark:bg-rose-950 dark:text-rose-400' :
        phase === 'stopped' ? 'border-amber-300 bg-amber-50 text-amber-700 dark:border-amber-700 dark:bg-amber-950 dark:text-amber-400' :
                              'border-amber-200 dark:border-amber-800 text-amber-700 dark:text-amber-400 hover:bg-amber-50 dark:hover:bg-amber-950',
    ].join(' ');

    return (
        <>
            <Tooltip>
                <TooltipTrigger asChild>
                    <button type="button" onClick={handleRun} disabled={phase === 'running'} className={btnClass}>
                        {phase === 'running' ? (
                            <><span className="w-2 h-2 rounded-full border border-current border-t-transparent animate-spin" /> Rodando</>
                        ) : phase === 'ok' ? (
                            <><Play size={10} strokeWidth={2.5} /> Concluído</>
                        ) : phase === 'err' ? (
                            <><TriangleAlert size={10} strokeWidth={2.5} /> Erro</>
                        ) : phase === 'stopped' ? (
                            <><Square size={10} strokeWidth={2.5} /> Parado</>
                        ) : (
                            <><Play size={10} strokeWidth={2.5} /> Rodar</>
                        )}
                    </button>
                </TooltipTrigger>
                <TooltipContent>Rodar manualmente em tempo real</TooltipContent>
            </Tooltip>

            <Dialog open={open} onOpenChange={setOpen}>
                <DialogContent className="max-w-2xl">
                    <DialogHeader>
                        <DialogTitle className="flex items-center justify-between pr-6">
                            <span className="flex items-center gap-2 text-sm">
                                {phase === 'running' && <span className="w-2 h-2 rounded-full border border-amber-500 border-t-transparent animate-spin" />}
                                Execução ao vivo
                            </span>
                            {phase === 'running' && (
                                <button
                                    type="button"
                                    onClick={handleStop}
                                    className="inline-flex items-center gap-1 text-[10px] font-semibold px-2 py-1 rounded-md border border-rose-300 bg-rose-50 text-rose-700 dark:border-rose-700 dark:bg-rose-950 dark:text-rose-400 hover:bg-rose-100 transition-colors"
                                >
                                    <Square size={10} strokeWidth={2.5} /> Parar
                                </button>
                            )}
                        </DialogTitle>
                    </DialogHeader>

                    <div className="rounded-lg border border-border bg-zinc-950 font-mono text-xs p-3 h-80 overflow-y-auto">
                        {logs.length === 0 && phase === 'running' && (
                            <span className="text-zinc-500">Iniciando...</span>
                        )}
                        {logs.map((l, i) => (
                            <div key={i} className={['leading-5', LOG_COLOR[l.type] ?? 'text-zinc-400'].join(' ')}>
                                <span className="opacity-40 mr-2 select-none">[{l.type}]</span>{l.msg}
                            </div>
                        ))}
                        <div ref={logsEndRef} />
                    </div>

                    {phase !== 'idle' && phase !== 'running' && (
                        <p className={[
                            'text-xs font-semibold text-center',
                            phase === 'ok'      ? 'text-emerald-600 dark:text-emerald-400' :
                            phase === 'stopped' ? 'text-amber-600 dark:text-amber-400'     :
                                                  'text-rose-600 dark:text-rose-400',
                        ].join(' ')}>
                            {phase === 'ok'      ? 'Execução concluída com sucesso.' :
                             phase === 'stopped' ? 'Execução interrompida pelo usuário.' :
                                                   'Erro durante a execução.'}
                        </p>
                    )}
                </DialogContent>
            </Dialog>
        </>
    );
}
