import type { CurrentVesselPosition, ProcessedTrack } from '../model/track.types';

function calculateHeading(from: [number, number], to: [number, number]): number {
  const dx = to[0] - from[0];
  const dy = to[1] - from[1];
  let angle = (Math.atan2(dx, dy) * 180) / Math.PI;
  if (angle < 0) angle += 360;
  return angle;
}

function interpolate(
  from: [number, number],
  to: [number, number],
  fromTs: number,
  toTs: number,
  currentTs: number,
): [number, number] {
  if (toTs <= fromTs) return from;
  if (currentTs <= fromTs) return from;
  if (currentTs >= toTs) return to;

  const ratio = (currentTs - fromTs) / (toTs - fromTs);
  return [
    from[0] + (to[0] - from[0]) * ratio,
    from[1] + (to[1] - from[1]) * ratio,
  ];
}

export function getCurrentPosition(track: ProcessedTrack, currentTime: number): CurrentVesselPosition | null {
  const len = track.timestampsMs.length;
  if (len === 0 || track.geometry.length === 0) return null;

  const firstTime = track.timestampsMs[0];
  const lastTime = track.timestampsMs[len - 1];
  if (currentTime < firstTime || currentTime > lastTime) return null;

  if (len === 1) {
    return {
      vesselId: track.vesselId,
      targetId: track.targetId,
      sigSrcCd: track.sigSrcCd,
      shipName: track.shipName,
      shipKindCode: track.shipKindCode,
      nationalCode: track.nationalCode,
      position: track.geometry[0],
      heading: 0,
      speed: track.speeds[0] || 0,
      timestamp: firstTime,
    };
  }

  let hi = len - 1;
  let lo = 0;
  while (lo <= hi) {
    const mid = Math.floor((lo + hi) / 2);
    if (track.timestampsMs[mid] <= currentTime) lo = mid + 1;
    else hi = mid - 1;
  }

  const idx = Math.max(0, Math.min(len - 2, hi));
  const from = track.geometry[idx];
  const to = track.geometry[idx + 1];
  const fromTs = track.timestampsMs[idx];
  const toTs = track.timestampsMs[idx + 1];

  const position = interpolate(from, to, fromTs, toTs, currentTime);
  const heading = calculateHeading(from, to);
  const speed = track.speeds[idx] || 0;

  return {
    vesselId: track.vesselId,
    targetId: track.targetId,
    sigSrcCd: track.sigSrcCd,
    shipName: track.shipName,
    shipKindCode: track.shipKindCode,
    nationalCode: track.nationalCode,
    position,
    heading,
    speed,
    timestamp: currentTime,
  };
}

export function getCurrentPositions(tracks: ProcessedTrack[], currentTime: number): CurrentVesselPosition[] {
  const out: CurrentVesselPosition[] = [];
  for (const track of tracks) {
    const pos = getCurrentPosition(track, currentTime);
    if (pos) out.push(pos);
  }
  return out;
}
