import { ComponentFixture, TestBed, fakeAsync, tick, flush } from '@angular/core/testing';
import { HistoryStateFacade } from '@shelf-store/history';
import { ShelfHistoryLogsComponent } from './shelf-history-logs.component';
import { NO_ERRORS_SCHEMA } from '@angular/core';
import { ShelfHistoryLogModule } from '../../../components/history-log';
import { CommonModule } from '@angular/common';
import { FilterHistoriesWithStatusChangePipe } from '../pipes';
import { of } from 'rxjs';
import { By } from '@angular/platform-browser';
import { take } from 'rxjs/operators';

fdescribe('ShelfHistoryLogComponent', () => {
  let fixture: ComponentFixture<ShelfHistoryLogsComponent>;
  let component: ShelfHistoryLogsComponent;
  let facade: jasmine.SpyObj<HistoryStateFacade>;

  const id = 123;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      imports: [CommonModule, ShelfHistoryLogModule],
      declarations: [ShelfHistoryLogsComponent, FilterHistoriesWithStatusChangePipe],
      providers: [
        {
          provide: HistoryStateFacade,
          useValue: jasmine.createSpyObj('historyStateFacade', ['getHistory$', 'hasErrorStatus$']),
        },
      ],
      schemas: [NO_ERRORS_SCHEMA],
    }).compileComponents();

    facade = TestBed.inject(HistoryStateFacade);
    fixture = TestBed.createComponent(ShelfHistoryLogsComponent);
    component = fixture.componentInstance;

    component.orderItemSubsetId = id;
  });

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

  describe('getHistory', () => {
    it('should call the facade to get the histories', () => {
      spyOn(component, 'getHistory$').and.callThrough();
      component.getHistory$();

      expect(facade.getHistory$).toHaveBeenCalled();
    });
  });

  describe('History status management', () => {
    it('should show a message when the history could not be fetched', async () => {
      spyOn(component, 'getErrorStatus$').and.returnValue(of(true));
      component.ngOnInit();

      fixture.detectChanges();

      const result = await component.hasError$.pipe(take(1)).toPromise();
      expect(result).toBe(true);

      const errorMessage = fixture.debugElement.query(By.css('#error'));
      expect(errorMessage).toBeTruthy();
    });

    it('should call the facade to to get the error status', () => {
      spyOn(component, 'getErrorStatus$').and.returnValue(of(false));

      component.ngOnInit();
      expect(component.getErrorStatus$).toHaveBeenCalled();
    });
  });
});
