import { TestBed } from '@angular/core/testing';
import { ScheduleBreadCrumbService } from '@schedule/services/bread-crumb.service';
import { ScheduleTitleService } from '@schedule/services/title.service';
import { ScheduleUrlBuilderService } from '@schedule/services/url/url-builder.service';

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

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

    const getStartPageTitleMock = jasmine.createSpy('getStartPageTitle');
    const getSearchPageRouteTitleMock = jasmine.createSpy(
        'getSearchPageRouteTitle',
    );

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                ScheduleBreadCrumbService,
                {
                    provide: ScheduleUrlBuilderService,
                    useValue: {
                        getStartPageUrl: getStartPageUrlMock,
                        getRoutePageUrl: getRoutePageUrlMock,
                    },
                },
                {
                    provide: ScheduleTitleService,
                    useValue: {
                        getStartPageTitle: getStartPageTitleMock,
                        getSearchPageRouteTitle: getSearchPageRouteTitleMock,
                    },
                },
            ],
        });

        service = TestBed.inject(ScheduleBreadCrumbService);

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

        getStartPageTitleMock.calls.reset();
        getSearchPageRouteTitleMock.calls.reset();
    });

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

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

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

    it('should return breadcrumb item for outbound route', async () => {
        const url = 'outbound-route-url';
        const label = 'outbound-route-label';
        const outbound = {
            departure: 'MOW',
            arrival: 'MRS',
            dateFrom: new Date(2022, 4, 20),
            dateTo: new Date(2022, 4, 26),
        };

        getSearchPageRouteTitleMock
            .withArgs(outbound)
            .and.returnValue(Promise.resolve(label));
        getRoutePageUrlMock.withArgs(outbound, undefined).and.returnValue(url);

        const result = await service.getSearchPageBreadCrumb(outbound);
        expect(result).toEqual({
            url,
            label,
        });
    });

    it('should return breadcrumb item for full route', async () => {
        const url = 'full-route-url';
        const label = 'full-route-label';
        const outbound = {
            departure: 'MOW',
            arrival: 'MRS',
            dateFrom: new Date(2022, 4, 20),
            dateTo: new Date(2022, 4, 26),
        };
        const inbound = {
            departure: 'MRS',
            arrival: 'MOW',
            dateFrom: new Date(2022, 4, 20),
            dateTo: new Date(2022, 4, 26),
        };

        getSearchPageRouteTitleMock
            .withArgs(outbound)
            .and.returnValue(Promise.resolve(label));
        getRoutePageUrlMock.withArgs(outbound, inbound).and.returnValue(url);

        const result = await service.getSearchPageBreadCrumb(outbound, inbound);
        expect(result).toEqual({
            url,
            label,
        });
    });
});
