import { Component, Input } from '@angular/core';
import { Leg } from '@app/shared/models-legacy';
import { arrivalBlockOnTimes, departureBlockOffTimes } from '@app/utils/times';
import { ITimesSet } from '@typings/times';

type ITimesSetExtractor = (leg: Leg) => ITimesSet;

export type StationProperty = keyof Pick<Leg, 'arrival' | 'departure'>;
@Component({
    selector: 'timeline',
    templateUrl: './timeline.component.html',
    styleUrls: ['./timeline.component.scss'],
})
export class TimelineComponent {
    @Input() canChange = true;
    @Input() legs: Leg[];
    index = 0;

    getDepartureActualTimesSet(index: number) {
        return this.getActualTimesSet(index, getDepartureScheduledTimes, getDepartureActualTimes);
    }

    getArrivalActualTimesSet(index: number) {
        return this.getActualTimesSet(index, getArrivalScheduledTimes, getArrivalActualTimes);
    }

    getDepartureScheduledTimesSet(index: number) {
        return this.getScheduledTimesSet(index, getDepartureScheduledTimes);
    }

    getArrivalScheduledTimesSet(index: number) {
        return this.getScheduledTimesSet(index, getArrivalScheduledTimes);
    }

    getActualTimesSet(index: number, getScheduled: ITimesSetExtractor, getActual: ITimesSetExtractor) {
        if (!this.canChange) {
            return;
        }

        const leg = this.legs[index];

        if (!leg) {
            return;
        }

        const scheduled = getScheduled(leg);
        const actual = getActual(leg);

        return this.canChange ? actual || scheduled : scheduled;
    }

    getScheduledTimesSet(index: number, getScheduled: ITimesSetExtractor) {
        const leg = this.legs[index];

        if (!leg) {
            return;
        }

        return getScheduled(leg);
    }

    getType() {
        return this.canChange ? 'actual' : 'scheduled';
    }

    next() {
        this.index++;
    }

    previous() {
        this.index--;
    }

    isSpecifying(leg: Leg) {
        const duration = this.canChange ? leg.estimatedDuration || leg.scheduledDuration : leg.scheduledDuration;

        if (!duration) {
            return true;
        }

        const { days, hours, minutes } = duration;

        return days < 0 || hours < 0 || minutes < 0;
    }
}

function getArrivalActualTimes(leg: Leg) {
    return arrivalBlockOnTimes(leg.arrival._times);
}

function getDepartureActualTimes(leg: Leg) {
    return departureBlockOffTimes(leg.departure._times);
}

function getArrivalScheduledTimes(leg: Leg) {
    return leg.arrival._times.scheduledArrival;
}

function getDepartureScheduledTimes(leg: Leg) {
    return leg.departure._times.scheduledDeparture;
}
