'use client';
import { useCallback, useEffect, useRef, useState } from 'react';
const MAX_EVENTS = 200;
const PRUNE_KEEP = 100;
const RECONNECT_BASE_MS = 1_000;
const RECONNECT_MAX_MS = 30_000;
/**
 * Hook that receives real-time SDLC task and sub-task events via SSE.
 *
 * Connects to /api/sdlc-events (optionally scoped to a featureId) and
 * receives task/sub-task create, update, and delete events. Automatically
 * reconnects on disconnect with exponential backoff.
 */
export function useSdlcEvents({ featureId, eventTypes, onEvent, }) {
    const [events, setEvents] = useState([]);
    const [lastEvent, setLastEvent] = useState(null);
    const [connectionStatus, setConnectionStatus] = useState('disconnected');
    const eventSourceRef = useRef(null);
    const retryCountRef = useRef(0);
    const retryTimeoutRef = useRef(null);
    const onEventRef = useRef(onEvent);
    onEventRef.current = onEvent;
    const eventTypesKey = eventTypes?.sort().join(',') ?? '';
    const connect = useCallback(() => {
        if (typeof window === 'undefined')
            return;
        // Clean up existing connection
        eventSourceRef.current?.close();
        setConnectionStatus('connecting');
        const params = new URLSearchParams();
        if (featureId) {
            params.set('featureId', featureId);
        }
        const query = params.toString();
        const url = `/api/sdlc-events${query ? `?${query}` : ''}`;
        const es = new EventSource(url);
        eventSourceRef.current = es;
        es.addEventListener('sdlc_event', (e) => {
            try {
                const parsed = JSON.parse(e.data);
                // Apply event type filter if specified
                if (eventTypesKey && !eventTypesKey.includes(parsed.eventType)) {
                    return;
                }
                setEvents((prev) => {
                    const next = [...prev, parsed];
                    return next.length > MAX_EVENTS ? next.slice(-PRUNE_KEEP) : next;
                });
                setLastEvent(parsed);
                onEventRef.current?.(parsed);
            }
            catch {
                // Ignore malformed events
            }
        });
        es.onopen = () => {
            setConnectionStatus('connected');
            retryCountRef.current = 0;
        };
        es.onerror = () => {
            es.close();
            setConnectionStatus('disconnected');
            // Exponential backoff reconnection
            const delay = Math.min(RECONNECT_BASE_MS * Math.pow(2, retryCountRef.current), RECONNECT_MAX_MS);
            retryCountRef.current++;
            retryTimeoutRef.current = setTimeout(connect, delay);
        };
    }, [featureId, eventTypesKey]);
    useEffect(() => {
        connect();
        return () => {
            eventSourceRef.current?.close();
            eventSourceRef.current = null;
            if (retryTimeoutRef.current) {
                clearTimeout(retryTimeoutRef.current);
                retryTimeoutRef.current = null;
            }
        };
    }, [connect]);
    return { events, lastEvent, connectionStatus };
}
