import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { OnlineBoardRouteFilterValidationService } from '@online-board/components/filter/components/route-filter/services/online-board-route-filter-validation.service';
import { IOnlineBoardRoutePageUrlParams } from '@online-board/services/url/types';
import { IOnlineBoardRouteData } from '@online-board/types';
import { OnlineBoardFiltersStateService } from '@shared/services/filters/online-board-filters-state.service';
import { UserLocationService } from '@shared/services/user-location/user-location.service';
import { IUrlTimeRange } from '@typings/common/url';
import MobileUtils from '@utils/mobile';
import { getDefaultTimeRangeOnMobile } from '@utils/time-range';
import { OnlineBoardApiService } from '@online-board/services/api.service';
import { StateService } from '@shared/services/state.service';

@Component({
    selector: 'online-board-route-filter',
    templateUrl: './online-board-route-filter.component.html',
    providers: [OnlineBoardRouteFilterValidationService],
})
export class OnlineBoardRouteFilterComponent implements OnInit {
    @Input() minDate: Date;
    @Input() maxDate: Date;
    disabledDates: Date[];

    @Output() onSearch = new EventEmitter<IOnlineBoardRoutePageUrlParams>();

    constructor(
        public validationService: OnlineBoardRouteFilterValidationService,
        private apiService: OnlineBoardApiService,
        private route: ActivatedRoute,
        private locationService: UserLocationService,
        private state: OnlineBoardFiltersStateService,
        private stateService: StateService,
    ) {}

    ngOnInit() {
        this.route.data.subscribe((data: IOnlineBoardRouteData) => {
            if (data.urlParams?.route) {
                this.setState(data.urlParams.route);
            }
        });

        this.locationService.location.subscribe((location) => {
            // set default state only if user permitted geo position
            // search and filter isn't filled
            if (location && !this.departure && !this.arrival) {
                this.setDefaultState(location);
            }
        });
    }

    get date() {
        return this.state.routeDate;
    }

    set date(date: Date) {
        this.state.routeDate = date;
    }

    get arrival() {
        return this.state.arrival;
    }

    set arrival(arrival: string) {
        this.state.arrival = arrival;
        this.updateCalendar();
    }

    get departure() {
        return this.state.departure;
    }

    set departure(departure: string) {
        this.state.departure = departure;
        this.updateCalendar();
    }

    get timeRange() {
        return this.state.timeRange;
    }

    set timeRange(timeRange: IUrlTimeRange) {
        this.state.timeRange = timeRange;
    }

    get departurePlaceholder() {
        return this.arrival
            ? 'SHARED.ALL_DIRECTIONS'
            : 'SHARED.CITY_PLACEHOLDER';
    }

    get arrivalPlaceholder() {
        return this.departure
            ? 'SHARED.ALL_DIRECTIONS'
            : 'SHARED.CITY_PLACEHOLDER';
    }

    async updateCalendar() {
        const isDepartureValid = await this.validationService.validateCode(this.departure);
        const isArrivalValid = await this.validationService.validateCode(this.arrival);

        if (isDepartureValid || isArrivalValid) {
            var date = new Date();
            date.setUTCHours(0,0,0,0);
            date.setDate(date.getDate() - 1);
            this.apiService
                .getFlightDaysByRoute(date, isDepartureValid ? this.departure: undefined, isArrivalValid ? this.arrival: undefined)
                .then((res) => {
                    this.disabledDates = new Array();
                    for(var i=0;i<res.days.length;i++) {
                        if (res.days[i] == '0') {
                            this.disabledDates.push(new Date(date));
                        }
                        date.setDate(date.getDate() + 1);
                    }
                })
                .finally(() => {
                });
        } else {
            this.disabledDates = new Array();
        }
    }

    exchange() {
        [this.departure, this.arrival] = [this.arrival, this.departure];
    }

    async search() {
        const params = this.getSearchParams();
        const areParamsValid = await this.validationService.validate(params);
        if (!areParamsValid) {
            return;
        }
        this.stateService.set("boardroute", params);

        this.onSearch.emit(params);
    }

    private setState(params: IOnlineBoardRoutePageUrlParams) {
        this.departure = params.departure;
        this.arrival = params.arrival;
        this.date = params.date;

        if (params.timeFrom && params.timeTo) {
            this.timeRange = {
                timeFrom: params.timeFrom,
                timeTo: params.timeTo,
            };
        }
    }

    private setDefaultState(userLocation: string) {
        this.departure = userLocation;
        this.date = new Date();

        if (MobileUtils.isMobile()) {
            this.timeRange = getDefaultTimeRangeOnMobile();
        }
        this.search();
    }

    private getSearchParams(): IOnlineBoardRoutePageUrlParams {
        return {
            arrival: this.arrival,
            departure: this.departure,
            date: this.date,
            timeFrom: this.timeRange?.timeFrom,
            timeTo: this.timeRange?.timeTo,
        };
    }
}
