import { IconLayer, TextLayer } from '@deck.gl/layers';
import type { PickingInfo, Layer } from '@deck.gl/core';
import { svgToDataUri } from '../../utils/svgToDataUri';
import { EAST_ASIA_PORTS } from '../../data/ports';
import type { Port } from '../../data/ports';
import { KOREA_WIND_FARMS } from '../../data/windFarms';
import type { WindFarm } from '../../data/windFarms';
import { hexToRgb } from './types';
import type { LayerFactoryConfig } from './types';
import { FONT_MONO } from '../../styles/fonts';

// ─── Port colors ──────────────────────────────────────────────────────────────

const PORT_COUNTRY_COLOR: Record<string, string> = {
  KR: '#3b82f6',
  CN: '#ef4444',
  JP: '#f472b6',
  KP: '#f97316',
  TW: '#10b981',
};

// ─── Port SVG ────────────────────────────────────────────────────────────────

function portSvg(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="5" r="2.5" stroke="${color}" stroke-width="1.5" fill="none"/>
    <line x1="12" y1="7.5" x2="12" y2="21" stroke="${color}" stroke-width="1.5"/>
    <line x1="7" y1="12" x2="17" y2="12" stroke="${color}" stroke-width="1.5"/>
    <path d="M5 18 Q8 21 12 21 Q16 21 19 18" stroke="${color}" stroke-width="1.5" fill="none"/>
  </svg>`;
}

// ─── Wind Turbine SVG ─────────────────────────────────────────────────────────

const WIND_COLOR = '#00bcd4';

function windTurbineSvg(size: number): string {
  return `<svg width="${size}" height="${size}" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
    <line x1="12" y1="10" x2="11" y2="23" stroke="${WIND_COLOR}" stroke-width="1.5"/>
    <line x1="12" y1="10" x2="13" y2="23" stroke="${WIND_COLOR}" stroke-width="1.5"/>
    <circle cx="12" cy="9" r="1.8" fill="${WIND_COLOR}"/>
    <path d="M12 9 L11.5 1 Q12 0 12.5 1 Z" fill="${WIND_COLOR}" opacity="0.9"/>
    <path d="M12 9 L18 14 Q18.5 13 17.5 12.5 Z" fill="${WIND_COLOR}" opacity="0.9"/>
    <path d="M12 9 L6 14 Q5.5 13 6.5 12.5 Z" fill="${WIND_COLOR}" opacity="0.9"/>
    <line x1="8" y1="23" x2="16" y2="23" stroke="${WIND_COLOR}" stroke-width="1.5"/>
  </svg>`;
}

// ─── Module-level icon caches ─────────────────────────────────────────────────

const portIconCache = new Map<string, string>();
const WIND_ICON_URL = svgToDataUri(windTurbineSvg(36));

export function createPortLayers(
  config: { ports: boolean; windFarm: boolean },
  fc: LayerFactoryConfig,
): Layer[] {
  const layers: Layer[] = [];
  const sc = fc.sc;
  const onPick = fc.onPick;

  // ── Ports ───────────────────────────────────────────────────────────────
  if (config.ports) {
    function getPortIconUrl(p: Port): string {
      const key = `${p.country}-${p.type}`;
      if (!portIconCache.has(key)) {
        const color = PORT_COUNTRY_COLOR[p.country] ?? PORT_COUNTRY_COLOR.KR;
        const size = p.type === 'major' ? 32 : 24;
        portIconCache.set(key, svgToDataUri(portSvg(color, size)));
      }
      return portIconCache.get(key)!;
    }

    layers.push(
      new IconLayer<Port>({
        id: 'static-ports-icon',
        data: EAST_ASIA_PORTS,
        getPosition: (d) => [d.lng, d.lat],
        getIcon: (d) => ({
          url: getPortIconUrl(d),
          width: d.type === 'major' ? 32 : 24,
          height: d.type === 'major' ? 32 : 24,
          anchorX: d.type === 'major' ? 16 : 12,
          anchorY: d.type === 'major' ? 16 : 12,
        }),
        getSize: (d) => (d.type === 'major' ? 16 : 12) * sc,
        updateTriggers: { getSize: [sc] },
        pickable: true,
        onClick: (info: PickingInfo<Port>) => {
          if (info.object) onPick({ kind: 'port', object: info.object });
          return true;
        },
      }),
      new TextLayer<Port>({
        id: 'static-ports-label',
        data: EAST_ASIA_PORTS,
        getPosition: (d) => [d.lng, d.lat],
        getText: (d) => d.nameKo.replace('항', ''),
        getSize: 12 * sc * fc.fs,
        updateTriggers: { getSize: [sc, fc.fs] },
        getColor: (d) => [...hexToRgb(PORT_COUNTRY_COLOR[d.country] ?? PORT_COUNTRY_COLOR.KR), 255] as [number, number, number, number],
        getTextAnchor: 'middle',
        getAlignmentBaseline: 'top',
        getPixelOffset: [0, 8],
        fontFamily: FONT_MONO,
        fontWeight: 700,
        fontSettings: { sdf: true },
        outlineWidth: 3,
        outlineColor: [0, 0, 0, 255],
        billboard: false,
        characterSet: 'auto',
      }),
    );
  }

  // ── Wind Farms ─────────────────────────────────────────────────────────
  if (config.windFarm) {
    layers.push(
      new IconLayer<WindFarm>({
        id: 'static-windfarm-icon',
        data: KOREA_WIND_FARMS,
        getPosition: (d) => [d.lng, d.lat],
        getIcon: () => ({ url: WIND_ICON_URL, width: 36, height: 36, anchorX: 18, anchorY: 18 }),
        getSize: 18 * sc,
        updateTriggers: { getSize: [sc] },
        pickable: true,
        onClick: (info: PickingInfo<WindFarm>) => {
          if (info.object) onPick({ kind: 'windFarm', object: info.object });
          return true;
        },
      }),
      new TextLayer<WindFarm>({
        id: 'static-windfarm-label',
        data: KOREA_WIND_FARMS,
        getPosition: (d) => [d.lng, d.lat],
        getText: (d) => (d.name.length > 10 ? d.name.slice(0, 10) + '..' : d.name),
        getSize: 12 * sc * fc.fs,
        updateTriggers: { getSize: [sc, fc.fs] },
        getColor: [...hexToRgb(WIND_COLOR), 255] as [number, number, number, number],
        getTextAnchor: 'middle',
        getAlignmentBaseline: 'top',
        getPixelOffset: [0, 10],
        fontFamily: FONT_MONO,
        fontWeight: 700,
        fontSettings: { sdf: true },
        outlineWidth: 3,
        outlineColor: [0, 0, 0, 255],
        billboard: false,
        characterSet: 'auto',
      }),
    );
  }

  return layers;
}
