import { Inject, Injectable } from '@angular/core';
import { ApiParserService } from '@shared/services/api/parser.service';
import { UrlBuilderService } from '@shared/services/url/url-builder.service';
import { RouteType } from '@typings/enums';
import { IConnectingFlight, IFlight } from '@typings/flight/flight';
import { IScheduleRouteDirectionParams } from './types';
import { SCHEDULE_URL_BASE } from './url-base';
import { IWithLeg } from '@utils/flight/legs/types';
import FlightDateUtils from '@utils/flight/date';
import * as moment from 'moment';

@Injectable()
export class ScheduleUrlBuilderService extends UrlBuilderService {
    constructor(
        @Inject(SCHEDULE_URL_BASE) public base,
        protected apiParser: ApiParserService,
    ) {
        super(apiParser);
    }

    getStartPageUrl() {
        return this.base;
    }

    getDetailsPageUrl(flight: IFlight, date?: Date) {
        if (flight.routeType === RouteType.CONNECTING) {
            return this.getConnectingFlightDetailsPageUrl(flight, date);
        }

        const departure = this.getDeparture(flight);
        const arrival = this.getArrival(flight);
        var diff = 0;
        if (date != null) {
            var oldDate = moment(FlightDateUtils.getFlightDate(flight));
            oldDate.startOf('day');
            diff = moment(date).diff(oldDate);
        }
        var flightDate = new Date(FlightDateUtils.getFlightDate(flight).getTime()+diff);
        return `${this.base}/${departure}/${this.formatFlightIdWithDate(flight.flightId, flightDate)}/${arrival}`;
    }

    getRoutePageUrl(
        outbound: IScheduleRouteDirectionParams,
        inbound?: IScheduleRouteDirectionParams,
    ) {
        const base = `${this.base}/route`;
        const routeParamsUrl = this.formatRouteParams(outbound);

        if (inbound) {
            const returnRouteParamsUrl = this.formatRouteParams(inbound);
            return `${base}/${routeParamsUrl}/${returnRouteParamsUrl}`;
        }

        return `${base}/${routeParamsUrl}`;
    }

    formatRouteParams(params: IScheduleRouteDirectionParams) {
        const dateFrom = this.formatDate(params.dateFrom);
        const dateTo = this.formatDate(params.dateTo);

        let base = `${params.departure}-${params.arrival}-${dateFrom}-${dateTo}`;

        if (params.timeFrom && params.timeTo) {
            base = `${base}-${params.timeFrom}${params.timeTo}`;
        }

        if (params.connections || params.connections === 0) {
            base = `${base}-C${params.connections}`;
        }

        return base;
    }

    private getDeparture(flight: IWithLeg) {
        if (flight.routeType == RouteType.DIRECT) {
            return flight.leg.departure.scheduled.airportCode;
        }
        if (flight.routeType == RouteType.MULTI_LEG) {
            return flight.legs[0].departure.scheduled.airportCode;
        }
    }

    private getArrival(flight: IWithLeg) {
        if (flight.routeType == RouteType.DIRECT) {
            return flight.leg.arrival.scheduled.airportCode;
        }
        if (flight.routeType == RouteType.MULTI_LEG) {
            return flight.legs[flight.legs.length-1].arrival.scheduled.airportCode;
        }
    }

    private getConnectingFlightDetailsPageUrl(flight: IConnectingFlight, date?: Date) {
        var diff = 0;
        if (date != null) {
            var oldDate = moment(FlightDateUtils.getFlightDate(flight.flights[0]));
            oldDate.startOf('day');
            diff = moment(date).diff(oldDate);
        }
        var url = `${this.base}/`;
        var prevAirport = '';
        flight.flights.forEach((fl) => {
            var departure = this.getDeparture(fl);
            if (prevAirport != departure) {
                url += departure+'/';
            }
            var arrival = this.getArrival(fl);
            var flightDate = new Date(FlightDateUtils.getFlightDate(fl).getTime()+diff);
            url += this.formatFlightIdWithDate(fl.flightId, flightDate) + '/' + arrival + '/';
            prevAirport = arrival;
        });

        return url;
    }
}
