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

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

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

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

  describe('selectedOption computed', () => {
    it('should be null when value is null', () => {
      componentRef.setInput('value', null);
      componentRef.setInput('options', []);
      fixture.detectChanges();
      // biome-ignore lint/suspicious/noExplicitAny: access protected computed for test
      expect((component as any).selectedOption()).toBeNull();
    });

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

    it('should be null when value has no matching option', () => {
      componentRef.setInput('value', 'missing');
      componentRef.setInput('options', [{ value: 'a', label: 'A' }]);
      fixture.detectChanges();
      // biome-ignore lint/suspicious/noExplicitAny: access protected computed for test
      expect((component as any).selectedOption()).toBeNull();
    });
  });

  describe('valueChange output', () => {
    it('should emit the option value when a selection happens', () => {
      const emitted: (string | null)[] = [];
      component.valueChange.subscribe((v) => emitted.push(v));

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

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

    it('should emit null when selection is cleared', () => {
      const emitted: (string | null)[] = [];
      component.valueChange.subscribe((v) => emitted.push(v));

      // biome-ignore lint/suspicious/noExplicitAny: invoke protected handler
      (component as any).onValueChange(null);

      expect(emitted).toEqual([null]);
    });
  });

  describe('touched output', () => {
    it('should fire when the consumer triggers it (popover close emits via template binding)', () => {
      let emittedCount = 0;
      component.touched.subscribe(() => emittedCount++);
      component.touched.emit();
      expect(emittedCount).toBe(1);
    });
  });
});
