import '@angular/compiler';
import { ComponentRef } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import type { Option } from '../types';
import { AsyncMultipleSearchSelect } from './async-multiple-search-select.component';

describe('AsyncMultipleSearchSelect', () => {
  let fixture: ComponentFixture<AsyncMultipleSearchSelect>;
  let component: AsyncMultipleSearchSelect;
  let componentRef: ComponentRef<AsyncMultipleSearchSelect>;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [AsyncMultipleSearchSelect],
    });

    fixture = TestBed.createComponent(AsyncMultipleSearchSelect);
    component = fixture.componentInstance;
    componentRef = fixture.componentRef;
  });

  describe('selectedOptions computed', () => {
    it('should resolve matching options', () => {
      const options: Option[] = [
        { value: 'a', label: 'A' },
        { value: 'b', label: 'B' },
      ];
      componentRef.setInput('value', ['a']);
      componentRef.setInput('options', options);
      fixture.detectChanges();
      // biome-ignore lint/suspicious/noExplicitAny: access protected computed for test
      expect((component as any).selectedOptions()).toEqual([options[0]]);
    });
  });

  describe('valueChange output', () => {
    it('should emit ids array when options selected', () => {
      const emitted: string[][] = [];
      component.valueChange.subscribe((v) => emitted.push(v));

      // biome-ignore lint/suspicious/noExplicitAny: invoke protected handler
      (component as any).onValueChange([
        { value: 'x', label: 'X' },
        { value: 'y', label: 'Y' },
      ]);

      expect(emitted).toEqual([['x', 'y']]);
    });
  });

  describe('searchChange output', () => {
    beforeEach(() => {
      vi.useFakeTimers();
    });

    afterEach(() => {
      vi.useRealTimers();
    });

    it('should debounce search input before emitting', () => {
      componentRef.setInput('debounce', 300);
      fixture.detectChanges();

      const emitted: string[] = [];
      component.searchChange.subscribe((v) => emitted.push(v));

      // biome-ignore lint/suspicious/noExplicitAny: invoke protected handler
      const onSearch = (component as any).onSearchChange.bind(component);

      onSearch('a');
      onSearch('ab');
      onSearch('abc');
      expect(emitted).toEqual([]);

      vi.advanceTimersByTime(300);
      expect(emitted).toEqual(['abc']);
    });
  });

  describe('touched output', () => {
    it('should fire when emitted', () => {
      let emittedCount = 0;
      component.touched.subscribe(() => emittedCount++);
      component.touched.emit();
      expect(emittedCount).toBe(1);
    });
  });
});
