'use client';

import { createContext, useContext, useEffect, useState } from 'react';
import { RealtimeEvent, RealtimeMessage, REALTIME_EVENTS } from '@/lib/realtime/events';

interface RealtimeContextValue {
  isConnected: boolean;
  subscribe: <T = any>(event: RealtimeEvent, handler: (data: T) => void) => () => void;
  lastEvent: RealtimeMessage | null;
}

const RealtimeContext = createContext<RealtimeContextValue | null>(null);

export function RealtimeProvider({ children }: { children: React.ReactNode }) {
  const [isConnected, setIsConnected] = useState(false);
  const [lastEvent, setLastEvent] = useState<RealtimeMessage | null>(null);
  const [handlers, setHandlers] = useState<Map<RealtimeEvent, Set<(data: any) => void>>>(new Map());

  useEffect(() => {
    const eventSource = new EventSource('/api/v1/realtime/events');

    eventSource.onopen = () => {
      setIsConnected(true);
    };

    eventSource.onmessage = (event) => {
      try {
        const message = JSON.parse(event.data);
        if (message.type === 'connected') return;

        setLastEvent(message);

        const eventHandlers = handlers.get(message.event);
        if (eventHandlers) {
          eventHandlers.forEach(handler => handler(message.data));
        }
      } catch (e) {
        console.error('Parse error:', e);
      }
    };

    eventSource.onerror = () => {
      setIsConnected(false);
    };

    return () => eventSource.close();
  }, [handlers]);

  const subscribe = <T = any>(event: RealtimeEvent, handler: (data: T) => void) => {
    setHandlers(prev => {
      const newHandlers = new Map(prev);
      if (!newHandlers.has(event)) {
        newHandlers.set(event, new Set());
      }
      newHandlers.get(event)!.add(handler);
      return newHandlers;
    });

    return () => {
      setHandlers(prev => {
        const newHandlers = new Map(prev);
        newHandlers.get(event)?.delete(handler);
        return newHandlers;
      });
    };
  };

  return (
    <RealtimeContext.Provider value={{ isConnected, subscribe, lastEvent }}>
      {children}
    </RealtimeContext.Provider>
  );
}

export function useRealtimeContext() {
  const context = useContext(RealtimeContext);
  if (!context) {
    throw new Error('useRealtimeContext must be used within RealtimeProvider');
  }
  return context;
}
