import React, { useState, useEffect } from 'react';
import { MapContainer, TileLayer, Marker, Popup, Circle } from 'react-leaflet';
import { Icon } from 'leaflet';
import { useSocket } from '../contexts/SocketContext';
import api from '../services/api';
import { format } from 'date-fns';
import { 
  ServerIcon, 
  ExclamationTriangleIcon,
  SignalIcon,
  EyeIcon
} from '@heroicons/react/24/outline';

// Fix for default markers in React Leaflet
import 'leaflet/dist/leaflet.css';
import iconRetinaUrl from 'leaflet/dist/images/marker-icon-2x.png';
import iconUrl from 'leaflet/dist/images/marker-icon.png';
import shadowUrl from 'leaflet/dist/images/marker-shadow.png';

delete Icon.Default.prototype._getIconUrl;
Icon.Default.mergeOptions({
  iconRetinaUrl,
  iconUrl,
  shadowUrl,
});

// Custom icons
const createDeviceIcon = (status, hasDetections) => {
  let color = '#6b7280'; // gray for offline/inactive
  
  if (status === 'online') {
    color = hasDetections ? '#ef4444' : '#22c55e'; // red if detecting, green if online
  }
  
  return new Icon({
    iconUrl: `data:image/svg+xml;base64,${btoa(`
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="32" height="32">
        <circle cx="12" cy="12" r="10" fill="${color}" stroke="#fff" stroke-width="2"/>
        <path d="M12 8v4l3 3" stroke="#fff" stroke-width="2" fill="none"/>
      </svg>
    `)}`,
    iconSize: [32, 32],
    iconAnchor: [16, 16],
    popupAnchor: [0, -16],
  });
};

// Drone detection icon
const createDroneIcon = (rssi, droneType) => {
  // Color based on signal strength
  let color = '#ff6b6b'; // Default red
  
  if (rssi > -50) color = '#ff4757'; // Very strong - bright red
  else if (rssi > -60) color = '#ff6b6b'; // Strong - red
  else if (rssi > -70) color = '#ffa726'; // Medium - orange
  else if (rssi > -80) color = '#ffca28'; // Weak - yellow
  else color = '#66bb6a'; // Very weak - green
  
  return new Icon({
    iconUrl: `data:image/svg+xml;base64,${btoa(`
      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="28" height="28">
        <circle cx="12" cy="12" r="11" fill="${color}" stroke="#fff" stroke-width="2" opacity="0.8"/>
        <path d="M12 6l-2 4h4l-2-4zm0 6l-3 3h6l-3-3z" fill="#fff"/>
      </svg>
    `)}`,
    iconSize: [28, 28],
    iconAnchor: [14, 14],
    popupAnchor: [0, -14],
  });
};

