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

interface Props {
  aircraft: Aircraft[];
  militaryOnly: boolean;
}

// ═══ tar1090 / Airplanes.live style SVG icons ═══
const SHAPES: Record<string, { viewBox: string; w: number; h: number; path: string }> = {
  airliner: {
    viewBox: '-1 -2 34 34', w: 24, h: 24,
    path: 'M16 1c-.17 0-.67.58-.9 1.03-.6 1.21-.6 1.15-.65 5.2-.04 2.97-.08 3.77-.18 3.9-.15.17-1.82 1.1-1.98 1.1-.08 0-.1-.25-.05-.83.03-.5.01-.92-.05-1.08-.1-.25-.13-.26-.71-.26-.82 0-.86.07-.78 1.5.03.6.08 1.17.11 1.25.05.12-.02.2-.25.33l-8 4.2c-.2.2-.18.1-.19 1.29 3.9-1.2 3.71-1.21 3.93-1.21.06 0 .1 0 .13.14.08.3.28.3.28-.04 0-.25.03-.27 1.16-.6.65-.2 1.22-.35 1.28-.35.05 0 .12.04.15.17.07.3.27.27.27-.08 0-.25.01-.27.7-.47.68-.1.98-.09 1.47-.1.18 0 .22 0 .26.18.06.34.22.35.27-.01.04-.2.1-.17 1.06-.14l1.07.02.05 4.2c.05 3.84.07 4.28.26 5.09.11.49.2.99.2 1.11 0 .19-.31.43-1.93 1.5l-1.93 1.26v1.02l4.13-.95.63 1.54c.05.07.12.09.19.09s.14-.02.19-.09l.63-1.54 4.13.95V29.3l-1.93-1.27c-1.62-1.06-1.93-1.3-1.93-1.49 0-.12.09-.62.2-1.11.19-.81.2-1.25.26-5.09l.05-4.2 1.07-.02c.96-.03 1.02-.05 1.06.14.05.36.21.35.27 0 .04-.17.08-.16.26-.16.49 0 .8-.02 1.48.1.68.2.69.21.69.46 0 .35.2.38.27.08.03-.13.1-.17.15-.17.06 0 .63.15 1.28.34 1.13.34 1.16.36 1.16.61 0 .35.2.34.28.04.03-.13.07-.14.13-.14.22 0 .03 0 3.93 1.2-.01-1.18.02-1.07-.19-1.27l-8-4.21c-.23-.12-.3-.21-.25-.33.03-.08.08-.65.11-1.25.08-1.43.04-1.5-.78-1.5-.58 0-.61.01-.71.26-.06.16-.08.58-.05 1.08.04.58.03.83-.05.83-.16 0-1.83-.93-1.98-1.1-.1-.13-.14-.93-.18-3.9-.05-4.05-.05-3.99-.65-5.2C16.67 1.58 16.17 1 16 1z',
  },
  hi_perf: {
    viewBox: '-7.8 0 80 80', w: 24, h: 24,
    path: 'M 30.82,61.32 29.19,54.84 29.06,60.19 27.70,60.70 22.27,60.63 21.68,59.60 l -0.01,-2.71 6.26,-5.52 -0.03,-3.99 -13.35,-0.01 -3e-6,1.15 -1.94,0.00 -0.01,-1.31 0.68,-0.65 L 13.30,37.20 c -0.01,-0.71 0.57,-0.77 0.60,0 l 0.05,1.57 0.28,0.23 0.26,4.09 L 19.90,38.48 c 0,0 -0.04,-1.26 0.20,-1.28 0.16,-0.02 0.20,0.98 0.20,0.98 l 4.40,-3.70 c 0,0 0.02,-1.28 0.20,-1.28 0.14,-0.00 0.20,0.98 0.20,0.98 l 1.80,-1.54 C 27.02,28.77 28.82,25.58 29,21.20 c 0.06,-1.41 0.23,-3.34 0.86,-3.85 0.21,-4.40 1.32,-11.03 2.39,-11.03 1.07,0 2.17,6.64 2.39,11.03 0.63,0.51 0.80,2.45 0.86,3.85 0.18,4.38 1.98,7.57 2.10,11.44 l 1.80,1.54 c 0,0 0.06,-0.99 0.20,-0.98 0.18,0.01 0.20,1.28 0.20,1.28 l 4.40,3.70 c 0,0 0.04,-1.00 0.20,-0.98 0.24,0.03 0.20,1.28 0.20,1.28 l 5.41,4.60 0.26,-4.09 0.28,-0.23 L 50.59,37.20 c 0.03,-0.77 0.61,-0.71 0.60,0 l 0.02,9.37 0.68,0.65 -0.01,1.31 -1.94,-0.00 -3e-6,-1.15 -13.35,0.01 -0.03,3.99 6.26,5.52 L 42.81,59.60 42.22,60.63 36.79,60.70 35.43,60.19 35.30,54.84 33.67,61.32 Z',
  },
  jet_nonSweep: {
    viewBox: '-2 -2.4 22 22', w: 18, h: 18,
    path: 'M9,17.09l-3.51.61v-.3c0-.65.11-1,.33-1.09L8.5,15a5.61,5.61,0,0,1-.28-1.32l-.53-.41-.1-.69H7.12l0-.21a7.19,7.19,0,0,1-.15-2.19L.24,9.05V8.84c0-1.1.51-1.15.61-1.15L7.8,7.18V2.88C7.8.64,8.89.3,8.93.28L9,.26l.07,0s1.13.36,1.13,2.6v4.3l7,.51c.09,0,.59.06.59,1.15v.21l-6.69,1.16a7.17,7.17,0,0,1-.15,2.19l0,.21h-.47l-.1.69-.53.41A5.61,5.61,0,0,1,9.5,15l2.74,1.28c.2.07.31.43.31,1.08v.3Z',
  },
  heavy_2e: {
    viewBox: '0 -3.2 64.2 64.2', w: 26, h: 26,
    path: 'm 31.414,2.728 c -0.314,0.712 -1.296,2.377 -1.534,6.133 l -0.086,13.379 c 0.006,0.400 -0.380,0.888 -0.945,1.252 l -2.631,1.729 c 0.157,-0.904 0.237,-3.403 -0.162,-3.850 l -2.686,0.006 c -0.336,1.065 -0.358,2.518 -0.109,4.088 h 0.434 L 24.057,26.689 8.611,36.852 7.418,38.432 7.381,39.027 8.875,38.166 l 8.295,-2.771 0.072,0.730 0.156,-0.004 0.150,-0.859 3.799,-1.234 0.074,0.727 0.119,0.004 0.117,-0.832 2.182,-0.730 h 1.670 l 0.061,0.822 h 0.176 l 0.062,-0.822 4.018,-0.002 v 13.602 c 0.051,1.559 0.465,3.272 0.826,4.963 l -6.836,5.426 c -0.097,0.802 -0.003,1.372 0.049,1.885 l 7.734,-2.795 0.477,1.973 h 0.232 l 0.477,-1.973 7.736,2.795 c 0.052,-0.513 0.146,-1.083 0.049,-1.885 l -6.836,-5.426 c 0.361,-1.691 0.775,-3.404 0.826,-4.963 V 33.193 l 4.016,0.002 0.062,0.822 h 0.178 L 38.875,33.195 h 1.672 l 2.182,0.730 0.117,0.832 0.119,-0.004 0.072,-0.727 3.799,1.234 0.152,0.859 0.154,0.004 0.072,-0.730 8.297,2.771 1.492,0.861 -0.037,-0.596 -1.191,-1.580 -15.447,-10.162 0.363,-1.225 H 41.125 c 0.248,-1.569 0.225,-3.023 -0.111,-4.088 l -2.686,-0.006 c -0.399,0.447 -0.317,2.945 -0.160,3.850 L 35.535,23.492 C 34.970,23.128 34.584,22.640 34.590,22.240 L 34.504,8.910 C 34.193,4.926 33.369,3.602 32.934,2.722 32.442,1.732 31.894,1.828 31.414,2.728 Z',
  },
  helicopter: {
    viewBox: '-13 -13 90 90', w: 22, h: 22,
    path: 'm 24.698,60.712 c 0,0 -0.450,2.134 -0.861,2.142 -0.561,0.011 -0.480,-3.836 -0.593,-5.761 -0.064,-1.098 1.381,-1.192 1.481,-0.042 l 5.464,0.007 -0.068,-9.482 -0.104,-1.108 c -2.410,-2.131 -3.028,-3.449 -3.152,-7.083 l -12.460,13.179 c -0.773,0.813 -2.977,0.599 -3.483,-0.428 L 26.920,35.416 26.866,29.159 11.471,14.513 c -0.813,-0.773 -0.599,-2.977 0.428,-3.483 l 14.971,14.428 0.150,-5.614 c -0.042,-1.324 1.075,-4.784 3.391,-5.633 0.686,-0.251 2.131,-0.293 3.033,0.008 2.349,0.783 3.433,4.309 3.391,5.633 l 0.073,4.400 12.573,-12.763 c 0.779,-0.807 2.977,-0.599 3.483,0.428 L 37.054,28.325 37.027,35.027 52.411,49.365 c 0.813,0.773 0.599,2.977 -0.428,3.483 L 36.992,38.359 c -0.124,3.634 -0.742,5.987 -3.152,8.118 l -0.104,1.108 -0.068,9.482 5.321,-0.068 c 0.101,-1.150 1.546,-1.057 1.481,0.042 -0.113,1.925 -0.032,5.772 -0.593,5.761 -0.412,-0.008 -0.861,-2.142 -0.861,-2.142 l -5.387,-0.011 0.085,9.377 -1.094,2.059 -1.386,-0.018 -1.093,-2.049 0.085,-9.377 z',
  },
  cessna: {
    viewBox: '0 -1 32 31', w: 20, h: 20,
    path: 'M16.36 20.96l2.57.27s.44.05.4.54l-.02.63s-.03.47-.45.54l-2.31.34-.44-.74-.22 1.63-.25-1.62-.38.73-2.35-.35s-.44-.1-.43-.6l-.02-.6s0-.5.48-.5l2.5-.27-.56-5.4-3.64-.1-5.83-1.02h-.45v-2.06s-.07-.37.46-.34l5.8-.17 3.55.12s-.1-2.52.52-2.82l-1.68-.04s-.1-.06 0-.14l1.94-.03s.35-1.18.7 0l1.91.04s.11.05 0 .14l-1.7.02s.62-.09.56 2.82l3.54-.1 5.81.17s.51-.04.48.35l-.01 2.06h-.47l-5.8 1-3.67.11z',
  },
  ground: {
    viewBox: '0 0 24 24', w: 12, h: 12,
    path: 'M12 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16zm0 2a6 6 0 1 1 0 12 6 6 0 0 1 0-12zm0 2a4 4 0 1 0 0 8 4 4 0 0 0 0-8z',
  },
};

