import { TestBed } from '@angular/core/testing';
import { ScheduleRequestParserService } from '@schedule/services/request/request-parser.service';
import { IScheduleRouteDirectionParams } from '@schedule/services/url/types';
import { SCHEDULE_URL_BASE } from '@schedule/services/url/url-base';
import { ScheduleUrlParserService } from '@schedule/services/url/url-parser.service';

describe('ScheduleRequestParserService', () => {
    let service: ScheduleRequestParserService;

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                ScheduleUrlParserService,
                ScheduleRequestParserService,
                {
                    provide: SCHEDULE_URL_BASE,
                    useValue: 'schedule',
                },
            ],
        });
        service = TestBed.inject(ScheduleRequestParserService);
    });

    it('should parse one way request without time range and connections', () => {
        const request = 'schedule-route-NBC-KHV-20220307-20220313';
        const { outbound, inbound } = service.parseRouteRequest(request);
        assertRoute(outbound);

        expect(inbound).toBe(undefined);
    });

    it('should parse one way request without connections', () => {
        const request = 'schedule-route-NBC-KHV-20220307-20220313-06002200';
        const { outbound, inbound } = service.parseRouteRequest(request);
        assertRoute(outbound, '0600', '2200');

        expect(inbound).toBe(undefined);
    });

    it('should parse one way request without time range', () => {
        const request = 'schedule-route-NBC-KHV-20220307-20220313-C1';
        const { outbound, inbound } = service.parseRouteRequest(request);
        assertRoute(outbound, undefined, undefined, 1);

        expect(inbound).toBe(undefined);
    });

    it('should parse one way request with all params', () => {
        const request = 'schedule-route-NBC-KHV-20220307-20220313-06002200-С0';
        const { outbound, inbound } = service.parseRouteRequest(request);
        assertRoute(outbound, '0600', '2200', 0);

        expect(inbound).toBe(undefined);
    });

    it('should parse two ways request without time range and connections', () => {
        const request =
            'schedule-route-NBC-KHV-20220307-20220313-KHV-NBC-20220307-20220313';
        const { outbound, inbound } = service.parseRouteRequest(request);

        assertRoute(outbound);
        assertRoute(inbound, undefined, undefined, undefined, true);
    });

    it('should parse two ways request without connections', () => {
        const request =
            'schedule-route-NBC-KHV-20220307-20220313-06002200-KHV-NBC-20220307-20220313-06002200';
        const { outbound, inbound } = service.parseRouteRequest(request);

        assertRoute(outbound, '0600', '2200');
        assertRoute(inbound, '0600', '2200', undefined, true);
    });

    it('should parse two ways request without time range', () => {
        const request =
            'schedule-route-NBC-KHV-20220307-20220313-C1-KHV-NBC-20220307-20220313-C1';
        const { outbound, inbound } = service.parseRouteRequest(request);

        assertRoute(outbound, undefined, undefined, 1);
        assertRoute(inbound, undefined, undefined, 1, true);
    });

    it('should parse two ways request with all params', () => {
        const request =
            'schedule-route-NBC-KHV-20220307-20220313-06002200-С0-KHV-NBC-20220307-20220313-06002200-C0';
        const { outbound, inbound } = service.parseRouteRequest(request);

        assertRoute(outbound, '0600', '2200', 0);
        assertRoute(inbound, '0600', '2200', 0, true);
    });

    function assertRoute(
        route: IScheduleRouteDirectionParams,
        timeFrom?: string,
        timeTo?: string,
        connections?: number,
        isReturn = false,
    ) {
        const departure = isReturn ? 'KHV' : 'NBC';
        const arrival = isReturn ? 'NBC' : 'KHV';

        expect(route.departure).toBe(departure);
        expect(route.arrival).toBe(arrival);
        expect(route.dateFrom).toEqual(new Date(2022, 2, 7));
        expect(route.dateTo).toEqual(new Date(2022, 2, 13));
        expect(route.timeFrom).toBe(timeFrom);
        expect(route.timeTo).toBe(timeTo);
        expect(route.connections).toBe(connections);
    }
});
