import { TestBed } from '@angular/core/testing';
import { ScheduleApiService } from '@schedule/services/api.service';
import { ScheduleDetailsDataSourceService } from '@schedule/services/data-source/details-data-source.service';
import { ScheduleDateValidationService } from '@schedule/services/date-validation.service';
import { IScheduleDetailsParams } from '@schedule/services/url/types';
import PopulateLogicLegacy from '@shared/models-legacy/populate.logic';
import { RouteType } from '@typings/enums';
import {
    getFlightMock,
    getMultiLegFlightMock,
} from '@utils/test/get-flight.mock';

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

    const getFlightDetailsMock = jasmine.createSpy('getFlightDetails');

    const defaultDate = new Date(2022, 4, 28);
    const defaultParams: IScheduleDetailsParams = {
        flights: [
            {
                flightNumber: '0001',
                carrier: 'SU',
                date: defaultDate,
            },
            {
                flightNumber: '0002',
                carrier: 'SU',
                date: defaultDate,
            },
        ]
    };

    const flightsInfo = ['SU0001', 'SU0002'];
    const dates = [defaultDate, defaultDate];

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                ScheduleDetailsDataSourceService,
                {
                    provide: ScheduleDateValidationService,
                    useValue: {},
                },
                {
                    provide: ScheduleApiService,
                    useValue: {
                        getFlightDetails: getFlightDetailsMock,
                    },
                },
            ],
        });

        getFlightDetailsMock.calls.reset();

        createFlightsMock = spyOn(PopulateLogicLegacy, 'createFlights');

        service = TestBed.inject(ScheduleDetailsDataSourceService);
    });

    it('should set flights for connecting flight result', async () => {
        const flights = [
            getFlightMock('GDX', 'MOW', '1'),
            getMultiLegFlightMock(
                [
                    {
                        departure: 'GDX',
                        arrival: 'MFQ',
                    },
                    {
                        departure: 'IGT',
                        arrival: 'MQF',
                    },
                ],
                '2',
            ),
        ];

        createFlightsMock.withArgs(flights).and.returnValue(flights);
        getFlightDetailsMock.withArgs(flightsInfo, dates).and.returnValue(
            Promise.resolve({
                data: {
                    routes: flights,
                },
            }),
        );

        expect(service.flight).toBe(undefined);
        expect(service.flightLegacy).toBe(undefined);
        expect(service.detailsLoading).toBe(false);

        await service.loadFlightDetails(defaultParams);

        expect(service.detailsLoading).toBe(false);
        expect(service.flight.routeType).toBe(RouteType.CONNECTING);
        expect((service.flight as any).flights).toBe(flights);

        expect(service.flightLegacy.routeType).toBe(RouteType.CONNECTING);
        expect((service.flightLegacy as any).flights).toBe(flights);

        expect(flights[0].leg.crossIndex).toBe(1);
        expect(flights[1].legs[0].crossIndex).toBe(2);
        expect(flights[1].legs[1].crossIndex).toBe(3);
    });

    it('should set flights for direct flight result', async () => {
        const flights = [getFlightMock('GDX', 'MOW', '1')];

        createFlightsMock.withArgs(flights).and.returnValue(flights);
        getFlightDetailsMock.withArgs(flightsInfo, dates).and.returnValue(
            Promise.resolve({
                data: {
                    routes: flights,
                },
            }),
        );

        await service.loadFlightDetails(defaultParams);

        expect(service.detailsLoading).toBe(false);
        expect(service.flight).toEqual(flights[0]);

        expect(service.flightLegacy).toEqual(flights[0]);

        expect(flights[0].leg.crossIndex).toBe(undefined);
    });
});
