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<WidgetFilter>) => void;
  resetFilters: () => void;
  
  // Shared data between widgets
  sharedData: SharedData;
  updateSharedData: (data: Partial<SharedData>) => void;
  
  // Event system for widget communication
  publishEvent: (event: Omit<WidgetEvent, 'timestamp'>) => 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<WidgetContextType | null>(null);

export const WidgetProvider = ({ children }: { children: ReactNode }) => {
  const [filters, setFiltersState] = useState<WidgetFilter>(defaultFilters);
  const [sharedData, setSharedData] = useState<SharedData>({});
  const [recentEvents, setRecentEvents] = useState<WidgetEvent[]>([]);
  const [subscribers, setSubscribers] = useState<Set<(event: WidgetEvent) => void>>(new Set());

  const setFilters = useCallback((newFilters: Partial<WidgetFilter>) => {
    setFiltersState(prev => ({ ...prev, ...newFilters }));
  }, []);

  const resetFilters = useCallback(() => {
    setFiltersState(defaultFilters);
  }, []);

  const updateSharedData = useCallback((data: Partial<SharedData>) => {
    setSharedData(prev => ({ ...prev, ...data }));
  }, []);

  const publishEvent = useCallback((event: Omit<WidgetEvent, 'timestamp'>) => {
    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 (
    <WidgetContext.Provider value={{
      filters,
      setFilters,
      resetFilters,
      sharedData,
      updateSharedData,
      publishEvent,
      subscribeToEvents,
      recentEvents,
    }}>
      {children}
    </WidgetContext.Provider>
  );
};

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,
  };
};