const MapView = () => {
  const [devices, setDevices] = useState([]);
  const [selectedDevice, setSelectedDevice] = useState(null);
  const [loading, setLoading] = useState(true);
  const [mapCenter, setMapCenter] = useState([59.4, 18.1]); // Stockholm area center
  const [mapZoom, setMapZoom] = useState(11); // Closer zoom for Stockholm area
  const [showDroneDetections, setShowDroneDetections] = useState(true);
  const [droneDetectionHistory, setDroneDetectionHistory] = useState([]);
  const { recentDetections, deviceStatus } = useSocket();

  // Drone types mapping
  const droneTypes = {
    1: "DJI Mavic",
    2: "Racing Drone", 
    3: "DJI Phantom",
    4: "Fixed Wing",
    5: "Surveillance",
    0: "Unknown"
  };

  useEffect(() => {
    fetchDevices();
    const interval = setInterval(fetchDevices, 30000); // Refresh every 30 seconds
    return () => clearInterval(interval);
  }, []);

  // Update drone detection history when new detections arrive
  useEffect(() => {
    if (recentDetections.length > 0) {
      const latestDetection = recentDetections[0];
      
      // Add to history with timestamp for fade-out
      setDroneDetectionHistory(prev => [
        {
          ...latestDetection,
          timestamp: Date.now(),
          id: `${latestDetection.device_id}-${latestDetection.drone_id}-${latestDetection.device_timestamp}`
        },
        ...prev.slice(0, 19) // Keep last 20 detections
      ]);
    }
  }, [recentDetections]);

  // Clean up old detections (fade them out after 5 minutes)
  useEffect(() => {
    const cleanup = setInterval(() => {
      const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);
      setDroneDetectionHistory(prev => 
        prev.filter(detection => detection.timestamp > fiveMinutesAgo)
      );
    }, 30000); // Clean up every 30 seconds

    return () => clearInterval(cleanup);
  }, []);

  const fetchDevices = async () => {
    try {
      const response = await api.get('/devices/map');
      const deviceData = response.data.data;
      
      setDevices(deviceData);
      
      // Set map bounds to Stockholm area with all three detectors
      if (deviceData.length > 0 && devices.length === 0) {
        // Stockholm area bounds that include Arlanda, Naval Base, and Royal Castle
        const stockholmBounds = [
          [59.2, 17.8],  // Southwest
          [59.7, 18.4]   // Northeast
        ];
        setMapCenter([59.4, 18.1]); // Center of Stockholm area
        setMapZoom(11);
      }
    } catch (error) {
      console.error('Error fetching devices:', error);
    } finally {
      setLoading(false);
    }
  };

  const getDeviceStatus = (device) => {
    const realtimeStatus = deviceStatus[device.id];
    if (realtimeStatus) {
      return realtimeStatus.status;
    }
    return device.status || 'offline';
  };

  const getDeviceDetections = (deviceId) => {
    return recentDetections.filter(d => d.device_id === deviceId);
  };

  const getDetectionAge = (detection) => {
    const ageMs = Date.now() - detection.timestamp;
    const ageMinutes = ageMs / (1000 * 60);
    return ageMinutes;
  };

  const getDetectionOpacity = (detection) => {
    const age = getDetectionAge(detection);
    if (age < 1) return 1.0; // Full opacity for first minute
    if (age < 3) return 0.8; // 80% for 1-3 minutes
    if (age < 5) return 0.5; // 50% for 3-5 minutes
    return 0.2; // 20% for older detections
  };

  if (loading) {
    return (
      <div className="flex items-center justify-center h-96">
        <div className="animate-spin rounded-full h-32 w-32 border-b-2 border-primary-600"></div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <div>
          <h3 className="text-lg leading-6 font-medium text-gray-900">
            Device Map
          </h3>
          <p className="mt-1 text-sm text-gray-500">
            Real-time view of all devices and drone detections
          </p>
        </div>
        
        <div className="flex items-center space-x-4">
          <label className="flex items-center space-x-2">
            <input
              type="checkbox"
              checked={showDroneDetections}
              onChange={(e) => setShowDroneDetections(e.target.checked)}
              className="rounded border-gray-300 text-primary-600 focus:ring-primary-500"
            />
            <span className="text-sm text-gray-700">Show Drone Detections</span>
          </label>
          
          {droneDetectionHistory.length > 0 && (
            <div className="text-sm text-gray-500">
              {droneDetectionHistory.length} recent detection{droneDetectionHistory.length > 1 ? 's' : ''}
            </div>
          )}
        </div>
      </div>

      {/* Map */}
      <div className="bg-white rounded-lg shadow-lg overflow-hidden">
        <div className="h-96 lg:h-[600px] relative">
          <MapContainer
            center={mapCenter}
            zoom={mapZoom}
            className="h-full w-full"
            whenCreated={(map) => {
              // Set bounds to Stockholm area to show all three detectors
              const stockholmBounds = [
                [59.2, 17.8],  // Southwest 
                [59.7, 18.4]   // Northeast
              ];
              map.fitBounds(stockholmBounds, { padding: [20, 20] });
            }}
          >
            <TileLayer
              attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
              url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
            />
            
            {devices
              .filter(device => device.geo_lat && device.geo_lon)
              .map(device => {
                const status = getDeviceStatus(device);
                const detections = getDeviceDetections(device.id);
                const hasRecentDetections = detections.length > 0;
                
                return (
                  <Marker
                    key={device.id}
                    position={[device.geo_lat, device.geo_lon]}
                    icon={createDeviceIcon(status, hasRecentDetections)}
                    eventHandlers={{
                      click: () => setSelectedDevice(device),
                    }}
                  >
                    <Popup>
                      <DevicePopup 
                        device={device} 
                        status={status}
                        detections={detections}
                      />
                    </Popup>
                  </Marker>
                );
              })}
            
            {/* Drone Detection Markers */}
            {showDroneDetections && droneDetectionHistory
              .filter(detection => detection.geo_lat && detection.geo_lon)
              .map(detection => {
                const opacity = getDetectionOpacity(detection);
                const age = getDetectionAge(detection);
                
                return (
                  <React.Fragment key={detection.id}>
                    <Marker
                      position={[detection.geo_lat, detection.geo_lon]}
                      icon={createDroneIcon(detection.rssi, detection.drone_type)}
                      opacity={opacity}
                    >
                      <Popup>
                        <DroneDetectionPopup detection={detection} age={age} droneTypes={droneTypes} />
                      </Popup>
                    </Marker>
                    
                    {/* Detection range circle for recent detections */}
                    {age < 2 && (
                      <Circle
                        center={[detection.geo_lat, detection.geo_lon]}
                        radius={200} // 200m detection radius
                        pathOptions={{
                          color: detection.rssi > -60 ? '#ff4757' : '#ffa726',
                          fillColor: detection.rssi > -60 ? '#ff4757' : '#ffa726',
                          fillOpacity: 0.1 * opacity,
                          weight: 2,
                          opacity: opacity * 0.5
                        }}
                      />
                    )}
                  </React.Fragment>
                );
              })}
          </MapContainer>
          
          {/* Map Legend - Fixed positioning and visibility */}
          <div className="absolute bottom-4 left-4 bg-white rounded-lg p-3 shadow-lg text-xs border border-gray-200 z-[1000] max-w-xs">
            <div className="font-semibold mb-2 text-gray-800">Map Legend</div>
            <div className="space-y-1.5">
              <div className="flex items-center space-x-2">
                <div className="w-3 h-3 bg-green-500 rounded-full border border-green-600"></div>
                <span className="text-gray-700">Device Online</span>
              </div>
              <div className="flex items-center space-x-2">
                <div className="w-3 h-3 bg-red-500 rounded-full border border-red-600"></div>
                <span className="text-gray-700">Device Detecting</span>
              </div>
              <div className="flex items-center space-x-2">
                <div className="w-3 h-3 bg-gray-500 rounded-full border border-gray-600"></div>
                <span className="text-gray-700">Device Offline</span>
              </div>
              {showDroneDetections && (
                <>
                  <div className="border-t border-gray-200 mt-2 pt-2">
                    <div className="font-medium text-gray-800 mb-1">Drone Detections:</div>
                  </div>
                  <div className="flex items-center space-x-2">
                    <div className="w-3 h-3 bg-red-500 rounded-full border border-red-600 opacity-100"></div>
                    <span className="text-gray-700">Strong Signal (&gt;-60dBm)</span>
                  </div>
                  <div className="flex items-center space-x-2">
                    <div className="w-3 h-3 bg-orange-500 rounded-full border border-orange-600 opacity-90"></div>
                    <span className="text-gray-700">Medium Signal (-60 to -70dBm)</span>
                  </div>
                  <div className="flex items-center space-x-2">
                    <div className="w-3 h-3 bg-green-500 rounded-full border border-green-600 opacity-80"></div>
                    <span className="text-gray-700">Weak Signal (&lt;-70dBm)</span>
                  </div>
                  <div className="flex items-center space-x-2">
                    <div className="w-3 h-3 border-2 border-red-400 rounded-full bg-transparent"></div>
                    <span className="text-gray-700">Detection Range</span>
                  </div>
                </>
              )}
            </div>
          </div>
        </div>
      </div>

      {/* Device List */}
      <div className="bg-white rounded-lg shadow">
        <div className="px-6 py-4 border-b border-gray-200">
          <h3 className="text-lg font-medium text-gray-900">Device Status</h3>
        </div>
        <div className="divide-y divide-gray-200">
          {devices.map(device => {
            const status = getDeviceStatus(device);
            const detections = getDeviceDetections(device.id);
            
            return (
              <DeviceListItem
                key={device.id}
                device={device}
                status={status}
                detections={detections}
                onClick={() => setSelectedDevice(device)}
              />
            );
          })}
          {devices.length === 0 && (
            <div className="px-6 py-8 text-center text-gray-500">
              No devices found
            </div>
          )}
        </div>
      </div>
    </div>
  );
};

