import { TestBed } from '@angular/core/testing';
import { SearchStateFacade } from '@shelf-store';
import { ShelfFilterService } from './shelf-filter.service';
import { mockFilters } from '../shared/mockdata';
import { hot, cold } from 'jasmine-marbles';
import { take } from 'rxjs/operators';

fdescribe('#ShelfFilterService', () => {
  let service: ShelfFilterService;
  let facade: jasmine.SpyObj<SearchStateFacade>;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      providers: [
        {
          provide: SearchStateFacade,
          useValue: jasmine.createSpyObj('searchStateFacade', ['selectFilters$', 'primaryFilterChangedFromDefault$', 'selectFilters$']),
        },
      ],
    });
    const filters$ = hot('-a--b', { a: mockFilters, b: mockFilters });

    spyOn(ShelfFilterService.prototype, 'initService').and.callFake(() => {
      ShelfFilterService.prototype.filters$ = filters$;
    });
    spyOn(ShelfFilterService.prototype, 'initPendingFilters').and.callFake(() => {});

    facade = TestBed.inject(SearchStateFacade);
    service = TestBed.inject(ShelfFilterService);
  });

  it('should be created', () => {
    expect(service).toBeTruthy();
  });

  describe('#filtersChangedFromDefault', () => {
    beforeEach(() => {
      spyOnProperty(service, 'filtersChangedFromDefault$').and.callThrough();
    });

    it('should return false if the primary Filters changed', () => {
      const pendingFilters$ = cold('-a', { a: mockFilters });
      const primaryFilterChangedFromDefault$ = hot('-b', {
        b: true,
      });
      spyOnProperty(service, 'pendingFilter$', 'get').and.returnValue(pendingFilters$);

      ((facade.primaryFilterChangedFromDefault$ as unknown) as jasmine.Spy).and.returnValue(primaryFilterChangedFromDefault$);

      const expected$ = cold('-c', { c: false });

      expect(service.filtersChangedFromDefault$).toBeObservable(expected$);
    });
    it('should return true if the pending Filters changed', () => {
      const updatedMockFilters = mockFilters.map((filter, index) =>
        index % 2
          ? {
              ...filter,
              options: filter.options.map((o) => ({ ...o, selected: true })),
            }
          : filter
      );
      const pendingFilters$ = cold('-a', { a: updatedMockFilters });
      spyOnProperty(service, 'pendingFilter$', 'get').and.returnValue(pendingFilters$);

      const expected$ = cold('-c', { c: true });
      expect(service.filtersChangedFromDefault$).toBeObservable(expected$);
    });
  });
});