function getShape(ac: Aircraft) {
  if (ac.onGround) return SHAPES.ground;
  switch (ac.category) {
    case 'fighter': case 'military': return SHAPES.hi_perf;
    case 'tanker': case 'surveillance': case 'cargo': return SHAPES.heavy_2e;
    case 'civilian': return SHAPES.airliner;
    default: return SHAPES.jet_nonSweep;
  }
}

const ALT_COLORS: [number, string][] = [
  [0, '#00c000'], [150, '#2AD62A'], [300, '#55EC55'], [600, '#7CFC00'],
  [1200, '#BFFF00'], [1800, '#FFFF00'], [3000, '#FFD700'], [6000, '#FF8C00'],
  [9000, '#FF4500'], [12000, '#FF1493'], [15000, '#BA55D3'],
];

const MIL_HEX: Partial<Record<AircraftCategory, string>> = {
  fighter: '#ff4444', military: '#ff6600', surveillance: '#ffcc00', tanker: '#00ccff',
};

function getAltitudeColor(altMeters: number): string {
  if (altMeters <= 0) return ALT_COLORS[0][1];
  for (let i = ALT_COLORS.length - 1; i >= 0; i--) {
    if (altMeters >= ALT_COLORS[i][0]) return ALT_COLORS[i][1];
  }
  return ALT_COLORS[0][1];
}