const DevicePopup = ({ device, status, detections }) => (
  <div className="p-2 min-w-[200px]">
    <div className="flex items-center justify-between mb-2">
      <h4 className="font-semibold text-gray-900">
        {device.name || `Device ${device.id}`}
      </h4>
      <span className={`px-2 py-1 rounded-full text-xs font-medium ${
        status === 'online' 
          ? 'bg-green-100 text-green-800'
          : 'bg-red-100 text-red-800'
      }`}>
        {status}
      </span>
    </div>
    
    {device.location_description && (
      <p className="text-sm text-gray-600 mb-2">
        {device.location_description}
      </p>
    )}
    
    <div className="text-xs text-gray-500 space-y-1">
      <div>ID: {device.id}</div>
      <div>Coordinates: {device.geo_lat}, {device.geo_lon}</div>
      {device.last_heartbeat && (
        <div>
          Last seen: {format(new Date(device.last_heartbeat), 'MMM dd, HH:mm')}
        </div>
      )}
    </div>
    
    {detections.length > 0 && (
      <div className="mt-3 pt-2 border-t border-gray-200">
        <div className="flex items-center space-x-1 text-red-600 text-sm font-medium mb-1">
          <ExclamationTriangleIcon className="h-4 w-4" />
          <span>{detections.length} recent detection{detections.length > 1 ? 's' : ''}</span>
        </div>
        {detections.slice(0, 3).map((detection, index) => (
          <div key={index} className="text-xs text-gray-600">
            Drone {detection.drone_id} • {detection.freq}MHz • {detection.rssi}dBm
          </div>
        ))}
      </div>
    )}
  </div>
);

