import { ScheduleItemModel, FlightModel } from '@shared/models-legacy';
import { IRouteContract } from '@shared/models-legacy/contracts';
import { createFlights } from '@shared/models-legacy/populate.logic';
import * as moment from 'moment';

export function createScheduleFromRoutes(
    contracts: IRouteContract[],
    dateFrom: Date,
    dateTo: Date,
) {
    const flights = createFlights(contracts);

    return createSchedule(flights, dateFrom, dateTo);
}
export function createSchedule(
    flights: FlightModel[],
    dateFrom: Date,
    dateTo: Date,
): ScheduleItemModel[] {
    function byDate(flight: FlightModel) {
        return moment(flight.dateToSearchBy).startOf('day').toDate().getTime();
    }

    const result = flights.groupBy(byDate).map(({ key, items: flights }) => {
        return new ScheduleItemModel({
            date: moment(key).toDate(),
            flights,
        });
    });

    return addMissingDays(result, dateFrom, dateTo);
}

function addMissingDays(
    items: ScheduleItemModel[],
    dateFrom: Date,
    dateTo: Date,
): ScheduleItemModel[] {
    const map = new Map<number, ScheduleItemModel>();
    for (const item of items) {
        if (dateFrom <= item.date && item.date <= dateTo)
            map.set(item.date.getTime(), item);
    }

    const daysBetween = moment(dateTo).diff(dateFrom, 'day');

    for (let i = 0; i <= daysBetween; i++) {
        const date = moment(dateFrom).add(i, 'day').toDate();
        const key = date.getTime();
        if (map.has(key)) continue;
        map.set(key, new ScheduleItemModel({ date }));
    }

    items = [...map.values()];

    function byDate(a: ScheduleItemModel, b: ScheduleItemModel) {
        if (a.date > b.date) return 1;
        if (a.date < b.date) return -1;
        return 0;
    }

    return items.sort(byDate);
}

const ScheduleLegacyFactories = {
    createScheduleFromRoutes,
    createSchedule,
};

export default ScheduleLegacyFactories;
