import {
    Component,
    EventEmitter,
    Input,
    OnChanges,
    Output,
    SimpleChanges,
} from '@angular/core';
import { ScheduleHelpersService } from '@schedule/services/schedule-helpers.service';
import { FlightModel, ScheduleItemModel } from '@shared/models-legacy';
import { areSame } from '@utils/date';
import { compareFlightsByPId } from '@utils/flight/p-id';

@Component({
    selector: 'schedule-flights-mini-list',
    templateUrl: './schedule-flights-mini-list.component.html',
    styleUrls: ['./schedule-flights-mini-list.component.scss'],
})
export class ScheduleFlightsMiniListComponent implements OnChanges {
    @Input() flight: FlightModel;
    @Input('schedule') scheduleInput: ScheduleItemModel[];
    @Input() loading: boolean;

    @Output() open = new EventEmitter<FlightModel>();

    private _initialDate: Date;
    schedule: ScheduleItemModel[];

    constructor(private scheduleHelpers: ScheduleHelpersService) {}

    ngOnChanges(changes: SimpleChanges) {
        if ('flight' in changes) {
            this._initialDate = this.flight && this.flight.dateToSearchBy;
        }

        if ('scheduleInput' in changes) {
            this.schedule = this.scheduleInput;
        }

        if ('flight' in changes || 'scheduleInput' in changes) {
            this.addDaysToSchedule();
        }
    }

    openFlight(flight: FlightModel) {
        this.open.emit(flight);
    }

    get shouldShowAccordion() {
        return this.schedule?.length > 1;
    }

    get initialDate() {
        // _initialDate can be undefined in showStateSchedule because
        // ngOnChanges called before ngOnInit. After ngOnInit call
        // this.initialDate will be this.flight.dateToSearchBy.
        const flightDate = this.flight && this.flight.dateToSearchBy;

        return this._initialDate || flightDate;
    }

    isInitiallySelected(scheduleItem: ScheduleItemModel) {
        return areSame(this.initialDate, scheduleItem.date);
    }

    isFlightSelected(flight: FlightModel) {
        return compareFlightsByPId(flight as any, this.flight as any);
    }

    private addDaysToSchedule() {
        // it is possible in two cases:
        // 1) when the first day of schedule exceeds -1 day threshold:
        //    this.schedule[0] - schedule for yesterday;
        //    this.schedule[1] - schedule for today.
        // 2) when the first day is monday of the next week. Then there is no
        //    tuesday of the next week in this.state.schedule
        if (this.schedule?.length !== 2) {
            return;
        }

        const [firstDay] = this.schedule;

        if (areSame(this.initialDate, firstDay.date)) {
            this.addPastDay();
        } else {
            this.addFutureDay();
        }
    }

    private addPastDay() {
        const itemToAdd = this.scheduleHelpers.getFirstScheduleDayToAdd(
            this.schedule,
        );

        this.schedule = [itemToAdd, ...this.schedule];
    }

    private addFutureDay() {
        const itemToAdd = this.scheduleHelpers.getLastScheduleDayToAdd(
            this.schedule,
        );

        this.schedule = [...this.schedule, itemToAdd];
    }
}