const DroneDetectionPopup = ({ detection, age, droneTypes }) => (
  <div className="p-2 min-w-[250px]">
    <div className="flex items-center justify-between mb-2">
      <h4 className="font-semibold text-red-700 flex items-center space-x-1">
        <span>🚨</span>
        <span>Drone Detection</span>
      </h4>
      <span className={`px-2 py-1 rounded-full text-xs font-medium ${
        age < 1 ? 'bg-red-100 text-red-800' :
        age < 3 ? 'bg-orange-100 text-orange-800' :
        'bg-gray-100 text-gray-800'
      }`}>
        {age < 1 ? 'LIVE' : `${Math.round(age)}m ago`}
      </span>
    </div>
    
    <div className="space-y-2 text-sm">
      <div className="grid grid-cols-2 gap-2">
        <div>
          <span className="font-medium text-gray-700">Drone ID:</span>
          <div className="text-gray-900">{detection.drone_id}</div>
        </div>
        <div>
          <span className="font-medium text-gray-700">Type:</span>
          <div className="text-gray-900">{droneTypes[detection.drone_type] || 'Unknown'}</div>
        </div>
      </div>
      
      <div className="grid grid-cols-2 gap-2">
        <div>
          <span className="font-medium text-gray-700">RSSI:</span>
          <div className={`font-mono ${
            detection.rssi > -50 ? 'text-red-600' :
            detection.rssi > -70 ? 'text-orange-600' :
            'text-green-600'
          }`}>
            {detection.rssi}dBm
          </div>
        </div>
        <div>
          <span className="font-medium text-gray-700">Frequency:</span>
          <div className="text-gray-900">{detection.freq}MHz</div>
        </div>
      </div>
      
      <div className="grid grid-cols-2 gap-2">
        <div>
          <span className="font-medium text-gray-700">Confidence:</span>
          <div className="text-gray-900">{(detection.confidence_level * 100).toFixed(0)}%</div>
        </div>
        <div>
          <span className="font-medium text-gray-700">Duration:</span>
          <div className="text-gray-900">{(detection.signal_duration / 1000).toFixed(1)}s</div>
        </div>
      </div>
      
      {/* Movement Analysis */}
      {detection.movement_analysis && (
        <div className="pt-2 border-t border-gray-200">
          <span className="font-medium text-gray-700 block mb-1">Movement Analysis:</span>
          <div className="text-xs space-y-1">
            <div className={`px-2 py-1 rounded ${
              detection.movement_analysis.alertLevel >= 3 ? 'bg-red-100 text-red-800' :
              detection.movement_analysis.alertLevel >= 2 ? 'bg-orange-100 text-orange-800' :
              detection.movement_analysis.alertLevel >= 1 ? 'bg-blue-100 text-blue-800' :
              'bg-gray-100 text-gray-800'
            }`}>
              {detection.movement_analysis.description}
            </div>
            
            {detection.movement_analysis.rssiTrend && (
              <div className="flex items-center space-x-2 mt-1">
                <span className="text-gray-600">Trend:</span>
                <span className={`font-medium ${
                  detection.movement_analysis.rssiTrend.trend === 'STRENGTHENING' ? 'text-red-600' :
                  detection.movement_analysis.rssiTrend.trend === 'WEAKENING' ? 'text-green-600' :
                  'text-gray-600'
                }`}>
                  {detection.movement_analysis.rssiTrend.trend}
                  {detection.movement_analysis.rssiTrend.change !== 0 && (
                    <span className="ml-1">
                      ({detection.movement_analysis.rssiTrend.change > 0 ? '+' : ''}{detection.movement_analysis.rssiTrend.change.toFixed(1)}dB)
                    </span>
                  )}
                </span>
              </div>
            )}
            
            {detection.movement_analysis.proximityLevel && (
              <div className="flex items-center space-x-2">
                <span className="text-gray-600">Proximity:</span>
                <span className={`px-1 py-0.5 rounded text-xs font-medium ${
                  detection.movement_analysis.proximityLevel === 'VERY_CLOSE' ? 'bg-red-100 text-red-700' :
                  detection.movement_analysis.proximityLevel === 'CLOSE' ? 'bg-orange-100 text-orange-700' :
                  detection.movement_analysis.proximityLevel === 'MEDIUM' ? 'bg-yellow-100 text-yellow-700' :
                  'bg-green-100 text-green-700'
                }`}>
                  {detection.movement_analysis.proximityLevel.replace('_', ' ')}
                </span>
              </div>
            )}
          </div>
        </div>
      )}
      
      <div className="pt-2 border-t border-gray-200">
        <div className="text-xs text-gray-500">
          <div>Detected by: Device {detection.device_id}</div>
          <div>Location: {detection.geo_lat?.toFixed(4)}, {detection.geo_lon?.toFixed(4)}</div>
          <div>Time: {format(new Date(detection.device_timestamp), 'MMM dd, HH:mm:ss')}</div>
        </div>
      </div>
    </div>
  </div>
);

