import { Moment } from 'moment';
import * as moment from 'moment';
import { FlightModel, getFirstLeg, getLastLeg } from '@shared/models-legacy';

export function findClosestFlight(
    flights: FlightModel[] = [],
    flightDate: moment.MomentInput,
    isArrival: boolean,
) {
    if (!flights.length) {
        return;
    }

    const searchForToday = moment().isSame(flightDate, 'day');

    return searchForToday
        ? findClosestFlightForToday(flights, isArrival)
        : findClosestFlightNotForToday(flights, isArrival);
}

function findClosestFlightForToday(flights: FlightModel[], isArrival: boolean) {
    const now = moment();
    let min = Number.MAX_VALUE;
    let candidate: FlightModel = flights[0];

    flights.forEach((flight) => {
        const diff = getDiffFromNow(flight, now, isArrival);

        // It is necessary to call Math.abs with min
        // because min can be negative too
        if (Math.abs(diff) < Math.abs(min)) {
            min = diff;
            candidate = flight;
        }
    });

    return candidate;
}

function findClosestFlightNotForToday(
    flights: FlightModel[],
    isArrival: boolean,
) {
    const firstFlight = flights[0];
    const lastFlight = flights[flights.length - 1];

    const firstFlightTime = getFlightTime(firstFlight, isArrival);

    // For tomorrow returns first flight for yesterday - last
    return moment().isBefore(firstFlightTime) ? firstFlight : lastFlight;
}

function getDiffFromNow(flight: FlightModel, now: Moment, isArrival: boolean) {
    const time = getFlightTime(flight, isArrival);

    return moment(time).diff(now);
}

function getFlightTime(flight: FlightModel, isArrival: boolean) {
    const times = isArrival
        ? getLastLeg(flight).arrival.times
        : getFirstLeg(flight).departure.times;

    return (times.actual ?? times.latest ?? times.scheduled).local;
}
