import { TestBed } from '@angular/core/testing';
import { DictionariesService } from '@modules/components/page-filters/services/dictionaries-service';
import { getDictionariesServiceMock } from '@modules/components/page-filters/services/dictionaries-service.mock';
import { TranslatePipe, TranslateService } from '@ngx-translate/core';
import { OnlineBoardMetaTagsService } from '@online-board/services/meta-tags.service';
import { DateTransformerService } from '@shared/services/date/date-transformer.service';

describe('OnlineBoardMetaTagsService', () => {
    let service: OnlineBoardMetaTagsService;
    const transformMock = jasmine.createSpy('transform');
    const instantMock = jasmine.createSpy('instant');

    beforeEach(() => {
        TestBed.configureTestingModule({
            providers: [
                OnlineBoardMetaTagsService,
                DateTransformerService,
                {
                    provide: DictionariesService,
                    useValue: getDictionariesServiceMock(),
                },
                {
                    provide: TranslatePipe,
                    useValue: {
                        transform: transformMock,
                    },
                },
                {
                    provide: TranslateService,
                    useValue: {
                        instant: instantMock,
                    },
                },
            ],
        });

        service = TestBed.inject(OnlineBoardMetaTagsService);
        transformMock.calls.reset();
        instantMock.calls.reset();

        jasmine.clock().install();
        jasmine.clock().mockDate(new Date(2022, 4, 1));
    });

    afterEach(() => {
        jasmine.clock().uninstall();
    });

    it('should return object with empty fields as arrival meta tags if arrival was not provided', async () => {
        const result = await service.getArrivalMetaTags({} as any);

        expect(result.title).toBe('');
        expect(result.description).toBe('');
    });

    it('should return arrival meta tags', async () => {
        const expectedArgsObj = {
            arrivalCity: 'Москва',
            date: '28.05.2022',
        };

        transformMock
            .withArgs('SEO.BOARD.ARRIVAL-SEARCH.TITLE', expectedArgsObj)
            .and.returnValue('arrival title');
        transformMock
            .withArgs('SEO.BOARD.ARRIVAL-SEARCH.DESCRIPTION', expectedArgsObj)
            .and.returnValue('arrival description');

        const result = await service.getArrivalMetaTags({
            arrival: 'MOW',
            date: new Date(2022, 4, 28),
        });

        expect(result.title).toBe('arrival title');
        expect(result.description).toBe('arrival description');
    });

    it('should return object with empty fields as departure meta tags if departure was not provided', async () => {
        const result = await service.getDepartureMetaTags({} as any);

        expect(result.title).toBe('');
        expect(result.description).toBe('');
    });

    it('should return departure meta tags', async () => {
        const expectedArgsObj = {
            departureCity: 'Москва',
            date: '28.05.2022',
        };

        transformMock
            .withArgs('SEO.BOARD.DEPARTURE-SEARCH.TITLE', expectedArgsObj)
            .and.returnValue('departure title');
        transformMock
            .withArgs('SEO.BOARD.DEPARTURE-SEARCH.DESCRIPTION', expectedArgsObj)
            .and.returnValue('departure description');

        const result = await service.getDepartureMetaTags({
            departure: 'MOW',
            date: new Date(2022, 4, 28),
        });

        expect(result.title).toBe('departure title');
        expect(result.description).toBe('departure description');
    });

    it('should return object with empty fields as route meta tags if departure or arrival were not provided', async () => {
        const expected = {
            title: '',
            description: '',
        };

        let result = await service.getRouteMetaTags({} as any);
        expect(result).toEqual(expected);

        result = await service.getRouteMetaTags({ arrival: 'MOW' } as any);
        expect(result).toEqual(expected);

        result = await service.getRouteMetaTags({
            departure: 'MRS',
        } as any);
        expect(result).toEqual(expected);
    });

    it('should return departure meta tags', async () => {
        const expectedArgsObj = {
            departureCity: 'Москва',
            arrivalCity: 'Марсель',
            date: '28.05.2022',
        };

        transformMock
            .withArgs('SEO.BOARD.ROUTE-SEARCH.TITLE', expectedArgsObj)
            .and.returnValue('route title');
        transformMock
            .withArgs('SEO.BOARD.ROUTE-SEARCH.DESCRIPTION', expectedArgsObj)
            .and.returnValue('route description');

        const result = await service.getRouteMetaTags({
            departure: 'MOW',
            arrival: 'MRS',
            date: new Date(2022, 4, 28),
        });

        expect(result.title).toBe('route title');
        expect(result.description).toBe('route description');
    });

    it('should return flight number meta tags', () => {
        const expectedArgsObj = {
            flightNumber: 'SU 0001',
            date: '28.05.2022',
        };

        transformMock
            .withArgs('SEO.BOARD.FLIGHT-SEARCH.TITLE', expectedArgsObj)
            .and.returnValue('flight number title');
        transformMock
            .withArgs('SEO.BOARD.FLIGHT-SEARCH.DESCRIPTION', expectedArgsObj)
            .and.returnValue('flight number description');

        const result = service.getFlightNumberMetaTags({
            flightNumber: '0001',
            carrier: 'SU',
            date: new Date(2022, 4, 28),
        });

        expect(result.title).toBe('flight number title');
        expect(result.description).toBe('flight number description');
    });
});
