import { createContext, useContext, useState, useCallback, ReactNode } from 'react'; // Types for widget communication export interface WidgetFilter { severity?: 'all' | 'critical' | 'high' | 'medium' | 'low'; region?: string; timeRange?: '1h' | '6h' | '24h' | '7d' | '30d'; searchQuery?: string; } export interface WidgetEvent { type: string; sourceWidgetId: string; payload: any; timestamp: number; } export interface SharedData { selectedThreat?: { id: string; name: string; severity: string }; selectedRegion?: string; highlightedIP?: string; activeAlert?: { id: string; type: string; message: string }; } interface WidgetContextType { // Global filters filters: WidgetFilter; setFilters: (filters: Partial) => void; resetFilters: () => void; // Shared data between widgets sharedData: SharedData; updateSharedData: (data: Partial) => void; // Event system for widget communication publishEvent: (event: Omit) => void; subscribeToEvents: (callback: (event: WidgetEvent) => void) => () => void; // Recent events for debugging/display recentEvents: WidgetEvent[]; } const defaultFilters: WidgetFilter = { severity: 'all', region: undefined, timeRange: '24h', searchQuery: '', }; const WidgetContext = createContext(null); export const WidgetProvider = ({ children }: { children: ReactNode }) => { const [filters, setFiltersState] = useState(defaultFilters); const [sharedData, setSharedData] = useState({}); const [recentEvents, setRecentEvents] = useState([]); const [subscribers, setSubscribers] = useState void>>(new Set()); const setFilters = useCallback((newFilters: Partial) => { setFiltersState(prev => ({ ...prev, ...newFilters })); }, []); const resetFilters = useCallback(() => { setFiltersState(defaultFilters); }, []); const updateSharedData = useCallback((data: Partial) => { setSharedData(prev => ({ ...prev, ...data })); }, []); const publishEvent = useCallback((event: Omit) => { const fullEvent: WidgetEvent = { ...event, timestamp: Date.now(), }; // Add to recent events (keep last 50) setRecentEvents(prev => [fullEvent, ...prev.slice(0, 49)]); // Notify all subscribers subscribers.forEach(callback => callback(fullEvent)); console.log('[WidgetContext] Event published:', fullEvent); }, [subscribers]); const subscribeToEvents = useCallback((callback: (event: WidgetEvent) => void) => { setSubscribers(prev => new Set(prev).add(callback)); // Return unsubscribe function return () => { setSubscribers(prev => { const newSet = new Set(prev); newSet.delete(callback); return newSet; }); }; }, []); return ( {children} ); }; export const useWidgetContext = () => { const context = useContext(WidgetContext); if (!context) { throw new Error('useWidgetContext must be used within a WidgetProvider'); } return context; }; // Custom hook for widgets to easily communicate export const useWidgetCommunication = (widgetId: string) => { const context = useWidgetContext(); const publish = useCallback((type: string, payload: any) => { context.publishEvent({ type, sourceWidgetId: widgetId, payload, }); }, [context, widgetId]); const selectThreat = useCallback((threat: { id: string; name: string; severity: string }) => { context.updateSharedData({ selectedThreat: threat }); publish('threat_selected', threat); }, [context, publish]); const selectRegion = useCallback((region: string) => { context.updateSharedData({ selectedRegion: region }); context.setFilters({ region }); publish('region_selected', { region }); }, [context, publish]); const highlightIP = useCallback((ip: string) => { context.updateSharedData({ highlightedIP: ip }); publish('ip_highlighted', { ip }); }, [context, publish]); const selectAlert = useCallback((alert: { id: string; type: string; message: string }) => { context.updateSharedData({ activeAlert: alert }); publish('alert_selected', alert); }, [context, publish]); return { ...context, publish, selectThreat, selectRegion, highlightIP, selectAlert, }; };