import computeDestinationPoint from 'geolib/es/computeDestinationPoint';
import getGreatCircleBearing from 'geolib/es/getGreatCircleBearing';
import getPreciseDistance from 'geolib/es/getPreciseDistance';
import { generateOverflyArc } from '../pathGenerators/generateOverflyArc';
import { computeSpeed } from '../utils/computeSpeed';

// NOTE: Distance not adjusted for altitude in this demo
export const TerminatorsFD = (
  leg: FDTerminalEntry,
  previousFix: NavFix,
  lastCourse: number
): [NavFix?, LineSegment[]?] => {
  const refFix = {
    latitude: leg.WptLat,
    longitude: leg.WptLon,
  };
  const navaid = {
    latitude: leg.NavLat,
    longitude: leg.NavLon,
  };
  const crsIntoEndpoint = leg.Course.toTrue(refFix);
  const speed = computeSpeed(leg, previousFix);

  // Compute overfly
  const [line, arcEnd, _lastCourse] = generateOverflyArc(crsIntoEndpoint, lastCourse, previousFix, speed, leg.TurnDir);
  lastCourse = _lastCourse;

  // Compute distance to fly from arc end
  const crsToNavaid = getGreatCircleBearing(arcEnd, navaid);
  const distToNavaid = getPreciseDistance(arcEnd, navaid);
  let remainingDistance = leg.Distance.toMetre();
  // Navaid behind us
  if (Math.abs(crsToNavaid - lastCourse) > 90) {
    remainingDistance -= distToNavaid;
  }
  // Navaid in front of us
  else {
    // Navaid will not be passed before distance is hit
    if (distToNavaid > remainingDistance) remainingDistance = distToNavaid - remainingDistance;
  }

  // Compute intercept of crs from arc end and distance
  const targetFix: NavFix = {
    ...computeDestinationPoint(arcEnd, remainingDistance, lastCourse),
    name: leg.Distance.toString(),
    isFlyOver: true,
    altitude: leg.Alt ? leg.Alt.parseAltitude() : previousFix.altitude,
    speed: speed,
    speedConstraint: leg.SpeedLimit,
    altitudeConstraint: leg.Alt,
    IsFAF: leg.IsFAF,
    IsMAP: leg.IsMAP,
  };
  line.push([targetFix.longitude, targetFix.latitude]);

  return [targetFix, line];
};
