import { Component } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { By } from '@angular/platform-browser';

import { <%= classify(name) %> } from './<%= dasherize(name) %>';

@Component({
  imports: [<%= classify(name) %>],
  template: `<<%= selector %> />`,
})
class HostComponent {}

describe('<%= classify(name) %>', () => {
  let fixture: ComponentFixture<HostComponent>;
  let host: HTMLElement;

  beforeEach(async () => {
    await TestBed.configureTestingModule({
      imports: [HostComponent],
    }).compileComponents();

    fixture = TestBed.createComponent(HostComponent);
    fixture.detectChanges();
    host = fixture.nativeElement as HTMLElement;
  });

  it('renders the combobox with label and collapsed popup wiring', () => {
    const input = host.querySelector<HTMLInputElement>('[role="combobox"]');
    const listbox = host.querySelector<HTMLElement>('[role="listbox"]');

    expect(input).toBeTruthy();
    expect(input?.getAttribute('aria-autocomplete')).toBe('list');
    expect(input?.getAttribute('aria-expanded')).toBe('false');
    expect(input?.getAttribute('aria-controls')).toBe(listbox?.id);
    expect(input?.getAttribute('aria-labelledby')).toBeTruthy();
    expect(listbox?.hidden).toBe(true);
  });

  it('filters options from user input and opens the listbox', () => {
    const inputDebug = fixture.debugElement.query(By.css('[role="combobox"]'));
    const input = inputDebug.nativeElement as HTMLInputElement;

    input.value = 'ba';
    inputDebug.triggerEventHandler('input', { target: input });
    fixture.detectChanges();

    const options = Array.from(host.querySelectorAll<HTMLElement>('[role="option"]'));
    const listbox = host.querySelector<HTMLElement>('[role="listbox"]');

    expect(input.value).toBe('ba');
    expect(listbox?.hidden).toBe(false);
    expect(options.map((option) => option.textContent?.trim())).toEqual(['Banana']);
  });

  it('moves active option with the keyboard and selects it with Enter', () => {
    const inputDebug = fixture.debugElement.query(By.css('[role="combobox"]'));
    const input = inputDebug.nativeElement as HTMLInputElement;

    inputDebug.triggerEventHandler('keydown', new KeyboardEvent('keydown', { key: 'ArrowDown' }));
    fixture.detectChanges();

    let activeOption = host.querySelector<HTMLElement>('[role="option"][aria-selected="true"]');
    expect(input.getAttribute('aria-activedescendant')).toBe(activeOption?.id);
    expect(activeOption?.textContent?.trim()).toBe('Maçã');

    inputDebug.triggerEventHandler('keydown', new KeyboardEvent('keydown', { key: 'ArrowDown' }));
    fixture.detectChanges();

    activeOption = host.querySelector<HTMLElement>('[role="option"][aria-selected="true"]');
    expect(activeOption?.textContent?.trim()).toBe('Banana');

    inputDebug.triggerEventHandler('keydown', new KeyboardEvent('keydown', { key: 'Enter' }));
    fixture.detectChanges();

    const listbox = host.querySelector<HTMLElement>('[role="listbox"]');
    expect(input.value).toBe('Banana');
    expect(listbox?.hidden).toBe(true);
  });
});
