/** 측점값(체이니지) 공유 유틸 — 드론 GPS 를 측점 폴리라인에 투영해 측점값/최근접측점 산출.
 *  StationBar(배지)·VideoPlayer(측점 진단 HUD) 가 동일 계산을 공유한다. */

export interface ChainLine {
  pts: { x: number; y: number; km: number; lat: number; lon: number; title: string }[];
  k: number; // 경도→m 환산 (cos(lat0)*111000)
}

/** "157K970" → 157970(m). 실패 시 -1. */
export function kmFromTitle(title: string): number {
  const m = title.match(/(\d+)[Kk](\d+)/);
  return m ? parseInt(m[1], 10) * 1000 + parseInt(m[2], 10) : -1;
}

/** 미터값 → "157+970" (10m 단위). */
export function fmtKm10(m: number): string {
  const r = Math.round(m / 10) * 10;
  return `${Math.floor(r / 1000)}+${String(r % 1000).padStart(3, '0')}`;
}

/** 측점 POI 목록 → 평면투영 폴리라인(km 오름차순). 측점이 없으면 null. */
export function buildChainLine(stations: { title: string; lat: number; lon: number }[]): ChainLine | null {
  const sts = stations.filter((s) => kmFromTitle(s.title) >= 0);
  if (!sts.length) return null;
  const sorted = [...sts].sort((a, b) => kmFromTitle(a.title) - kmFromTitle(b.title));
  const lat0 = sorted.reduce((s, p) => s + p.lat, 0) / sorted.length;
  const k = Math.cos((lat0 * Math.PI) / 180) * 111000;
  return {
    pts: sorted.map((p) => ({ x: p.lon * k, y: p.lat * 111000, km: kmFromTitle(p.title), lat: p.lat, lon: p.lon, title: p.title })),
    k,
  };
}

/** 드론 lat/lon 을 폴리라인에 투영 → { km(측점값), offsetM(선로 수직이격) }. */
export function projectToChain(lat: number, lon: number, line: ChainLine): { km: number; offsetM: number } {
  const px = lon * line.k;
  const py = lat * 111000;
  const pts = line.pts;
  let bestD = Infinity;
  let bestKm = pts.length ? pts[0].km : -1;
  for (let i = 0; i < pts.length - 1; i++) {
    const a = pts[i], b = pts[i + 1];
    const dx = b.x - a.x, dy = b.y - a.y, L2 = dx * dx + dy * dy;
    const t = L2 === 0 ? 0 : Math.max(0, Math.min(1, ((px - a.x) * dx + (py - a.y) * dy) / L2));
    const cx = a.x + dx * t, cy = a.y + dy * t;
    const d = (px - cx) ** 2 + (py - cy) ** 2;
    if (d < bestD) { bestD = d; bestKm = a.km + (b.km - a.km) * t; }
  }
  return { km: bestKm, offsetM: Math.sqrt(bestD) };
}

/** 드론 lat/lon 의 최근접 측점(점) → { title, km, distM }. */
export function nearestChainPoint(lat: number, lon: number, line: ChainLine): { title: string; km: number; distM: number } | null {
  const pts = line.pts;
  if (!pts.length) return null;
  let nIdx = 0, nD = Infinity;
  for (let i = 0; i < pts.length; i++) {
    const dx = (lat - pts[i].lat) * 111000;
    const dy = (lon - pts[i].lon) * line.k;
    const d = dx * dx + dy * dy;
    if (d < nD) { nD = d; nIdx = i; }
  }
  return { title: pts[nIdx].title, km: pts[nIdx].km, distM: Math.sqrt(nD) };
}