function getAircraftColor(ac: Aircraft): string {
  const milColor = MIL_HEX[ac.category];
  if (milColor) return milColor;
  if (ac.onGround) return '#555555';
  return getAltitudeColor(ac.altitude);
}

// ═══ Planespotters.net photo API ═══
interface PhotoResult { url: string; photographer: string; link: string; }
const photoCache = new Map<string, PhotoResult | null>();

function AircraftPhoto({ hex }: { hex: string }) {
  const { t } = useTranslation('ships');
  const [photo, setPhoto] = useState<PhotoResult | null | undefined>(
    photoCache.has(hex) ? photoCache.get(hex) : undefined,
  );

  useEffect(() => {
    if (photo !== undefined) return;
    let cancelled = false;
    (async () => {
      try {
        const res = await fetch(`https://api.planespotters.net/pub/photos/hex/${hex}`);
        if (!res.ok) throw new Error(`${res.status}`);
        const data = await res.json();
        if (cancelled) return;
        if (data.photos && data.photos.length > 0) {
          const p = data.photos[0];
          const result: PhotoResult = {
            url: p.thumbnail_large?.src || p.thumbnail?.src || '',
            photographer: p.photographer || '',
            link: p.link || '',
          };
          photoCache.set(hex, result);
          setPhoto(result);
        } else {
          photoCache.set(hex, null);
          setPhoto(null);
        }
      } catch {
        photoCache.set(hex, null);
        setPhoto(null);
      }
    })();
    return () => { cancelled = true; };
  }, [hex, photo]);

  if (photo === undefined) {
    return <div className="text-center p-2 text-kcg-muted text-[10px]">{t('aircraftPopup.loadingPhoto')}</div>;
  }
  if (!photo) return null;
  return (
    <div className="mb-1.5">
      <a href={photo.link} target="_blank" rel="noopener noreferrer">
        <img src={photo.url} alt="Aircraft"
          className="w-full rounded block"
          onError={(e) => { (e.target as HTMLImageElement).style.display = 'none'; }}
        />
      </a>
      {photo.photographer && (
        <div className="text-[9px] text-[#999] mt-0.5 text-right">
          &copy; {photo.photographer}
        </div>
      )}
    </div>
  );
}

