import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { ActivatedRoute } from '@angular/router';
import { DictionariesService } from '@modules/components/page-filters/services/dictionaries-service';
import { TranslatePipe } from '@ngx-translate/core';
import { ScheduleSearchMetaTagsComponent } from '@schedule/pages/search/components/meta-tags/schedule-search-meta-tags.component';
import { ScheduleUrlParserService } from '@schedule/services/url/url-parser.service';
import { DateTransformerService } from '@shared/services/date/date-transformer.service';
import { BehaviorSubject } from 'rxjs';

describe('ScheduleSearchMetaTagsComponent', () => {
    let fixture: ComponentFixture<ScheduleSearchMetaTagsComponent>;
    let component: ScheduleSearchMetaTagsComponent;

    const dateFrom = new Date(2022, 4, 28);
    const transformedDate = '2022-05-28';

    const params1 = 'MOW-KUF-20220528-20220531';
    const params2 = 'MOW-LED-20220528-20220531';
    const routeParams = {};

    const title = 'schedule flight details meta tag title';
    const description = 'schedule flight details meta tag description';

    const titleForEmptyArrival = 'empty title';
    const descriptionForEmptyArrival = 'empty description';

    const getCityOrAirportMock = jasmine
        .createSpy('getCityOrAirport')
        .withArgs('MOW')
        .and.returnValue({ name: 'Moscow' })
        .withArgs('KUF')
        .and.returnValue({ name: 'Samara' })
        .withArgs('LED')
        .and.returnValue(undefined);

    const transformMock = jasmine
        .createSpy('transform')
        .withArgs('SEO.SCHEDULE.SEARCH.TITLE', {
            departureCity: 'Moscow',
            arrivalCity: 'Samara',
            date: transformedDate,
        })
        .and.returnValue(title)
        .withArgs('SEO.SCHEDULE.SEARCH.DESCRIPTION', {
            departureCity: 'Moscow',
            arrivalCity: 'Samara',
            date: transformedDate,
        })
        .and.returnValue(description)
        .withArgs('SEO.SCHEDULE.SEARCH.TITLE', {
            departureCity: 'Moscow',
            arrivalCity: '',
            date: transformedDate,
        })
        .and.returnValue(titleForEmptyArrival)
        .withArgs('SEO.SCHEDULE.SEARCH.DESCRIPTION', {
            departureCity: 'Moscow',
            arrivalCity: '',
            date: transformedDate,
        })
        .and.returnValue(descriptionForEmptyArrival);

    const parseRouteParamsMock = jasmine
        .createSpy('parseRouteParams')
        .withArgs(params1)
        .and.returnValue({
            departure: 'MOW',
            arrival: 'KUF',
            dateFrom,
        })
        .withArgs(params2)
        .and.returnValue({
            departure: 'MOW',
            arrival: 'LED',
            dateFrom,
        });

    const toStringMock = jasmine
        .createSpy('toString')
        .withArgs(dateFrom)
        .and.returnValue(transformedDate);

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [ScheduleSearchMetaTagsComponent],
            providers: [
                {
                    provide: ActivatedRoute,
                    useValue: {
                        params: new BehaviorSubject(routeParams),
                    },
                },
                {
                    provide: DictionariesService,
                    useValue: {
                        ready$: Promise.resolve(),
                        getCityOrAirport: getCityOrAirportMock,
                    },
                },
                {
                    provide: TranslatePipe,
                    useValue: {
                        transform: transformMock,
                    },
                },
                {
                    provide: ScheduleUrlParserService,
                    useValue: {
                        parseRouteParams: parseRouteParamsMock,
                    },
                },
                {
                    provide: DateTransformerService,
                    useValue: {
                        toString: toStringMock,
                    },
                },
            ],
            schemas: [NO_ERRORS_SCHEMA],
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(ScheduleSearchMetaTagsComponent);
        component = fixture.componentInstance;

        getCityOrAirportMock.calls.reset();
        transformMock.calls.reset();
        parseRouteParamsMock.calls.reset();
        toStringMock.calls.reset();
    });

    it('should set title and description fields for schedule', async () => {
        (routeParams as any).params = params1;
        component.ngOnInit();
        await Promise.resolve();

        expect(component.title).toBe(title);
        expect(component.description).toBe(description);
    });

    it('should set empty title and description fields for schedule', async () => {
        (routeParams as any).params = params2;
        component.ngOnInit();
        await Promise.resolve();

        expect(component.title).toBe(titleForEmptyArrival);
        expect(component.description).toBe(descriptionForEmptyArrival);
    });
});
