import { useMemo, useState, useRef, useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { Map, Marker, Popup, Source, Layer, NavigationControl } from 'react-map-gl/maplibre';
import type { MapRef } from 'react-map-gl/maplibre';
import { AircraftLayer } from '../layers/AircraftLayer';
import { SatelliteLayer } from '../layers/SatelliteLayer';
import { ShipLayer } from '../layers/ShipLayer';
import { DamagedShipLayer } from '../layers/DamagedShipLayer';
import { SeismicMarker } from '../layers/SeismicMarker';
import { OilFacilityLayer } from './OilFacilityLayer';
import { AirportLayer } from './AirportLayer';
import { MEFacilityLayer } from './MEFacilityLayer';
import { iranOilFacilities } from '../../data/oilFacilities';
import { middleEastAirports } from '../../data/airports';
import type { GeoEvent, Aircraft, SatellitePosition, Ship, LayerVisibility } from '../../types';
import { countryLabelsGeoJSON } from '../../data/countryLabels';
import maplibregl from 'maplibre-gl';
import 'maplibre-gl/dist/maplibre-gl.css';

interface Props {
  events: GeoEvent[];
  currentTime: number;
  aircraft: Aircraft[];
  satellites: SatellitePosition[];
  ships: Ship[];
  layers: LayerVisibility;
  hoveredShipMmsi?: string | null;
  focusShipMmsi?: string | null;
  onFocusShipClear?: () => void;
  flyToTarget?: { lat: number; lng: number; zoom?: number } | null;
  onFlyToDone?: () => void;
  seismicMarker?: { lat: number; lng: number; magnitude: number; place: string } | null;
}

// ESRI World Imagery + ESRI boundaries overlay
const SATELLITE_STYLE = {
  version: 8 as const,
  sources: {
    'esri-satellite': {
      type: 'raster' as const,
      tiles: [
        'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
      ],
      tileSize: 256,
      attribution: '&copy; Esri, Maxar, Earthstar Geographics',
      maxzoom: 19,
    },
    'esri-boundaries': {
      type: 'raster' as const,
      tiles: [
        'https://server.arcgisonline.com/ArcGIS/rest/services/Reference/World_Boundaries_and_Places/MapServer/tile/{z}/{y}/{x}',
      ],
      tileSize: 256,
      maxzoom: 19,
    },
  },
  layers: [
    { id: 'background', type: 'background' as const, paint: { 'background-color': '#000811' } },
    { id: 'satellite', type: 'raster' as const, source: 'esri-satellite' },
    { id: 'boundaries', type: 'raster' as const, source: 'esri-boundaries', paint: { 'raster-opacity': 0.65 } },
  ],
};

const EVENT_COLORS: Record<GeoEvent['type'], string> = {
  airstrike: '#ef4444',
  explosion: '#f97316',
  missile_launch: '#eab308',
  intercept: '#3b82f6',
  alert: '#a855f7',
  impact: '#ff0000',
  osint: '#06b6d4',
};

const SOURCE_COLORS: Record<string, string> = {
  US: '#ef4444',
  IL: '#22c55e',
  IR: '#ff0000',
  proxy: '#f59e0b',
};

function getEventColor(event: GeoEvent): string {
  if (event.type === 'impact') return '#ff0000';
  if (event.source && SOURCE_COLORS[event.source]) return SOURCE_COLORS[event.source];
  return EVENT_COLORS[event.type];
}

const EVENT_RADIUS: Record<GeoEvent['type'], number> = {
  airstrike: 12,
  explosion: 10,
  missile_launch: 8,
  intercept: 7,
  alert: 6,
  impact: 14,
  osint: 8,
};

export function SatelliteMap({ events, currentTime, aircraft, satellites, ships, layers, hoveredShipMmsi, focusShipMmsi, onFocusShipClear, flyToTarget, onFlyToDone, seismicMarker }: Props) {
  const { t } = useTranslation();
  const mapRef = useRef<MapRef>(null);
  const [selectedEventId, setSelectedEventId] = useState<string | null>(null);

  useEffect(() => {
    if (flyToTarget && mapRef.current) {
      mapRef.current.flyTo({
        center: [flyToTarget.lng, flyToTarget.lat],
        zoom: flyToTarget.zoom ?? 8,
        duration: 1200,
      });
      onFlyToDone?.();
    }
  }, [flyToTarget, onFlyToDone]);

  const visibleEvents = useMemo(() => {
    if (!layers.events) return [];
    return events.filter(e => e.timestamp <= currentTime);
  }, [events, currentTime, layers.events]);

  const selectedEvent = useMemo(
    () => visibleEvents.find(e => e.id === selectedEventId) || null,
    [visibleEvents, selectedEventId],
  );

  const countryLabels = useMemo(() => countryLabelsGeoJSON(), []);

  return (
    <Map
      ref={mapRef}
      initialViewState={{
        longitude: 53.0,
        latitude: 32.0,
        zoom: 5.5,
      }}
      style={{ width: '100%', height: '100%' }}
      mapStyle={SATELLITE_STYLE as maplibregl.StyleSpecification}
      attributionControl={false}
    >
      <NavigationControl position="top-right" />

      {/* Korean country labels */}
      <Source id="country-labels" type="geojson" data={countryLabels}>
        <Layer
          id="country-label-lg"
          type="symbol"
          filter={['==', ['get', 'rank'], 1]}
          layout={{
            'text-field': ['get', 'name'],
            'text-font': ['Open Sans Bold'],
            'text-size': 15,
            'text-allow-overlap': false,
            'text-ignore-placement': false,
          }}
          paint={{
            'text-color': '#1a1a2e',
            'text-halo-color': 'rgba(255,255,255,0.7)',
            'text-halo-width': 2,
          }}
        />
        <Layer
          id="country-label-md"
          type="symbol"
          filter={['==', ['get', 'rank'], 2]}
          layout={{
            'text-field': ['get', 'name'],
            'text-font': ['Open Sans Bold'],
            'text-size': 12,
            'text-allow-overlap': false,
          }}
          paint={{
            'text-color': '#2a2a3e',
            'text-halo-color': 'rgba(255,255,255,0.6)',
            'text-halo-width': 1.5,
          }}
        />
        <Layer
          id="country-label-sm"
          type="symbol"
          filter={['==', ['get', 'rank'], 3]}
          minzoom={4}
          layout={{
            'text-field': ['get', 'name'],
            'text-font': ['Open Sans Bold'],
            'text-size': 10,
            'text-allow-overlap': false,
          }}
          paint={{
            'text-color': '#333350',
            'text-halo-color': 'rgba(255,255,255,0.5)',
            'text-halo-width': 1.5,
          }}
        />
      </Source>

      {/* Event markers */}
      {visibleEvents.map(ev => (
        <Marker
          key={ev.id}
          longitude={ev.lng}
          latitude={ev.lat}
          anchor="center"
          onClick={e => { e.originalEvent.stopPropagation(); setSelectedEventId(ev.id); }}
        >
          <div
            className="rounded-full cursor-pointer"
            style={{
              width: EVENT_RADIUS[ev.type],
              height: EVENT_RADIUS[ev.type],
              background: getEventColor(ev),
              border: '2px solid rgba(255,255,255,0.8)',
              boxShadow: `0 0 8px ${getEventColor(ev)}`,
            }}
          />
        </Marker>
      ))}

      {/* Popup */}
      {selectedEvent && (
        <Popup
          longitude={selectedEvent.lng}
          latitude={selectedEvent.lat}
          anchor="bottom"
          onClose={() => setSelectedEventId(null)}
          closeOnClick={false}
          maxWidth="320px"
          className="event-popup"
        >
          <div className="min-w-[200px] max-w-[320px]">
            {selectedEvent.source && (
              <span
                className="inline-block rounded-sm text-[10px] font-bold text-white mb-1 px-1.5 py-px"
                style={{ background: getEventColor(selectedEvent) }}
              >
                {t(`source.${selectedEvent.source}`)}
              </span>
            )}
            {selectedEvent.type === 'impact' && (
              <div className="inline-block rounded-sm text-[11px] font-bold text-white mb-1.5 px-2 py-[3px] bg-kcg-event-impact">
                {t('popup.impactSite')}
              </div>
            )}
            <div className="text-kcg-text"><strong>{selectedEvent.label}</strong></div>
            <span className="text-xs text-kcg-muted">
              {new Date(selectedEvent.timestamp + 9 * 3600_000).toISOString().slice(0, 16).replace('T', ' ')} KST
            </span>
            {selectedEvent.description && (
              <p className="mt-1.5 mb-0 text-[13px] text-kcg-text-secondary">{selectedEvent.description}</p>
            )}
            {selectedEvent.imageUrl && (
              <div className="mt-2">
                <img
                  src={selectedEvent.imageUrl}
                  alt={selectedEvent.imageCaption || selectedEvent.label}
                  className="w-full rounded max-h-[180px] object-cover"
                  onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}
                />
                {selectedEvent.imageCaption && (
                  <div className="text-[10px] text-kcg-muted mt-[3px]">{selectedEvent.imageCaption}</div>
                )}
              </div>
            )}
            <div className="text-[10px] text-kcg-dim mt-1.5">
              {selectedEvent.lat.toFixed(4)}&deg;N, {selectedEvent.lng.toFixed(4)}&deg;E
            </div>
          </div>
        </Popup>
      )}

      {/* Overlay layers */}
      {layers.aircraft && <AircraftLayer aircraft={aircraft} militaryOnly={layers.militaryOnly} />}
      {layers.satellites && <SatelliteLayer satellites={satellites} />}
      {layers.ships && <ShipLayer ships={ships} militaryOnly={layers.militaryOnly} koreanOnly={layers.koreanShips} hoveredMmsi={hoveredShipMmsi} focusMmsi={focusShipMmsi} onFocusClear={onFocusShipClear} />}
      <DamagedShipLayer currentTime={currentTime} />
      {seismicMarker && <SeismicMarker {...seismicMarker} />}
      {layers.oilFacilities && <OilFacilityLayer facilities={iranOilFacilities} currentTime={currentTime} />}
      {layers.airports && <AirportLayer airports={middleEastAirports} />}
      {layers.meFacilities && <MEFacilityLayer />}
    </Map>
  );
}
