import { IconLayer, TextLayer } from '@deck.gl/layers';
import type { PickingInfo, Layer } from '@deck.gl/core';
import { svgToDataUri } from '../../utils/svgToDataUri';
import { FONT_MONO } from '../../styles/fonts';
import { middleEastAirports } from '../../data/airports';
import type { Airport } from '../../data/airports';

// ─── US base detection ───────────────────────────────────────────────────────

const US_BASE_ICAOS = new Set([
  'OMAD', 'OTBH', 'OKAJ', 'LTAG', 'OEPS', 'ORAA', 'ORBD', 'OBBS', 'OMTH', 'HDCL',
]);

function isUSBase(airport: Airport): boolean {
  return airport.type === 'military' && US_BASE_ICAOS.has(airport.icao);
}

// ─── Deduplication ───────────────────────────────────────────────────────────

const TYPE_PRIORITY: Record<Airport['type'], number> = {
  military: 3, large: 2, medium: 1, small: 0,
};

function deduplicateByArea(airports: Airport[]): Airport[] {
  const sorted = [...airports].sort((a, b) => {
    const pa = TYPE_PRIORITY[a.type] + (isUSBase(a) ? 1 : 0);
    const pb = TYPE_PRIORITY[b.type] + (isUSBase(b) ? 1 : 0);
    return pb - pa;
  });
  const kept: Airport[] = [];
  for (const ap of sorted) {
    const tooClose = kept.some(
      k => Math.abs(k.lat - ap.lat) < 0.8 && Math.abs(k.lng - ap.lng) < 0.8,
    );
    if (!tooClose) kept.push(ap);
  }
  return kept;
}

const DEDUPLICATED_AIRPORTS = deduplicateByArea(middleEastAirports);
export const IRAN_AIRPORT_COUNT = DEDUPLICATED_AIRPORTS.length;

// ─── Colors ──────────────────────────────────────────────────────────────────

function getAirportColor(airport: Airport): string {
  if (isUSBase(airport)) return '#60a5fa';
  if (airport.type === 'military') return '#f87171';
  return '#38bdf8';
}

// ─── SVG generators ──────────────────────────────────────────────────────────

function militaryPlaneSvg(color: string): string {
  return `<path d="M12 8.5 L12.8 11 L16.5 12.5 L16.5 13.5 L12.8 12.8 L12.5 15 L13.5 15.8 L13.5 16.5 L12 16 L10.5 16.5 L10.5 15.8 L11.5 15 L11.2 12.8 L7.5 13.5 L7.5 12.5 L11.2 11 L12 8.5Z" fill="${color}"/>`;
}

function civilPlaneSvg(color: string): string {
  return `<path d="M12 8c-.5 0-.8.3-.8.5v2.7l-4.2 2v1l4.2-1.1v2.5l-1.1.8v.8L12 16l1.9.5v-.8l-1.1-.8v-2.5l4.2 1.1v-1l-4.2-2V8.5c0-.2-.3-.5-.8-.5z" fill="${color}"/>`;
}

function airportSvg(airport: Airport): string {
  const color = getAirportColor(airport);
  const isMil = airport.type === 'military';
  const size = airport.type === 'large' ? 32 : airport.type === 'small' ? 24 : 28;
  const plane = isMil ? militaryPlaneSvg(color) : civilPlaneSvg(color);
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
    <circle cx="12" cy="12" r="10" fill="rgba(0,0,0,0.5)" stroke="${color}" stroke-width="2"/>
    ${plane}
  </svg>`;
}

// ─── Module-level icon cache ─────────────────────────────────────────────────

const airportIconCache = new Map<string, string>();

function getAirportIconUrl(airport: Airport): string {
  const isUS = isUSBase(airport);
  const key = `${airport.type}-${isUS ? 'us' : 'std'}`;
  if (!airportIconCache.has(key)) {
    airportIconCache.set(key, svgToDataUri(airportSvg(airport)));
  }
  return airportIconCache.get(key)!;
}

function getIconDimension(airport: Airport): number {
  return airport.type === 'large' ? 32 : airport.type === 'small' ? 24 : 28;
}

// ─── Label color ─────────────────────────────────────────────────────────────

function getAirportLabelColor(airport: Airport): [number, number, number, number] {
  if (isUSBase(airport)) return [59, 130, 246, 255];
  if (airport.type === 'military') return [239, 68, 68, 255];
  return [245, 158, 11, 255];
}

// ─── Public interface ────────────────────────────────────────────────────────

export interface AirportLayerConfig {
  visible: boolean;
  sc: number;
  onPick: (ap: Airport) => void;
}

export function createIranAirportLayers(config: AirportLayerConfig): Layer[] {
  if (!config.visible) return [];

  const { sc, onPick } = config;

  return [
    new IconLayer<Airport>({
      id: 'iran-airport-icon',
      data: DEDUPLICATED_AIRPORTS,
      getPosition: (d) => [d.lng, d.lat],
      getIcon: (d) => {
        const dim = getIconDimension(d);
        return {
          url: getAirportIconUrl(d),
          width: dim,
          height: dim,
          anchorX: dim / 2,
          anchorY: dim / 2,
        };
      },
      getSize: (d) => (d.type === 'large' ? 16 : d.type === 'small' ? 12 : 14) * sc,
      updateTriggers: { getSize: [sc] },
      pickable: true,
      onClick: (info: PickingInfo<Airport>) => {
        if (info.object) onPick(info.object);
        return true;
      },
    }),
    new TextLayer<Airport>({
      id: 'iran-airport-label',
      data: DEDUPLICATED_AIRPORTS,
      getPosition: (d) => [d.lng, d.lat],
      getText: (d) => d.nameKo ?? d.name,
      getSize: 9 * sc,
      updateTriggers: { getSize: [sc] },
      getColor: (d) => getAirportLabelColor(d),
      getTextAnchor: 'middle',
      getAlignmentBaseline: 'top',
      getPixelOffset: [0, 10],
      fontFamily: FONT_MONO,
      fontWeight: 700,
      outlineWidth: 2,
      outlineColor: [0, 0, 0, 200],
      billboard: false,
      characterSet: 'auto',
    }),
  ];
}
