import React, { createContext, useContext, useEffect, useState } from 'react';
import { io } from 'socket.io-client';
import { useAuth } from './AuthContext';
import toast from 'react-hot-toast';

const SocketContext = createContext();

export const SocketProvider = ({ children }) => {
  const [socket, setSocket] = useState(null);
  const [connected, setConnected] = useState(false);
  const [recentDetections, setRecentDetections] = useState([]);
  const [deviceStatus, setDeviceStatus] = useState({});
  const [movementAlerts, setMovementAlerts] = useState([]);
  const [droneTracking, setDroneTracking] = useState(new Map());
  const { isAuthenticated } = useAuth();

  useEffect(() => {
    if (isAuthenticated) {
      // Initialize socket connection
      const newSocket = io(process.env.NODE_ENV === 'production' 
        ? window.location.origin
        : 'http://localhost:3001', {
        path: process.env.NODE_ENV === 'production' ? '/drones/socket.io/' : '/socket.io/'
      });

      newSocket.on('connect', () => {
        console.log('Connected to server');
        setConnected(true);
        
        // Join dashboard room for general updates
        newSocket.emit('join_dashboard');
        
        toast.success('Connected to real-time updates');
      });

      newSocket.on('disconnect', () => {
        console.log('Disconnected from server');
        setConnected(false);
        toast.error('Disconnected from server');
      });

      newSocket.on('connect_error', (error) => {
        console.error('Connection error:', error);
        setConnected(false);
        toast.error('Failed to connect to server');
      });

      // Listen for drone detections
      newSocket.on('drone_detection', (detection) => {
        console.log('New drone detection:', detection);
        
        setRecentDetections(prev => [detection, ...prev.slice(0, 49)]); // Keep last 50
        
        // Update drone tracking
        if (detection.movement_analysis) {
          const trackingKey = `${detection.drone_id}_${detection.device_id}`;
          setDroneTracking(prev => {
            const newTracking = new Map(prev);
            newTracking.set(trackingKey, {
              droneId: detection.drone_id,
              deviceId: detection.device_id,
              lastDetection: detection,
              analysis: detection.movement_analysis,
              timestamp: Date.now()
            });
            return newTracking;
          });
        }
        
        // Show toast notification
        toast.error(
          `Drone ${detection.drone_id} detected by ${detection.device?.name || `Device ${detection.device_id}`}`,
          {
            duration: 5000,
            icon: '🚨',
          }
        );
      });

      // Listen for drone movement alerts
      newSocket.on('drone_movement_alert', (alertData) => {
        console.log('Drone movement alert:', alertData);
        
        setMovementAlerts(prev => [alertData, ...prev.slice(0, 19)]); // Keep last 20 alerts
        
        // Show priority-based notifications
        const alertIcon = alertData.analysis.alertLevel >= 3 ? '🚨' : 
                         alertData.analysis.alertLevel >= 2 ? '⚠️' : '📍';
        
        const alertColor = alertData.analysis.alertLevel >= 3 ? 'error' :
                          alertData.analysis.alertLevel >= 2 ? 'warning' : 'info';
        
        toast[alertColor === 'error' ? 'error' : alertColor === 'warning' ? 'error' : 'info'](
          alertData.analysis.description,
          {
            duration: alertData.analysis.alertLevel >= 2 ? 10000 : 6000,
            icon: alertIcon,
            style: {
              background: alertData.analysis.alertLevel >= 3 ? '#fee2e2' : 
                         alertData.analysis.alertLevel >= 2 ? '#fef3c7' : '#e0f2fe'
            }
          }
        );
      });

      // Listen for device heartbeats
      newSocket.on('device_heartbeat', (heartbeat) => {
        console.log('Device heartbeat:', heartbeat);
        
        setDeviceStatus(prev => ({
          ...prev,
          [heartbeat.device_id]: {
            ...heartbeat,
            last_seen: new Date()
          }
        }));
      });

      // Listen for device updates
      newSocket.on('device_updated', (device) => {
        console.log('Device updated:', device);
        toast.success(`Device ${device.name || device.id} updated`);
      });

      setSocket(newSocket);

      return () => {
        newSocket.disconnect();
      };
    } else {
      // Disconnect if not authenticated
      if (socket) {
        socket.disconnect();
        setSocket(null);
        setConnected(false);
      }
    }
  }, [isAuthenticated]);

  const joinDeviceRoom = (deviceId) => {
    if (socket) {
      socket.emit('join_device_room', deviceId);
    }
  };

  const leaveDeviceRoom = (deviceId) => {
    if (socket) {
      socket.emit('leave_device_room', deviceId);
    }
  };

  const clearRecentDetections = () => {
    setRecentDetections([]);
  };

  const clearMovementAlerts = () => {
    setMovementAlerts([]);
  };

  const getDroneTracking = (droneId, deviceId) => {
    const trackingKey = `${droneId}_${deviceId}`;
    return droneTracking.get(trackingKey);
  };

  const value = {
    socket,
    connected,
    recentDetections,
    deviceStatus,
    movementAlerts,
    droneTracking,
    joinDeviceRoom,
    leaveDeviceRoom,
    clearRecentDetections,
    clearMovementAlerts,
    getDroneTracking
  };

  return (
    <SocketContext.Provider value={value}>
      {children}
    </SocketContext.Provider>
  );
};

export const useSocket = () => {
  const context = useContext(SocketContext);
  if (!context) {
    throw new Error('useSocket must be used within a SocketProvider');
  }
  return context;
};
