import { By } from '@angular/platform-browser';
import { RouterTestingModule } from '@angular/router/testing';
import { BreadcrumbService } from '@core/breadcrumb';
import { DomainGoodsService } from '@domain/oms';
import { createComponentFactory, mockProvider, Spectator } from '@ngneat/spectator';
import { UiIconComponent } from '@ui/icon';
import { MockComponent } from 'ng-mocks';
import { GoodsInSearchFilterComponent } from './goods-in-search-filter';
import { GoodsInSearchComponent } from './goods-in-search.component';
import { GoodsInSearchStore } from './goods-in-search.store';

describe('GoodsInSearchComponent', () => {
  let spectator: Spectator<GoodsInSearchComponent>;
  let goodsInSearchStoreMock: jasmine.SpyObj<GoodsInSearchStore>;

  const createGoodsInComponent = createComponentFactory({
    component: GoodsInSearchComponent,
    declarations: [MockComponent(GoodsInSearchFilterComponent), MockComponent(UiIconComponent)],
    imports: [RouterTestingModule],
    componentProviders: [
      mockProvider(DomainGoodsService),
      mockProvider(GoodsInSearchStore, {
        loadSettings: async () => {},
      }),
      mockProvider(BreadcrumbService),
    ],
  });

  beforeEach(() => {
    spectator = createGoodsInComponent();
    goodsInSearchStoreMock = spectator.inject(GoodsInSearchStore, true);
  });

  it('should create', () => {
    expect(spectator.component).toBeTruthy();
  });

  describe('ngOnInit()', () => {
    it('should call GoodsInSearchService.loadSettings()', () => {
      spyOn(goodsInSearchStoreMock, 'loadSettings');
      spectator.component.ngOnInit();
      expect(goodsInSearchStoreMock.loadSettings).toHaveBeenCalled();
    });
  });

  describe('toggleFilterOverlay()', () => {
    it('should set showFilterOverlay to true', () => {
      spectator.component.showFilterOverlay = false;
      spectator.component.toggleFilterOverlay();
      expect(spectator.component.showFilterOverlay).toBe(true);
    });

    it('should set showFilterOverlay to false', () => {
      spectator.component.showFilterOverlay = true;
      spectator.component.toggleFilterOverlay();
      expect(spectator.component.showFilterOverlay).toBe(false);
    });
  });

  describe('button.filter', () => {
    it('should call toggleFilterOverlay() on click', () => {
      spyOn(spectator.component, 'toggleFilterOverlay');
      spectator.click('button.filter');

      expect(spectator.component.toggleFilterOverlay).toHaveBeenCalled();
    });
  });

  describe('page-goods-in-search-filter', () => {
    it('should not render the component if showFilterOverlay is false', () => {
      spectator.component.showFilterOverlay = false;
      spectator.detectComponentChanges();
      expect(spectator.query('page-goods-in-search-filter')).toBeNull();
    });

    it('should render the component if showFilterOverlay is true', () => {
      spectator.component.showFilterOverlay = true;
      spectator.detectComponentChanges();
      expect(spectator.query('page-goods-in-search-filter')).not.toBeNull();
    });

    it('should call toggleFilterOverlay() on (close)', () => {
      spyOn(spectator.component, 'toggleFilterOverlay');

      spectator.component.showFilterOverlay = true;
      spectator.detectComponentChanges();
      spectator.query('page-goods-in-search-filter');
      const filter: GoodsInSearchFilterComponent = spectator.debugElement.query(By.directive(GoodsInSearchFilterComponent))
        .componentInstance;
      filter.close.emit();

      expect(spectator.component.toggleFilterOverlay).toHaveBeenCalled();
    });
  });
});
