import { ComponentFixture, TestBed } from '@angular/core/testing';
import { AutocompleteResultsComponent } from './autocomplete-results.component';
import { ResultItemComponent } from './result-item';
import { ActiveDescendantKeyManager, Highlightable } from '@angular/cdk/a11y';
import { QueryList } from '@angular/core';

fdescribe('#AutocompleteResultsComponent', () => {
  let fixture: ComponentFixture<AutocompleteResultsComponent>;
  let component: AutocompleteResultsComponent;

  let items: QueryList<Highlightable & ResultItemComponent>;

  beforeEach(async () => {
    TestBed.configureTestingModule({
      declarations: [AutocompleteResultsComponent, ResultItemComponent],
    }).compileComponents();
  });

  beforeEach(() => {
    fixture = TestBed.createComponent(AutocompleteResultsComponent);
    component = fixture.componentInstance;
    items = new QueryList();
    component['keyManager'] = new ActiveDescendantKeyManager<ResultItemComponent>(items).withWrap();

    spyOn(component, 'ngAfterViewInit').and.callFake(() => {});
    component.results = [];
    fixture.detectChanges();
  });

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

  describe('Deselect Items on keypress', () => {
    let activeItemMock: Highlightable & ResultItemComponent;
    beforeEach(() => {
      activeItemMock = ({
        result: 'Test Result',
      } as unknown) as Highlightable & ResultItemComponent;
      spyOn(component, 'onKeyDown').and.callThrough();
      spyOn(component.selectItem, 'emit').and.callFake(() => {});
      spyOnProperty(component['keyManager'], 'activeItem').and.returnValue(activeItemMock);
      spyOn(component['keyManager'], 'setActiveItem').and.callFake(() => {});
    });

    it('should deselect the current active item if a letter is typed', () => {
      const event = new KeyboardEvent('keyup', { key: 'a' });
      window.dispatchEvent(event);
      fixture.detectChanges();

      expect(component.onKeyDown).toHaveBeenCalled();
      expect(component['keyManager'].setActiveItem).toHaveBeenCalledWith(null);
    });

    it('should deselect the current active item if backspace is typed', () => {
      const event = new KeyboardEvent('keyup', { key: 'Backspace' });
      window.dispatchEvent(event);
      fixture.detectChanges();

      expect(component.onKeyDown).toHaveBeenCalled();
      expect(component['keyManager'].setActiveItem).toHaveBeenCalledWith(null);
    });

    it('should not deselect if ArrowUp is pressed', () => {
      const event = new KeyboardEvent('keyup', { key: 'ArrowUp' });
      window.dispatchEvent(event);
      fixture.detectChanges();

      expect(component.onKeyDown).toHaveBeenCalled();
      expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(null);
      expect(component.selectItem.emit).toHaveBeenCalledWith(activeItemMock.result);
    });

    it('should not deselect if ArrowDown is pressed', () => {
      const event = new KeyboardEvent('keyup', { key: 'ArrowDown' });
      window.dispatchEvent(event);
      fixture.detectChanges();

      expect(component.onKeyDown).toHaveBeenCalled();
      expect(component['keyManager'].setActiveItem).not.toHaveBeenCalledWith(null);
      expect(component.selectItem.emit).toHaveBeenCalledWith(activeItemMock.result);
    });
  });
});
