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

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 [notificationsEnabled, setNotificationsEnabled] = useState(
    localStorage.getItem('notificationsEnabled') !== 'false' // Default to enabled
  );
  const { isAuthenticated } = useAuth();

  // Mobile notification management
  const [notificationCooldown, setNotificationCooldown] = useState(new Map());
  const [pendingNotifications, setPendingNotifications] = useState([]);
  
  // Check if device is mobile
  const isMobile = window.innerWidth <= 768;
  
  // Mobile-friendly notification handler
  const handleMobileNotification = (alertData) => {
    // Skip if notifications are disabled
    if (!notificationsEnabled) return;
    
    const now = Date.now();
    const cooldownKey = `${alertData.droneId}-${alertData.analysis.alertLevel}`;
    const lastNotification = notificationCooldown.get(cooldownKey) || 0;
    
    // Rate limiting based on device type and alert level
    const cooldownPeriod = isMobile 
      ? (alertData.analysis.alertLevel >= 3 ? 5000 : 15000) // 5s for critical, 15s for others on mobile
      : (alertData.analysis.alertLevel >= 3 ? 2000 : 8000);  // 2s for critical, 8s for others on desktop
    
    if (now - lastNotification < cooldownPeriod) {
      // Store pending notification for potential grouping
      setPendingNotifications(prev => [...prev, alertData]);
      return;
    }
    
    // Update cooldown
    setNotificationCooldown(prev => new Map(prev).set(cooldownKey, now));
    
    // Show notification with mobile-optimized settings
    const alertIcon = alertData.analysis.alertLevel >= 3 ? '🚨' : 
                     alertData.analysis.alertLevel >= 2 ? '⚠️' : '📍';
    
    const toastOptions = {
      duration: isMobile 
        ? (alertData.analysis.alertLevel >= 3 ? 4000 : 2500) // Shorter durations on mobile
        : (alertData.analysis.alertLevel >= 2 ? 6000 : 4000),
      icon: alertIcon,
      style: {
        background: alertData.analysis.alertLevel >= 3 ? '#fee2e2' : 
                   alertData.analysis.alertLevel >= 2 ? '#fef3c7' : '#e0f2fe',
        fontSize: isMobile ? '13px' : '14px',
        padding: isMobile ? '0.75rem' : '1rem',
        maxWidth: isMobile ? '85vw' : '400px',
      }
    };

    // Create condensed message for mobile
    const message = isMobile 
      ? `${alertIcon} Drone ${alertData.droneId}: ${getShortDescription(alertData.analysis)}`
      : alertData.analysis.description;

    if (alertData.analysis.alertLevel >= 3) {
      toast.error(message, toastOptions);
    } else if (alertData.analysis.alertLevel >= 2) {
      toast.error(message, toastOptions);
    } else {
      toast(message, toastOptions);
    }
  };
  
  // Helper function to create short descriptions for mobile
  const getShortDescription = (analysis) => {
    if (analysis.alertLevel >= 3) return 'Critical proximity';
    if (analysis.alertLevel >= 2) return 'Approaching';
    return analysis.movement === 'approaching' ? 'Detected' : 'Movement';
  };

  // Handle grouped notifications for mobile
  useEffect(() => {
    if (pendingNotifications.length > 0 && isMobile) {
      const timer = setTimeout(() => {
        const criticalCount = pendingNotifications.filter(n => n.analysis.alertLevel >= 3).length;
        const warningCount = pendingNotifications.filter(n => n.analysis.alertLevel === 2).length;
        const infoCount = pendingNotifications.filter(n => n.analysis.alertLevel < 2).length;
        
        if (criticalCount > 0) {
          toast.error(`🚨 ${criticalCount} critical alert${criticalCount > 1 ? 's' : ''}`, {
            duration: 5000,
            style: { background: '#fee2e2', fontSize: '13px' }
          });
        } else if (warningCount > 0) {
          toast.error(`⚠️ ${warningCount} warning${warningCount > 1 ? 's' : ''}`, {
            duration: 3000,
            style: { background: '#fef3c7', fontSize: '13px' }
          });
        } else if (infoCount > 0) {
          toast(`📍 ${infoCount} detection${infoCount > 1 ? 's' : ''}`, {
            duration: 2000,
            style: { background: '#e0f2fe', fontSize: '13px' }
          });
        }
        
        setPendingNotifications([]);
      }, 3000); // Group notifications for 3 seconds
      
      return () => clearTimeout(timer);
    }
  }, [pendingNotifications, isMobile]);

  useEffect(() => {
    if (isAuthenticated) {
      // Initialize socket connection
      const newSocket = io(APP_CONFIG.isProduction 
        ? window.location.origin
        : 'http://localhost:3001', {
        path: '/ws'
      });

      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
        
        // Mobile-friendly notification management
        handleMobileNotification(alertData);
      });

      // 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);
  };

  // Toggle notifications function
  const toggleNotifications = () => {
    const newValue = !notificationsEnabled;
    setNotificationsEnabled(newValue);
    localStorage.setItem('notificationsEnabled', newValue.toString());
    
    toast.success(
      newValue ? 'Notifications enabled' : 'Notifications disabled',
      { duration: 2000 }
    );
  };

  const value = {
    socket,
    connected,
    recentDetections,
    deviceStatus,
    movementAlerts,
    droneTracking,
    notificationsEnabled,
    toggleNotifications,
    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;
};
