import { Component, OnInit } from '@angular/core';
import { Router } from '@angular/router';
import { PopularRequestsApiService } from '@app/features/popular-requests/services/api.service';
import { OnlineBoardFiltersStateService } from '@shared/services/filters/online-board-filters-state.service';
import { ScheduleFiltersStateService } from '@shared/services/filters/schedule-filters-state.service';
import { UserLocationService } from '@shared/services/user-location/user-location.service';
import { RequestMode } from '@typings/enums';
import {
    IPopularRequest,
    IPopularRouteRequest,
} from '@typings/popular-request';
import MobileUtils from '@utils/mobile';
import { getDefaultTimeRangeOnMobile } from '@utils/time-range';
import { getWeek } from '@utils/week';
import * as moment from 'moment';

@Component({
    selector: 'popular-requests',
    templateUrl: './popular-requests.component.html',
    styleUrls: ['./popular-requests.component.scss'],
})
export class PopularRequestsComponent implements OnInit {
    requests: IPopularRequest[] = [];
    locationPermitted = false;

    constructor(
        private apiService: PopularRequestsApiService,
        private boardFiltersState: OnlineBoardFiltersStateService,
        private scheduleState: ScheduleFiltersStateService,
        private locationService: UserLocationService,
        private router: Router,
    ) {}

    ngOnInit(): void {
        this.apiService.getPopularRequests().then((requests) => {
            this.requests = requests;
        });

        this.locationService.location.subscribe((location) => {
            this.locationPermitted = location !== null;
        });
    }

    handleRequestClick(request: IPopularRequest) {
        this.clearFilters(request);

        switch (request.mode) {
            case RequestMode.FLIGHT_NUMBER: {
                this.boardFiltersState.selectedTab = 'flight';
                this.boardFiltersState.flightNumber = request.flightNumber;
                this.boardFiltersState.flightNumberDate = new Date();

                this.router.navigateByUrl('onlineboard');
                return;
            }
            case RequestMode.ARRIVAL: {
                this.setBoardRoute(request.arrival);

                this.router.navigateByUrl('onlineboard');
                return;
            }
            case RequestMode.DEPARTURE: {
                this.setBoardRoute(undefined, request.departure);

                this.router.navigateByUrl('onlineboard');
                return;
            }
            case RequestMode.ROUTE: {
                this.handleRouteRequest(request);

                return;
            }
            case RequestMode.SCHEDULE_ROUTE_BOTH_DIRECTIONS: {
                this.setScheduleRoute(request.arrival, request.departure, true);

                this.router.navigateByUrl('schedule');
            }
        }
    }

    private clearFilters(request: IPopularRequest) {
        switch (request.type) {
            case 'Schedule': {
                this.scheduleState.clear();
                return;
            }
            case 'Onlineboard': {
                if (request.mode !== RequestMode.FLIGHT_NUMBER) {
                    this.boardFiltersState.clearRoute();
                    return;
                }
            }
        }
    }

    private setBoardRoute(arrival?: string, departure?: string) {
        this.boardFiltersState.selectedTab = 'route';
        this.boardFiltersState.arrival = arrival;
        this.boardFiltersState.departure = departure;
        this.boardFiltersState.routeDate = new Date();

        this.scheduleState.arrival = arrival;
        this.scheduleState.departure = departure;

        if (MobileUtils.isMobile() && this.locationPermitted) {
            this.boardFiltersState.timeRange = getDefaultTimeRangeOnMobile();
        }
    }

    private setScheduleRoute(
        arrival: string,
        departure: string,
        withReturn: boolean,
    ) {
        this.scheduleState.departure = departure;
        this.scheduleState.arrival = arrival;
        this.scheduleState.dateRange = getWeek();

        if (withReturn) {
            const nextWeekDay = moment().add(1, 'week').toDate();
            this.scheduleState.returnDateRange = getWeek(nextWeekDay);
            this.scheduleState.withReturn = true;
        }
    }

    private handleRouteRequest(request: IPopularRouteRequest) {
        if (request.type === 'Onlineboard') {
            this.setBoardRoute(request.arrival, request.departure);
            this.router.navigateByUrl('onlineboard');
        } else {
            this.setScheduleRoute(request.arrival, request.departure, false);

            this.router.navigateByUrl('schedule');
        }
    }
}