// ═══ Main layer ═══
export function AircraftLayer({ aircraft, militaryOnly }: Props) {
  const filtered = useMemo(() => {
    if (militaryOnly) {
      return aircraft.filter(a => a.category !== 'civilian' && a.category !== 'unknown');
    }
    return aircraft;
  }, [aircraft, militaryOnly]);

  // Aircraft trails as GeoJSON
  const trailData = useMemo(() => ({
    type: 'FeatureCollection' as const,
    features: filtered
      .filter(ac => ac.trail && ac.trail.length > 1)
      .map(ac => ({
        type: 'Feature' as const,
        properties: { color: getAircraftColor(ac) },
        geometry: {
          type: 'LineString' as const,
          coordinates: ac.trail!.map(([lat, lng]) => [lng, lat]),
        },
      })),
  }), [filtered]);

  return (
    <>
      {trailData.features.length > 0 && (
        <Source id="aircraft-trails" type="geojson" data={trailData}>
          <Layer
            id="aircraft-trail-lines"
            type="line"
            paint={{
              'line-color': ['get', 'color'],
              'line-width': 1.5,
              'line-opacity': 0.4,
              'line-dasharray': [4, 4],
            }}
          />
        </Source>
      )}
      {filtered.map(ac => (
        <AircraftMarker key={ac.icao24} ac={ac} />
      ))}
    </>
  );
}

