'use client';

import { useEffect, useMemo } from 'react';
import { MapContainer, TileLayer, Polyline, Marker, useMap } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';

interface PortRouteMapProps {
  portA: { lat: number; lng: number };
  portB: { lat: number; lng: number };
  height?: string;
}

// Fix Leaflet marker icons
const DefaultIcon = L.icon({
  iconUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-icon.png',
  shadowUrl: 'https://unpkg.com/leaflet@1.9.4/dist/images/marker-shadow.png',
  iconSize: [25, 41],
  iconAnchor: [12, 41],
});
L.Marker.prototype.options.icon = DefaultIcon;

// Maritime waypoints for major shipping routes
const WAYPOINTS = {
  // Mediterranean / Suez route
  gibraltar: { lat: 36.1, lng: -5.3 },
  suezNorth: { lat: 31.2, lng: 32.3 },
  suezSouth: { lat: 29.9, lng: 32.5 },
  babElMandeb: { lat: 12.6, lng: 43.3 },

  // Indian Ocean
  sriLanka: { lat: 6.0, lng: 80.0 },

  // Southeast Asia
  malacca: { lat: 1.3, lng: 103.8 },
  singapore: { lat: 1.2, lng: 103.8 },

  // East Asia
  hongKong: { lat: 22.3, lng: 114.2 },
  taiwan: { lat: 23.5, lng: 121.0 },

  // Atlantic
  azores: { lat: 38.7, lng: -27.2 },

  // Americas
  panama: { lat: 9.0, lng: -79.5 },

  // Cape route (alternative to Suez)
  capeTown: { lat: -34.0, lng: 18.5 },
  capeAgulhas: { lat: -34.8, lng: 20.0 },
};

type Region =
  | 'northEurope'
  | 'medEurope'
  | 'eastAsia'
  | 'southeastAsia'
  | 'india'
  | 'middleEast'
  | 'eastAfrica'
  | 'westAfrica'
  | 'northAmerica'
  | 'southAmerica'
  | 'oceania'
  | 'unknown';

// Determine the region of a port based on coordinates
function getRegion(port: { lat: number; lng: number }): Region {
  const { lat, lng } = port;

  // North Europe (including UK, Scandinavia, North Sea, Baltic)
  if (lat > 45 && lat < 70 && lng > -15 && lng < 30) return 'northEurope';

  // Mediterranean Europe
  if (lat > 30 && lat <= 45 && lng > -10 && lng < 40) return 'medEurope';

  // East Asia (China, Japan, Korea)
  if (lat > 20 && lat < 55 && lng > 100 && lng < 150) return 'eastAsia';

  // Southeast Asia (Vietnam, Thailand, Malaysia, Indonesia, Philippines)
  if (lat > -10 && lat <= 20 && lng > 95 && lng < 130) return 'southeastAsia';

  // India / South Asia
  if (lat > 5 && lat < 35 && lng > 65 && lng < 95) return 'india';

  // Middle East (Persian Gulf, Red Sea)
  if (lat > 10 && lat < 35 && lng > 30 && lng < 65) return 'middleEast';

  // East Africa
  if (lat > -35 && lat < 15 && lng > 25 && lng < 55) return 'eastAfrica';

  // West Africa
  if (lat > -35 && lat < 35 && lng > -25 && lng < 25) return 'westAfrica';

  // North America (East Coast mainly)
  if (lat > 10 && lat < 60 && lng > -130 && lng < -50) return 'northAmerica';

  // South America
  if (lat > -60 && lat <= 10 && lng > -90 && lng < -30) return 'southAmerica';

  // Oceania (Australia, New Zealand)
  if (lat > -50 && lat < 0 && lng > 110 && lng < 180) return 'oceania';

  return 'unknown';
}

