/** Map CoT / ADS-B entity display: icons and popups. */

export const COT_COLORS = {
  air: '#60a5fa',
  helicopter: '#fbbf24',
  surface: '#38bdf8',
  ground: '#f59e0b',
}

export function cotCategory(type) {
  const t = typeof type === 'string' ? type : ''
  if (t.startsWith('a-f-A-')) return 'air'
  if (t.startsWith('a-f-S-')) return 'surface'
  return 'ground'
}

/** Whether the entity is a helicopter or fixed-wing aircraft. @returns {'helicopter' | 'fixedWing'} */
export function cotAirIconKind(entity) {
  const type = entity?.type ?? ''
  if (type.endsWith('-C-H') || type.endsWith('-M-H')) return 'helicopter'
  return 'fixedWing'
}

function iconWrap(heading, inner) {
  const rotate = Number.isFinite(heading) ? ` style="transform:rotate(${heading}deg)"` : ''
  return `<span class="poi-icon-svg cot-icon-rotatable"${rotate}>${inner}</span>`
}

const PLANE_SVG = color =>
  `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="${color}"><path d="M21 16v-2l-8-5V3.5a1.5 1.5 0 0 0-3 0V9l-8 5v2l8-2.5V19l-2 1.5V22l3.5-1 3.5 1v-1.5L13 19v-5.5l8 2.5z"/></svg>`

const HELI_SVG = color =>
  `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="1.75" stroke-linecap="round"><circle cx="12" cy="12" r="2.5" fill="${color}"/><path d="M3 8h18M3 12h18"/><path d="M12 8v8"/><path d="M9 16h6"/></svg>`

const SHIP_SVG = color =>
  `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="2"><path d="M2 20c2-4 6-6 10-6s8 2 10 6"/><path d="M12 14V4"/><path d="m8 8 4-4 4 4"/></svg>`

const GROUND_SVG = color =>
  `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="${color}" stroke-width="2"><circle cx="12" cy="12" r="9"/><circle cx="12" cy="8" r="2.5" fill="${color}"/></svg>`

export function getCotIconHtml(entity) {
  const category = cotCategory(entity?.type)
  const heading = Number(entity?.heading)
  if (category === 'air') {
    const kind = cotAirIconKind(entity)
    const color = kind === 'helicopter' ? COT_COLORS.helicopter : COT_COLORS.air
    const svg = kind === 'helicopter' ? HELI_SVG(color) : PLANE_SVG(color)
    return { html: iconWrap(heading, svg), className: `cot-entity-${kind}` }
  }
  if (category === 'surface') {
    return { html: iconWrap(heading, SHIP_SVG(COT_COLORS.surface)), className: 'cot-entity-surface' }
  }
  return { html: iconWrap(undefined, GROUND_SVG(COT_COLORS.ground)), className: 'cot-entity-ground' }
}

function msToKnots(ms) {
  return Number.isFinite(ms) ? Math.round(ms * 1.94384) : null
}

function metersToFeet(m) {
  return Number.isFinite(m) ? Math.round(m * 3.28084) : null
}

function fmtHeading(deg) {
  return Number.isFinite(deg) ? `${Math.round(deg)}°` : null
}

function fmtVerticalFpm(ms) {
  if (!Number.isFinite(ms) || ms === 0) return null
  const fpm = Math.round(ms * 196.85)
  return `${fpm > 0 ? '+' : ''}${fpm} fpm`
}

function icaoFromEntity(entity) {
  if (entity?.icao) return String(entity.icao).toUpperCase()
  if (typeof entity?.id === 'string' && entity.id.startsWith('ICAO.')) {
    return entity.id.slice(5).toUpperCase()
  }
  return null
}

function mmsiFromEntity(entity) {
  if (entity?.mmsi) return String(entity.mmsi)
  if (typeof entity?.id === 'string' && entity.id.startsWith('MMSI.')) return entity.id.slice(5)
  return null
}

function popupLine(escape, parts) {
  const line = parts.filter(Boolean).join(' · ')
  return line ? `<div class="text-kestrel-muted text-xs mt-1">${line}</div>` : ''
}

/**
 * @param {Record<string, unknown>} entity
 * @param {(s: string) => string} escape
 */
export function formatCotPopup(entity, escape) {
  const category = cotCategory(entity?.type)
  const label = escape(entity?.label || entity?.id || 'Unknown')

  if (entity?.source === 'adsb' || category === 'air') {
    const tag = cotAirIconKind(entity) === 'helicopter' ? 'Helicopter' : 'Aircraft'
    const icao = icaoFromEntity(entity)
    const meta = [
      icao ? `ICAO ${icao}` : null,
      entity?.originCountry ? escape(String(entity.originCountry)) : null,
    ].filter(Boolean).join(' · ')
    const alt = metersToFeet(entity?.altitude)
    const stats = [
      alt != null ? `${alt.toLocaleString()} ft` : null,
      entity?.onGround ? 'On ground' : null,
      msToKnots(entity?.speed) != null ? `${msToKnots(entity.speed)} kt` : null,
      fmtHeading(entity?.heading),
      fmtVerticalFpm(entity?.verticalRate),
      entity?.squawk ? `Squawk ${escape(String(entity.squawk))}` : null,
    ]
    return `<div class="kestrel-live-popup"><strong>${label}</strong> <span class="text-kestrel-muted">${tag}</span>${meta ? `<div class="text-kestrel-muted text-xs mt-0.5">${meta}</div>` : ''}${popupLine(escape, stats)}</div>`
  }

  if (entity?.source === 'ais' || category === 'surface') {
    const mmsi = mmsiFromEntity(entity)
    const meta = mmsi ? `MMSI ${escape(mmsi)}` : ''
    const stats = [
      Number.isFinite(entity?.speed) ? `${Number(entity.speed).toFixed(1)} kt` : null,
      fmtHeading(entity?.heading),
    ]
    return `<div class="kestrel-live-popup"><strong>${label}</strong> <span class="text-kestrel-muted">Vessel</span>${meta ? `<div class="text-kestrel-muted text-xs mt-0.5">${meta}</div>` : ''}${popupLine(escape, stats)}</div>`
  }

  return `<div class="kestrel-live-popup"><strong>${label}</strong> <span class="text-kestrel-muted">Team</span></div>`
}
