import { Injectable } from '@angular/core';
import { ActivatedRouteSnapshot, CanActivate } from '@angular/router';
import { OnlineBoardNavigationService } from '@online-board/services/navigation.service';
import { OnlineBoardRequestParserService } from '@online-board/services/request/request-parser.service';
import { OnlineBoardUrlParserService } from '@online-board/services/url';
import { CanActivateDateParams } from './utils/can-activate-date-params';
import { CanActivateRouteParams } from './utils/can-activate-route-params';
import { CanActivateRedirrect } from './utils/can-activate-redirrect-to-not-found';

@Injectable()
export class CanActivateOnlineBoardDetails implements CanActivate {
    constructor(
        private urlService: OnlineBoardUrlParserService,
        private dateParamsService: CanActivateDateParams,
        private routeParamsService: CanActivateRouteParams,
        private requestService: OnlineBoardRequestParserService,
        private navigationService: OnlineBoardNavigationService,
        private canRedirrect: CanActivateRedirrect,
    ) { }

    async canActivate(route: ActivatedRouteSnapshot) {
        const urlParams = this.urlService.parseFlightId(route.params.params);

        if (!this.canRedirrect.validateFlightNumber(urlParams.flightNumber)) {
            return this.navigationService.toNotFound();
        }

        const validationResult = await this.dateParamsService.canActivate(
            urlParams,
        );

        if (validationResult !== true) {
            return validationResult;
        }

        const requestValidationResult = await this.canActivateQueryParams(
            route,
        );

        if (requestValidationResult !== true) {
            return this.navigationService.toDetailsPage({
                flightId: {
                    flightNumber: urlParams.flightNumber,
                    carrier: urlParams.carrier,
                    suffix: urlParams.suffix,
                    date: '',
                },
                date: urlParams.date,
            });
        }

        return true;
    }

    private async canActivateQueryParams(route: ActivatedRouteSnapshot) {
        const { request } = route.queryParams;
        if (!request) {
            return true;
        }

        const onlineBoardRequest = this.requestService.parse(request);

        switch (onlineBoardRequest.type) {
            case 'flight-number': {
                return this.dateParamsService.validateDateParams(
                    onlineBoardRequest.params,
                );
            }
            case 'route': {
                return this.routeParamsService.validateRouteParams(
                    onlineBoardRequest.params,
                );
            }
        }
    }
}