// Calculate maritime route waypoints between two ports
function calculateMaritimeRoute(
  portA: { lat: number; lng: number },
  portB: { lat: number; lng: number }
): Array<{ lat: number; lng: number }> {
  const regionA = getRegion(portA);
  const regionB = getRegion(portB);

  const route: Array<{ lat: number; lng: number }> = [portA];

  // Europe to East Asia via Suez
  if (
    (regionA === 'northEurope' || regionA === 'medEurope') &&
    (regionB === 'eastAsia' || regionB === 'southeastAsia')
  ) {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.malacca);
    if (regionB === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
    }
  }
  // East Asia to Europe via Suez (reverse)
  else if (
    (regionA === 'eastAsia' || regionA === 'southeastAsia') &&
    (regionB === 'northEurope' || regionB === 'medEurope')
  ) {
    if (regionA === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
    }
    route.push(WAYPOINTS.malacca);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // Europe to India via Suez
  else if ((regionA === 'northEurope' || regionA === 'medEurope') && regionB === 'india') {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.babElMandeb);
  }
  // India to Europe via Suez (reverse)
  else if (regionA === 'india' && (regionB === 'northEurope' || regionB === 'medEurope')) {
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // Europe to Middle East via Suez
  else if ((regionA === 'northEurope' || regionA === 'medEurope') && regionB === 'middleEast') {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
  }
  // Middle East to Europe via Suez (reverse)
  else if (regionA === 'middleEast' && (regionB === 'northEurope' || regionB === 'medEurope')) {
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // Europe to Southeast Asia
  else if ((regionA === 'northEurope' || regionA === 'medEurope') && regionB === 'southeastAsia') {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.malacca);
  }
  // Southeast Asia to Europe (reverse)
  else if (regionA === 'southeastAsia' && (regionB === 'northEurope' || regionB === 'medEurope')) {
    route.push(WAYPOINTS.malacca);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // East Asia to India
  else if ((regionA === 'eastAsia' || regionA === 'southeastAsia') && regionB === 'india') {
    if (regionA === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
    }
    route.push(WAYPOINTS.malacca);
    route.push(WAYPOINTS.sriLanka);
  }
  // India to East Asia (reverse)
  else if (regionA === 'india' && (regionB === 'eastAsia' || regionB === 'southeastAsia')) {
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.malacca);
    if (regionB === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
    }
  }
  // Europe to East Africa
  else if ((regionA === 'northEurope' || regionA === 'medEurope') && regionB === 'eastAfrica') {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.babElMandeb);
  }
  // East Africa to Europe (reverse)
  else if (regionA === 'eastAfrica' && (regionB === 'northEurope' || regionB === 'medEurope')) {
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // Europe to Oceania via Suez
  else if ((regionA === 'northEurope' || regionA === 'medEurope') && regionB === 'oceania') {
    if (regionA === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
    route.push(WAYPOINTS.suezNorth);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.malacca);
  }
  // Oceania to Europe (reverse)
  else if (regionA === 'oceania' && (regionB === 'northEurope' || regionB === 'medEurope')) {
    route.push(WAYPOINTS.malacca);
    route.push(WAYPOINTS.sriLanka);
    route.push(WAYPOINTS.babElMandeb);
    route.push(WAYPOINTS.suezSouth);
    route.push(WAYPOINTS.suezNorth);
    if (regionB === 'northEurope') {
      route.push(WAYPOINTS.gibraltar);
    }
  }
  // North Europe to Med Europe (simple Atlantic)
  else if (regionA === 'northEurope' && regionB === 'medEurope') {
    route.push(WAYPOINTS.gibraltar);
  }
  // Med Europe to North Europe (reverse)
  else if (regionA === 'medEurope' && regionB === 'northEurope') {
    route.push(WAYPOINTS.gibraltar);
  }
  // East Asia to Oceania
  else if ((regionA === 'eastAsia' || regionA === 'southeastAsia') && regionB === 'oceania') {
    if (regionA === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
      route.push(WAYPOINTS.malacca);
    }
  }
  // Oceania to East Asia (reverse)
  else if (regionA === 'oceania' && (regionB === 'eastAsia' || regionB === 'southeastAsia')) {
    route.push(WAYPOINTS.malacca);
    if (regionB === 'eastAsia') {
      route.push(WAYPOINTS.hongKong);
    }
  }

  // Add destination
  route.push(portB);

  return route;
}

// Component to control map view (fitBounds)
function MapController({ routePoints }: { routePoints: Array<{ lat: number; lng: number }> }) {
  const map = useMap();

  useEffect(() => {
    if (routePoints.length < 2) return;

    // Create bounds from all route points
    const bounds = L.latLngBounds(routePoints.map(p => [p.lat, p.lng] as [number, number]));

    // Fit the map to show all points with padding
    map.fitBounds(bounds, {
      padding: [50, 50],
      maxZoom: 6,
    });
  }, [map, routePoints]);

  return null;
}

export default function PortRouteMap({ portA, portB, height = '500px' }: PortRouteMapProps) {
  // Calculate the maritime route with waypoints
  const routePoints = useMemo(
    () => calculateMaritimeRoute(portA, portB),
    [portA.lat, portA.lng, portB.lat, portB.lng]
  );

  // Convert route points to Leaflet positions
  const positions: [number, number][] = routePoints.map(p => [p.lat, p.lng]);

  // Calculate initial center (will be adjusted by MapController)
  const center = {
    lat: (portA.lat + portB.lat) / 2,
    lng: (portA.lng + portB.lng) / 2,
  };

  return (
    <div style={{ height }}>
      <MapContainer
        center={[center.lat, center.lng]}
        zoom={2}
        style={{ height: '100%', width: '100%' }}
        scrollWheelZoom={false}
      >
        <TileLayer
          url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
          attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
        />

        {/* Auto-fit bounds to show entire route */}
        <MapController routePoints={routePoints} />

        {/* Origin marker */}
        <Marker position={[portA.lat, portA.lng]} />

        {/* Destination marker */}
        <Marker position={[portB.lat, portB.lng]} />

        {/* Maritime route polyline */}
        <Polyline
          positions={positions}
          pathOptions={{
            color: '#2563eb',
            weight: 3,
            opacity: 0.8,
            dashArray: '10, 6',
          }}
        />
      </MapContainer>
    </div>
  );
}
