import { memo, useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { Marker, Popup, Source, Layer } from 'react-map-gl/maplibre';
import type { SatellitePosition } from '../types';

interface Props {
  satellites: SatellitePosition[];
}

const CAT_COLORS: Record<SatellitePosition['category'], string> = {
  reconnaissance: '#ef4444',
  communications: '#3b82f6',
  navigation: '#22c55e',
  weather: '#a855f7',
  other: '#6b7280',
};

const CAT_LABELS: Record<SatellitePosition['category'], string> = {
  reconnaissance: 'RECON', communications: 'COMMS',
  navigation: 'NAV', weather: 'WX', other: 'SAT',
};

const SVG_RECON = (
  <>
    <rect x={8} y={6} width={8} height={12} rx={1.5} fill="currentColor" opacity={0.9} />
    <rect x={1} y={8} width={6} height={3} rx={0.5} fill="currentColor" opacity={0.7} />
    <rect x={17} y={8} width={6} height={3} rx={0.5} fill="currentColor" opacity={0.7} />
    <circle cx={12} cy={16} r={1.8} fill="none" stroke="currentColor" strokeWidth={1} opacity={0.6} />
    <circle cx={12} cy={16} r={0.6} fill="currentColor" opacity={0.6} />
  </>
);

const SVG_COMMS = (
  <>
    <rect x={9} y={7} width={6} height={10} rx={1} fill="currentColor" opacity={0.9} />
    <rect x={1} y={9} width={7} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <rect x={16} y={9} width={7} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <path d="M10 4 Q12 2 14 4" fill="none" stroke="currentColor" strokeWidth={1.2} opacity={0.8} />
    <line x1={12} y1={4} x2={12} y2={7} stroke="currentColor" strokeWidth={0.8} />
  </>
);

const SVG_NAV = (
  <>
    <rect x={9} y={6} width={6} height={12} rx={1} fill="currentColor" opacity={0.9} />
    <rect x={2} y={8} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <rect x={16} y={8} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <line x1={12} y1={3} x2={12} y2={6} stroke="currentColor" strokeWidth={1} />
    <circle cx={12} cy={2.5} r={1} fill="currentColor" opacity={0.7} />
  </>
);

const SVG_WEATHER = (
  <>
    <rect x={8} y={7} width={8} height={10} rx={1.5} fill="currentColor" opacity={0.9} />
    <rect x={1} y={9} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <rect x={17} y={9} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <circle cx={12} cy={12} r={2.5} fill="none" stroke="currentColor" strokeWidth={0.8} opacity={0.5} />
  </>
);

const SVG_OTHER = (
  <>
    <rect x={9} y={7} width={6} height={10} rx={1} fill="currentColor" opacity={0.9} />
    <rect x={2} y={9} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
    <rect x={16} y={9} width={6} height={2.5} rx={0.5} fill="currentColor" opacity={0.7} />
  </>
);

const SVG_MAP: Record<SatellitePosition['category'], React.ReactNode> = {
  reconnaissance: SVG_RECON, communications: SVG_COMMS,
  navigation: SVG_NAV, weather: SVG_WEATHER, other: SVG_OTHER,
};

export function SatelliteLayer({ satellites }: Props) {
  const trackData = useMemo(() => {
    const features: GeoJSON.Feature[] = [];
    for (const sat of satellites) {
      if (!sat.groundTrack || sat.groundTrack.length < 2) continue;
      const color = CAT_COLORS[sat.category];
      let segment: [number, number][] = [];
      for (let i = 0; i < sat.groundTrack.length; i++) {
        const [lat, lng] = sat.groundTrack[i];
        if (i > 0) {
          const [, prevLng] = sat.groundTrack[i - 1];
          if (Math.abs(lng - prevLng) > 180) {
            if (segment.length > 1) {
              features.push({
                type: 'Feature',
                properties: { color },
                geometry: { type: 'LineString', coordinates: segment.map(([la, lo]) => [lo, la]) },
              });
            }
            segment = [];
          }
        }
        segment.push([lat, lng]);
      }
      if (segment.length > 1) {
        features.push({
          type: 'Feature',
          properties: { color },
          geometry: { type: 'LineString', coordinates: segment.map(([la, lo]) => [lo, la]) },
        });
      }
    }
    return { type: 'FeatureCollection' as const, features };
  }, [satellites]);

  return (
    <>
      {trackData.features.length > 0 && (
        <Source id="satellite-tracks" type="geojson" data={trackData}>
          <Layer
            id="satellite-track-lines"
            type="line"
            paint={{
              'line-color': ['get', 'color'],
              'line-width': 1,
              'line-opacity': 0.25,
              'line-dasharray': [6, 4],
            }}
          />
        </Source>
      )}
      {satellites.map(sat => (
        <SatelliteMarker key={sat.noradId} sat={sat} />
      ))}
    </>
  );
}

const SatelliteMarker = memo(function SatelliteMarker({ sat }: { sat: SatellitePosition }) {
  const [showPopup, setShowPopup] = useState(false);
  const { t } = useTranslation();
  const color = CAT_COLORS[sat.category];
  const svgBody = SVG_MAP[sat.category];
  const size = 22;

  return (
    <>
      <Marker longitude={sat.lng} latitude={sat.lat} anchor="center">
        <div className="relative">
          <div
            style={{ color }} className="size-[22px] cursor-pointer"
            onClick={(e) => { e.stopPropagation(); setShowPopup(true); }}
          >
            <svg viewBox="0 0 24 24" width={size} height={size} style={{ color }}>
              {svgBody}
            </svg>
          </div>
          <div className="gl-marker-label" style={{ color, fontSize: 10 }}>
            {sat.name}
          </div>
        </div>
      </Marker>
      {showPopup && (
        <Popup longitude={sat.lng} latitude={sat.lat}
          onClose={() => setShowPopup(false)} closeOnClick={false}
          anchor="bottom" maxWidth="200px" className="gl-popup">
          <div className="min-w-[180px] font-mono text-xs">
            <div className="mb-1.5 flex items-center gap-2">
              <span style={{
                background: color,
              }} className="rounded-sm px-1.5 py-px text-[10px] font-bold text-black">
                {CAT_LABELS[sat.category]}
              </span>
              <strong>{sat.name}</strong>
            </div>
            <table className="w-full text-[11px]">
              <tbody>
                <tr><td className="text-kcg-muted">{t('satellite.norad')}</td><td>{sat.noradId}</td></tr>
                <tr><td className="text-kcg-muted">{t('satellite.lat')}</td><td>{sat.lat.toFixed(2)}&deg;</td></tr>
                <tr><td className="text-kcg-muted">{t('satellite.lng')}</td><td>{sat.lng.toFixed(2)}&deg;</td></tr>
                <tr><td className="text-kcg-muted">{t('satellite.alt')}</td><td>{Math.round(sat.altitude)} km</td></tr>
              </tbody>
            </table>
          </div>
        </Popup>
      )}
    </>
  );
});