const DeviceListItem = ({ device, status, detections, onClick }) => (
  <div 
    className="px-6 py-4 hover:bg-gray-50 cursor-pointer transition-colors"
    onClick={onClick}
  >
    <div className="flex items-center justify-between">
      <div className="flex items-center space-x-3">
        <div className={`w-3 h-3 rounded-full ${
          status === 'online' 
            ? detections.length > 0 ? 'bg-red-400 animate-pulse' : 'bg-green-400'
            : 'bg-gray-400'
        }`} />
        <div>
          <div className="text-sm font-medium text-gray-900">
            {device.name || `Device ${device.id}`}
          </div>
          <div className="text-sm text-gray-500">
            {device.location_description || `${device.geo_lat}, ${device.geo_lon}`}
          </div>
        </div>
      </div>
      
      <div className="flex items-center space-x-4">
        {detections.length > 0 && (
          <div className="flex items-center space-x-1 text-red-600">
            <ExclamationTriangleIcon className="h-4 w-4" />
            <span className="text-sm font-medium">{detections.length}</span>
          </div>
        )}
        
        <span className={`px-2 py-1 rounded-full text-xs font-medium ${
          status === 'online'
            ? 'bg-green-100 text-green-800'
            : 'bg-red-100 text-red-800'
        }`}>
          {status}
        </span>
      </div>
    </div>
  </div>
);

export default MapView;
