import { TestBed } from '@angular/core/testing';
import { OnlineBoardBreadCrumbService } from '@online-board/services/bread-crumb.service';
import { OnlineBoardTitleService } from '@online-board/services/title.service';
import { OnlineBoardUrlBuilderService } from '@online-board/services/url';
import { IParsedFlightId } from '@typings/flight/flight-id';

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

    const getStartPageTitleMock = jasmine.createSpy('getStartPageTitle');
    const getFlightNumberTitleMock = jasmine.createSpy('getFlightNumberTitle');
    const getArrivalTitleMock = jasmine.createSpy('getArrivalTitle');
    const getDepartureTitleMock = jasmine.createSpy('getDepartureTitle');
    const getRouteTitleMock = jasmine.createSpy('getRouteTitle');

    const getStartPageUrlMock = jasmine.createSpy('getStartPageUrl');
    const getFlightNumberPageUrlMock = jasmine.createSpy(
        'getFlightNumberPageUrl',
    );
    const getRoutePageUrlMock = jasmine.createSpy('getRoutePageUrl');

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                OnlineBoardBreadCrumbService,
                {
                    provide: OnlineBoardTitleService,
                    useValue: {
                        getStartPageTitle: getStartPageTitleMock,
                        getFlightNumberTitle: getFlightNumberTitleMock,
                        getArrivalTitle: getArrivalTitleMock,
                        getDepartureTitle: getDepartureTitleMock,
                        getRouteTitle: getRouteTitleMock,
                    },
                },
                {
                    provide: OnlineBoardUrlBuilderService,
                    useValue: {
                        getStartPageUrl: getStartPageUrlMock,
                        getFlightNumberPageUrl: getFlightNumberPageUrlMock,
                        getRoutePageUrl: getRoutePageUrlMock,
                    },
                },
            ],
        });

        service = TestBed.inject(OnlineBoardBreadCrumbService);

        getStartPageTitleMock.calls.reset();
        getFlightNumberTitleMock.calls.reset();
        getArrivalTitleMock.calls.reset();
        getDepartureTitleMock.calls.reset();
        getRouteTitleMock.calls.reset();

        getStartPageUrlMock.calls.reset();
        getFlightNumberPageUrlMock.calls.reset();
        getRoutePageUrlMock.calls.reset();
    });

    it('should return root breadcrumb item', () => {
        const url = 'start-page-url';
        const label = 'start-page-label';

        getStartPageUrlMock.withArgs().and.returnValue(url);
        getStartPageTitleMock.withArgs().and.returnValue(label);

        expect(service.getRootBreadCrumb()).toEqual({
            url,
            label,
        });
    });

    it('should return flight number page breadcrumb item', () => {
        const parsedFlightId: IParsedFlightId = {
            flightNumber: '0001',
            carrier: 'SU',
            date: new Date(2022, 4, 28),
        };
        const label = 'flight-number-page-label';
        const url = 'flight-number-page-url';

        getFlightNumberTitleMock
            .withArgs(parsedFlightId, false)
            .and.returnValue(label);
        getFlightNumberPageUrlMock
            .withArgs(parsedFlightId)
            .and.returnValue(url);

        expect(service.getFlightNumberSearchBreadCrumb(parsedFlightId)).toEqual(
            {
                url,
                label,
            },
        );
    });

    it('should return bread crumb item with arrival label', async () => {
        const params = {
            arrival: 'MOW',
            date: new Date(2022, 4, 28),
        };

        const label = 'arrival-search-label';
        const url = 'arrival-search-url';

        getArrivalTitleMock
            .withArgs(params, false)
            .and.returnValue(Promise.resolve(label));
        getRoutePageUrlMock.withArgs(params).and.returnValue(url);

        const result = await service.getRouteSearchBreadCrumb(params);

        expect(result).toEqual({
            label,
            url,
        });
    });

    it('should return bread crumb item with departure label', async () => {
        const params = {
            departure: 'MOW',
            date: new Date(2022, 4, 28),
        };

        const label = 'departure-search-label';
        const url = 'departure-search-url';

        getDepartureTitleMock
            .withArgs(params, false)
            .and.returnValue(Promise.resolve(label));
        getRoutePageUrlMock.withArgs(params).and.returnValue(url);

        const result = await service.getRouteSearchBreadCrumb(params);

        expect(result).toEqual({
            label,
            url,
        });
    });

    it('should return bread crumb item with route label', async () => {
        const params = {
            arrival: 'MRS',
            departure: 'MOW',
            date: new Date(2022, 4, 28),
        };

        const label = 'route-search-label';
        const url = 'route-search-url';

        getRouteTitleMock
            .withArgs(params, false)
            .and.returnValue(Promise.resolve(label));
        getRoutePageUrlMock.withArgs(params).and.returnValue(url);

        const result = await service.getRouteSearchBreadCrumb(params);

        expect(result).toEqual({
            label,
            url,
        });
    });
});
