import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { OnlineBoardFilterComponent } from '@online-board/components/filter/online-board-filter.component';
import { OnlineBoardFilterService } from '@online-board/services/filter/filter.service';
import { getOnlineBoardFilterServiceMock } from '@online-board/services/filter/filter.service.mock';
import { IOnlineBoardRoutePageUrlParams } from '@online-board/services/url';
import { getMockPipe } from '@shared/pipes/pipe.mock';
import { APP_SETTINGS } from '@shared/services';
import { OnlineBoardFiltersStateService } from '@shared/services/filters/online-board-filters-state.service';
import { IParsedFlightId } from '@typings/flight/flight-id';

describe('OnlineBoardFilterComponent', () => {
    let component: OnlineBoardFilterComponent;
    let fixture: ComponentFixture<OnlineBoardFilterComponent>;
    let filterService: OnlineBoardFilterService;
    let state: OnlineBoardFiltersStateService;

    const startValidationDatesUpdatingIntervalMock = jasmine.createSpy(
        'startValidationDatesUpdatingInterval',
    );
    const stopValidationDatesUpdatingIntervalMock = jasmine.createSpy(
        'stopValidationDatesUpdatingInterval',
    );

    const toFlightNumberPageMock = jasmine.createSpy('toFlightNumberPage');
    const toRoutePageMock = jasmine.createSpy('toRoutePage');

    beforeEach(async () => {
        await TestBed.configureTestingModule({
            declarations: [
                OnlineBoardFilterComponent,
                getMockPipe('translate'),
            ],
            providers: [
                OnlineBoardFiltersStateService,
                {
                    provide: APP_SETTINGS,
                    useValue: {
                        startValidationDatesUpdatingInterval:
                            startValidationDatesUpdatingIntervalMock,
                        stopValidationDatesUpdatingInterval:
                            stopValidationDatesUpdatingIntervalMock,
                    },
                },
                {
                    provide: OnlineBoardFilterService,
                    useValue: getOnlineBoardFilterServiceMock(
                        toFlightNumberPageMock,
                        toRoutePageMock,
                    ),
                },
            ],
            schemas: [NO_ERRORS_SCHEMA],
        }).compileComponents();
    });

    beforeEach(() => {
        fixture = TestBed.createComponent(OnlineBoardFilterComponent);
        component = fixture.componentInstance;
        filterService = TestBed.inject(OnlineBoardFilterService);
        state = TestBed.inject(OnlineBoardFiltersStateService);

        startValidationDatesUpdatingIntervalMock.calls.reset();
        stopValidationDatesUpdatingIntervalMock.calls.reset();
        toFlightNumberPageMock.calls.reset();
        toRoutePageMock.calls.reset();
    });

    it('Should start dates updating interval on init', () => {
        component.ngOnInit();
        expect(startValidationDatesUpdatingIntervalMock).toHaveBeenCalled();
    });

    it('Should stop dates updating interval on destroy', () => {
        component.ngOnDestroy();
        expect(stopValidationDatesUpdatingIntervalMock).toHaveBeenCalled();
    });

    it('should set selected tab', () => {
        expect(state.selectedTab).toBe('route');

        component.handleOpen({ index: 0 });
        expect(state.selectedTab).toBe('flight');

        component.handleOpen({ index: 1 });
        expect(state.selectedTab).toBe('route');
    });

    it('should clear selected tab if selected tab was clicked', () => {
        expect(state.selectedTab).toBe('route');
        component.handleClose();

        expect(state.selectedTab).toBe(undefined);
    });

    it('should return selected tab', () => {
        expect(component.selectedTab === state.selectedTab).toBe(true);
    });

    it('should return true if tab is selected', () => {
        expect(component.selectedTab).toBe('route');

        expect(component.isSelected('flight')).toBe(false);
        expect(component.isSelected('route')).toBe(true);
    });

    it('should return appropriate icon color', () => {
        expect(component.selectedTab).toBe('route');

        expect(component.getIconColor('flight')).toBe('blue');
        expect(component.getIconColor('route')).toBe('gray');
    });

    it('should call toFlightNumberPage', () => {
        const params: IParsedFlightId = {
            flightNumber: '0001',
            carrier: 'SU',
            date: new Date(2022, 4, 28),
        };

        component.handleFlightNumberSearch(params);
        expect(filterService.toFlightNumberPage).toHaveBeenCalledWith(params);
    });

    it('should call toRoutePage', () => {
        const params: IOnlineBoardRoutePageUrlParams = {
            arrival: 'MOW',
            date: new Date(2022, 4, 28),
        };

        component.handleRouteSearch(params);
        expect(filterService.toRoutePage).toHaveBeenCalledWith(params);
    });
});
