import { IconLayer, TextLayer } from '@deck.gl/layers';
import type { Layer, PickingInfo } from '@deck.gl/core';
import { svgToDataUri } from '../../utils/svgToDataUri';
import { ME_FACILITIES, ME_FACILITY_TYPE_META } from '../../data/middleEastFacilities';
import type { MEFacility } from '../../data/middleEastFacilities';
import { FONT_MONO } from '../../styles/fonts';

export { type MEFacility };

export const ME_FACILITY_COUNT = ME_FACILITIES.length;

function hexToRgba(hex: string, alpha = 255): [number, number, number, number] {
  const r = parseInt(hex.slice(1, 3), 16);
  const g = parseInt(hex.slice(3, 5), 16);
  const b = parseInt(hex.slice(5, 7), 16);
  return [r, g, b, alpha];
}

function navalSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <line x1="12" y1="5" x2="12" y2="19" stroke="${color}" stroke-width="1.5"/>
    <line x1="7" y1="9" x2="17" y2="9" stroke="${color}" stroke-width="1.5"/>
    <path d="M7 9 Q6 13 8 15" fill="none" stroke="${color}" stroke-width="1"/>
    <path d="M17 9 Q18 13 16 15" fill="none" stroke="${color}" stroke-width="1"/>
    <path d="M8 15 Q12 18 16 15" fill="none" stroke="${color}" stroke-width="1.2"/>
    <circle cx="12" cy="5" r="1.5" fill="${color}"/>
  </svg>`;
}

function militaryHqSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <polygon points="12,5 13.8,10.1 19.2,10.1 14.7,13.2 16.5,18.3 12,15.2 7.5,18.3 9.3,13.2 4.8,10.1 10.2,10.1" fill="${color}" opacity="0.85"/>
  </svg>`;
}

function missileSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <path d="M12 5 L14 10 L14 17 L12 19 L10 17 L10 10 Z" fill="${color}" opacity="0.85"/>
    <path d="M10 13 L7 16 L10 15 Z" fill="${color}" opacity="0.7"/>
    <path d="M14 13 L17 16 L14 15 Z" fill="${color}" opacity="0.7"/>
    <path d="M11 10 L13 10 L13 8 Q12 6 11 8 Z" fill="#fff" opacity="0.5"/>
  </svg>`;
}

function intelligenceSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <ellipse cx="11" cy="11" rx="5" ry="5" fill="none" stroke="${color}" stroke-width="1.5"/>
    <circle cx="11" cy="11" r="2" fill="${color}" opacity="0.7"/>
    <line x1="15" y1="15" x2="18" y2="18" stroke="${color}" stroke-width="2" stroke-linecap="round"/>
  </svg>`;
}

function governmentSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <line x1="5" y1="18" x2="19" y2="18" stroke="${color}" stroke-width="1.2"/>
    <line x1="12" y1="5" x2="5" y2="9" stroke="${color}" stroke-width="1"/>
    <line x1="12" y1="5" x2="19" y2="9" stroke="${color}" stroke-width="1"/>
    <line x1="5" y1="9" x2="19" y2="9" stroke="${color}" stroke-width="1"/>
    <rect x="7" y="10" width="2" height="8" fill="${color}" opacity="0.7"/>
    <rect x="11" y="10" width="2" height="8" fill="${color}" opacity="0.7"/>
    <rect x="15" y="10" width="2" height="8" fill="${color}" opacity="0.7"/>
  </svg>`;
}

function radarSvg(color: string, size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" 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="1.2"/>
    <ellipse cx="12" cy="9" rx="5" ry="3" fill="none" stroke="${color}" stroke-width="1.2"/>
    <line x1="12" y1="12" x2="12" y2="19" stroke="${color}" stroke-width="1.5"/>
    <path d="M7 7 Q9 4 12 4 Q15 4 17 7" fill="none" stroke="${color}" stroke-width="0.8" opacity="0.6"/>
    <path d="M5 9 Q7 5 12 5 Q17 5 19 9" fill="none" stroke="${color}" stroke-width="0.6" opacity="0.4"/>
    <circle cx="12" cy="9" r="1.2" fill="${color}"/>
  </svg>`;
}

type MEFacilityType = MEFacility['type'];

type SvgFn = (color: string, size: number) => string;

const TYPE_SVG_FN: Record<MEFacilityType, SvgFn> = {
  naval:        navalSvg,
  military_hq:  militaryHqSvg,
  missile:      missileSvg,
  intelligence: intelligenceSvg,
  government:   governmentSvg,
  radar:        radarSvg,
};

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

function getIconUrl(type: MEFacilityType): string {
  if (!iconCache.has(type)) {
    const color = ME_FACILITY_TYPE_META[type].color;
    iconCache.set(type, svgToDataUri(TYPE_SVG_FN[type](color, 64)));
  }
  return iconCache.get(type)!;
}

export interface MEFacilityLayerConfig {
  visible: boolean;
  sc: number;
  fs?: number;
  onPick: (facility: MEFacility) => void;
}

export function createMEFacilityLayers(config: MEFacilityLayerConfig): Layer[] {
  const { visible, sc, onPick } = config;
  const fs = config.fs ?? 1;
  if (!visible) return [];

  const iconLayer = new IconLayer<MEFacility>({
    id: 'me-facility-icon',
    data: ME_FACILITIES,
    getPosition: (d) => [d.lng, d.lat],
    getIcon: (d) => ({ url: getIconUrl(d.type), width: 64, height: 64, anchorX: 32, anchorY: 32 }),
    getSize: 18 * sc,
    updateTriggers: { getSize: [sc] },
    pickable: true,
    onClick: (info: PickingInfo<MEFacility>) => {
      if (info.object) onPick(info.object);
      return true;
    },
  });

  const labelLayer = new TextLayer<MEFacility>({
    id: 'me-facility-label',
    data: ME_FACILITIES,
    getPosition: (d) => [d.lng, d.lat],
    getText: (d) => d.nameKo.length > 12 ? d.nameKo.slice(0, 12) + '..' : d.nameKo,
    getSize: 12 * sc * fs,
    updateTriggers: { getSize: [sc] },
    getColor: (d) => hexToRgba(ME_FACILITY_TYPE_META[d.type].color),
    getTextAnchor: 'middle',
    getAlignmentBaseline: 'top',
    getPixelOffset: [0, 12],
    fontFamily: FONT_MONO,
    fontWeight: 700,
    fontSettings: { sdf: true },
        outlineWidth: 3,
    outlineColor: [0, 0, 0, 255],
    billboard: false,
    characterSet: 'auto',
  });

  return [iconLayer, labelLayer];
}