// ═══ Aircraft Marker ═══
const AircraftMarker = memo(function AircraftMarker({ ac }: { ac: Aircraft }) {
  const { t } = useTranslation('ships');
  const [showPopup, setShowPopup] = useState(false);
  const color = getAircraftColor(ac);
  const shape = getShape(ac);
  const size = shape.w;
  const showLabel = ac.category === 'fighter' || ac.category === 'surveillance';
  const strokeWidth = ac.category === 'fighter' || ac.category === 'military' ? 1.5 : 0.8;

  return (
    <>
      <Marker longitude={ac.lng} latitude={ac.lat} anchor="center">
        <div className="relative">
          <div
            className="cursor-pointer"
            style={{
              width: size, height: size,
              transform: `rotate(${ac.heading}deg)`,
              filter: 'drop-shadow(0 0 2px rgba(0,0,0,0.7))',
            }}
            onClick={(e) => { e.stopPropagation(); setShowPopup(true); }}
          >
            <svg viewBox={shape.viewBox} width={size} height={size}
              fill={color} stroke="#000" strokeWidth={strokeWidth}
              strokeLinejoin="round" opacity={0.95}>
              <path d={shape.path} />
            </svg>
          </div>
          {showLabel && (
            <div className="gl-marker-label" style={{ color }}>
              {ac.callsign || ac.icao24}
            </div>
          )}
        </div>
      </Marker>
      {showPopup && (
        <Popup longitude={ac.lng} latitude={ac.lat}
          onClose={() => setShowPopup(false)} closeOnClick={false}
          anchor="bottom" maxWidth="300px" className="gl-popup">
          <div className="min-w-[240px] max-w-[300px] font-mono text-xs">
            <div className="flex items-center gap-2 mb-1.5">
              <strong className="text-sm">{ac.callsign || 'N/A'}</strong>
              <span
                className="px-1.5 py-px rounded text-[10px] font-bold ml-auto text-black"
                style={{ background: color }}
              >
                {t(`aircraftLabel.${ac.category}`)}
              </span>
            </div>
            <AircraftPhoto hex={ac.icao24} />
            <table className="w-full text-[11px] border-collapse">
              <tbody>
                <tr><td className="text-kcg-muted pr-2">{t('aircraftPopup.hex')}</td><td><strong>{ac.icao24.toUpperCase()}</strong></td></tr>
                {ac.registration && <tr><td className="text-kcg-muted">{t('aircraftPopup.reg')}</td><td><strong>{ac.registration}</strong></td></tr>}
                {ac.operator && <tr><td className="text-kcg-muted">{t('aircraftPopup.operator')}</td><td>{ac.operator}</td></tr>}
                {ac.typecode && (
                  <tr><td className="text-kcg-muted">{t('aircraftPopup.type')}</td>
                    <td><strong>{ac.typecode}</strong>{ac.typeDesc ? ` — ${ac.typeDesc}` : ''}</td></tr>
                )}
                {ac.squawk && <tr><td className="text-kcg-muted">{t('aircraftPopup.squawk')}</td><td>{ac.squawk}</td></tr>}
                <tr><td className="text-kcg-muted">{t('aircraftPopup.alt')}</td>
                  <td>{ac.onGround ? t('aircraftPopup.ground') : `${Math.round(ac.altitude * 3.281).toLocaleString()} ft`}</td></tr>
                <tr><td className="text-kcg-muted">{t('aircraftPopup.speed')}</td><td>{Math.round(ac.velocity * 1.944)} kts</td></tr>
                <tr><td className="text-kcg-muted">{t('aircraftPopup.hdg')}</td><td>{Math.round(ac.heading)}&deg;</td></tr>
                <tr><td className="text-kcg-muted">{t('aircraftPopup.verticalSpeed')}</td><td>{Math.round(ac.verticalRate * 196.85)} fpm</td></tr>
              </tbody>
            </table>
            <div className="mt-1.5 text-[10px] text-right">
              <a href={`https://globe.airplanes.live/?icao=${ac.icao24}`}
                target="_blank" rel="noopener noreferrer" className="text-kcg-accent">
                Airplanes.live &rarr;
              </a>
            </div>
          </div>
        </Popup>
      )}
    </>
  );
}, (prev, next) => {
  const a = prev.ac, b = next.ac;
  return a.icao24 === b.icao24 &&
    Math.abs(a.lat - b.lat) < 0.001 &&
    Math.abs(a.lng - b.lng) < 0.001 &&
    Math.round(a.heading / 10) === Math.round(b.heading / 10) &&
    a.category === b.category &&
    Math.round(a.altitude / 500) === Math.round(b.altitude / 500);
});
