import { useEffect, useMemo, useState, useRef } 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 'maplibre-gl/dist/maplibre-gl.css';

export interface FlyToTarget {
  lat: number;
  lng: number;
  zoom?: number;
}

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

// MarineTraffic-style: dark ocean + satellite land + nautical overlay
const MAP_STYLE = {
  version: 8 as const,
  sources: {
    'satellite': {
      type: 'raster' as const,
      tiles: [
        'https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}',
      ],
      tileSize: 256,
      maxzoom: 19,
      attribution: '&copy; Esri, Maxar',
    },
    'carto-dark': {
      type: 'raster' as const,
      tiles: [
        'https://a.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png',
        'https://b.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png',
        'https://c.basemaps.cartocdn.com/dark_nolabels/{z}/{x}/{y}{r}.png',
      ],
      tileSize: 256,
    },
    'opensea': {
      type: 'raster' as const,
      tiles: [
        'https://tiles.openseamap.org/seamark/{z}/{x}/{y}.png',
      ],
      tileSize: 256,
      maxzoom: 18,
    },
  },
  layers: [
    { id: 'background', type: 'background' as const, paint: { 'background-color': '#0b1526' } },
    { id: 'satellite-base', type: 'raster' as const, source: 'satellite', paint: { 'raster-brightness-max': 0.45, 'raster-saturation': -0.3, 'raster-contrast': 0.1 } },
    { id: 'dark-overlay', type: 'raster' as const, source: 'carto-dark', paint: { 'raster-opacity': 0.55 } },
    { id: 'seamark', type: 'raster' as const, source: 'opensea', paint: { 'raster-opacity': 0.6 } },
  ],
};

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 ReplayMap({ events, currentTime, aircraft, satellites, ships, layers, flyToTarget, onFlyToDone, initialCenter, initialZoom, hoveredShipMmsi, focusShipMmsi, onFocusShipClear, 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(
    () => events.filter(e => e.timestamp <= currentTime),
    [events, currentTime],
  );

  const impactEvents = useMemo(
    () => visibleEvents.filter(e => e.type === 'impact'),
    [visibleEvents],
  );
  const otherEvents = useMemo(
    () => visibleEvents.filter(e => e.type !== 'impact'),
    [visibleEvents],
  );

  const newEvents = useMemo(
    () => visibleEvents.filter(e => {
      const age = currentTime - e.timestamp;
      return age >= 0 && age < 600_000;
    }),
    [visibleEvents, currentTime],
  );

  const justActivated = useMemo(
    () => visibleEvents.filter(e => {
      const age = currentTime - e.timestamp;
      return age >= 0 && age < 120_000 &&
        (e.type === 'airstrike' || e.type === 'impact' || e.type === 'explosion');
    }),
    [visibleEvents, currentTime],
  );

  const trajectoryData = useMemo(() => {
    const launches = visibleEvents.filter(e => e.type === 'missile_launch');
    const targets = visibleEvents.filter(e => e.type === 'impact' || e.type === 'airstrike' || e.type === 'explosion');
    if (launches.length === 0 || targets.length === 0) {
      return { type: 'FeatureCollection' as const, features: [] as GeoJSON.Feature[] };
    }
    return {
      type: 'FeatureCollection' as const,
      features: launches.map(launch => ({
        type: 'Feature' as const,
        properties: {},
        geometry: {
          type: 'LineString' as const,
          coordinates: [[launch.lng, launch.lat], [targets[0].lng, targets[0].lat]],
        },
      })),
    };
  }, [visibleEvents]);

  const selectedEvent = selectedEventId
    ? visibleEvents.find(e => e.id === selectedEventId) ?? null
    : null;

  return (
    <Map
      ref={mapRef}
      initialViewState={{ longitude: initialCenter?.lng ?? 44, latitude: initialCenter?.lat ?? 31.5, zoom: initialZoom ?? 5 }}
      style={{ width: '100%', height: '100%' }}
      mapStyle={MAP_STYLE}
    >
      <NavigationControl position="top-right" />

      <Source id="country-labels" type="geojson" data={countryLabelsGeoJSON()}>
        <Layer
          id="country-label-lg"
          type="symbol"
          filter={['==', ['get', 'rank'], 1]}
          layout={{
            'text-field': ['get', 'name'],
            'text-size': 15,
            'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
            'text-allow-overlap': false,
            'text-ignore-placement': false,
            'text-padding': 6,
          }}
          paint={{
            'text-color': '#e2e8f0',
            'text-halo-color': '#000000',
            'text-halo-width': 2,
            'text-opacity': 0.9,
          }}
        />
        <Layer
          id="country-label-md"
          type="symbol"
          filter={['==', ['get', 'rank'], 2]}
          layout={{
            'text-field': ['get', 'name'],
            'text-size': 12,
            'text-font': ['Open Sans Bold', 'Arial Unicode MS Bold'],
            'text-allow-overlap': false,
            'text-ignore-placement': false,
            'text-padding': 4,
          }}
          paint={{
            'text-color': '#94a3b8',
            'text-halo-color': '#000000',
            'text-halo-width': 1.5,
            'text-opacity': 0.85,
          }}
        />
        <Layer
          id="country-label-sm"
          type="symbol"
          filter={['==', ['get', 'rank'], 3]}
          minzoom={5}
          layout={{
            'text-field': ['get', 'name'],
            'text-size': 10,
            'text-font': ['Open Sans Regular', 'Arial Unicode MS Regular'],
            'text-allow-overlap': false,
            'text-ignore-placement': false,
            'text-padding': 2,
          }}
          paint={{
            'text-color': '#64748b',
            'text-halo-color': '#000000',
            'text-halo-width': 1,
            'text-opacity': 0.75,
          }}
        />
      </Source>

      {layers.events && (
        <>
          {trajectoryData.features.length > 0 && (
            <Source id="trajectories" type="geojson" data={trajectoryData}>
              <Layer
                id="trajectory-lines"
                type="line"
                paint={{
                  'line-color': '#eab308',
                  'line-width': 1.5,
                  'line-opacity': 0.4,
                  'line-dasharray': [8, 4],
                }}
              />
            </Source>
          )}

          {newEvents.map(event => {
            const color = getEventColor(event);
            const size = EVENT_RADIUS[event.type] * 5;
            return (
              <Marker key={`pulse-${event.id}`} longitude={event.lng} latitude={event.lat} anchor="center">
                <div className="gl-pulse-ring rounded-full pointer-events-none" style={{
                  width: size, height: size,
                  border: `2px solid ${color}`,
                }} />
              </Marker>
            );
          })}

          {justActivated.map(event => {
            const color = getEventColor(event);
            const size = event.type === 'impact' ? 100 : 70;
            return (
              <Marker key={`shock-${event.id}`} longitude={event.lng} latitude={event.lat} anchor="center">
                <div className="gl-shockwave rounded-full pointer-events-none" style={{
                  width: size, height: size,
                  border: `3px solid ${color}`,
                }} />
              </Marker>
            );
          })}

          {justActivated.map(event => {
            const color = getEventColor(event);
            const size = event.type === 'impact' ? 40 : 30;
            return (
              <Marker key={`flash-${event.id}`} longitude={event.lng} latitude={event.lat} anchor="center">
                <div className="gl-strike-flash rounded-full opacity-60 pointer-events-none" style={{
                  width: size, height: size,
                  background: color,
                }} />
              </Marker>
            );
          })}

          {otherEvents.map(event => {
            const ageMs = currentTime - event.timestamp;
            const ageHours = ageMs / 3600_000;
            const DAY_H = 24;
            const isRecent = ageHours <= DAY_H;
            const opacity = isRecent
              ? Math.max(0.85, 1 - ageHours * 0.006)
              : Math.max(0.15, 0.4 - (ageHours - DAY_H) * 0.005);
            const color = getEventColor(event);
            const isNew = ageMs >= 0 && ageMs < 600_000;
            const baseR = EVENT_RADIUS[event.type];
            const r = isNew ? baseR * 1.3 : isRecent ? baseR * 1.1 : baseR * 0.85;
            const size = r * 2;

            return (
              <Marker key={event.id} longitude={event.lng} latitude={event.lat} anchor="center">
                <div
                  className={`cursor-pointer ${isNew ? 'gl-event-flash' : ''}`}
                  onClick={(e) => { e.stopPropagation(); setSelectedEventId(event.id); }}
                >
                  <svg width={size} height={size} viewBox={`0 0 ${size} ${size}`}>
                    <circle
                      cx={r} cy={r} r={r - 1}
                      fill={color} fillOpacity={isNew ? 0.9 : isRecent ? opacity * 0.8 : opacity * 0.4}
                      stroke={color} strokeWidth={isNew ? 3 : isRecent ? 2.5 : 1}
                      opacity={isNew ? 1 : opacity}
                    />
                  </svg>
                </div>
              </Marker>
            );
          })}

          {impactEvents.map(event => {
            const ageMs = currentTime - event.timestamp;
            const ageHours = ageMs / 3600_000;
            const isRecent = ageHours <= 24;
            const impactOpacity = isRecent
              ? Math.max(0.8, 1 - ageHours * 0.008)
              : Math.max(0.2, 0.45 - (ageHours - 24) * 0.005);
            const s = isRecent ? 22 : 16;
            const c = s / 2;
            const sw = isRecent ? 1.5 : 1;
            return (
              <Marker key={event.id} longitude={event.lng} latitude={event.lat} anchor="center">
                <div className="relative cursor-pointer" style={{ opacity: impactOpacity }}
                  onClick={(e) => { e.stopPropagation(); setSelectedEventId(event.id); }}>
                  <svg viewBox={`0 0 ${s} ${s}`} width={s} height={s}>
                    <circle cx={c} cy={c} r={c * 0.77} fill="none" stroke="#ff0000" strokeWidth={sw} opacity={0.8} />
                    <circle cx={c} cy={c} r={c * 0.32} fill="none" stroke="#ff0000" strokeWidth={sw * 0.7} opacity={0.9} />
                    <circle cx={c} cy={c} r={c * 0.14} fill="#ff0000" opacity={1} />
                    <line x1={c} y1={0.5} x2={c} y2={c * 0.23} stroke="#ff0000" strokeWidth={sw} opacity={0.8} />
                    <line x1={c} y1={s - 0.5} x2={c} y2={s - c * 0.23} stroke="#ff0000" strokeWidth={sw} opacity={0.8} />
                    <line x1={0.5} y1={c} x2={c * 0.23} y2={c} stroke="#ff0000" strokeWidth={sw} opacity={0.8} />
                    <line x1={s - 0.5} y1={c} x2={s - c * 0.23} y2={c} stroke="#ff0000" strokeWidth={sw} opacity={0.8} />
                  </svg>
                  <div className="gl-impact-label">
                    {isRecent && <span className="gl-new-badge">NEW</span>}
                    {event.label}
                  </div>
                </div>
              </Marker>
            );
          })}

          {selectedEvent && (
            <Popup
              longitude={selectedEvent.lng}
              latitude={selectedEvent.lat}
              onClose={() => setSelectedEventId(null)}
              closeOnClick={false}
              anchor="bottom"
              maxWidth="320px"
              className="gl-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><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]">{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>
                )}
                {selectedEvent.type === 'impact' && (
                  <div className="text-[10px] text-kcg-muted mt-1.5">
                    {selectedEvent.lat.toFixed(4)}&deg;N, {selectedEvent.lng.toFixed(4)}&deg;E
                  </div>
                )}
              </div>
            </Popup>
          )}
        </>
      )}

      {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} />}
      {layers.ships && <DamagedShipLayer currentTime={currentTime} />}
      {seismicMarker && <SeismicMarker {...seismicMarker} />}
      {layers.airports && <AirportLayer airports={middleEastAirports} />}
      {layers.oilFacilities && <OilFacilityLayer facilities={iranOilFacilities} currentTime={currentTime} />}
      {layers.meFacilities && <MEFacilityLayer />}
    </Map>
  );
}
