import { ComponentFixture, TestBed } from '@angular/core/testing';
import { SwitchMenuButtonComponent } from './switch-menu-button.component';
import { FilterService } from '../../core';
import { InputType } from '../../types';
import { signal } from '@angular/core';

describe('SwitchMenuButtonComponent', () => {
  let component: SwitchMenuButtonComponent;
  let fixture: ComponentFixture<SwitchMenuButtonComponent>;
  let mockFilterService: jest.Mocked<Partial<FilterService>>;

  beforeEach(async () => {
    mockFilterService = {
      inputs: signal([
        {
          type: InputType.Checkbox,
          key: 'test-switch',
          label: 'Test Switch',
          group: 'test-group',
          target: 'filter' as const,
          options: [{ key: 'option1', label: 'Option 1' }],
          selected: [],
        },
      ]),
      isDefaultFilterInput: jest.fn().mockReturnValue(true),
      setInputCheckboxOptionSelected: jest.fn(),
    } as any;

    await TestBed.configureTestingModule({
      imports: [SwitchMenuButtonComponent],
      providers: [{ provide: FilterService, useValue: mockFilterService }],
    }).compileComponents();

    fixture = TestBed.createComponent(SwitchMenuButtonComponent);
    component = fixture.componentInstance;
    fixture.componentRef.setInput('filterInput', {
      type: InputType.Checkbox,
      key: 'test-switch',
      label: 'Test Switch',
      group: 'test-group',
      target: 'filter' as const,
      options: [{ key: 'option1', label: 'Option 1' }],
      selected: [],
    });
    fixture.componentRef.setInput('icon', 'isaActionCheck');
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });

  it('should retrieve the correct checkbox input', () => {
    const input = component.input();
    expect(input).toBeDefined();
    expect(input.key).toBe('test-switch');
  });

  it('should return false for checked when no options are selected', () => {
    expect(component.checked()).toBe(false);
  });

  it('should return true for checked when options are selected', () => {
    fixture.componentRef.setInput('filterInput', {
      type: InputType.Checkbox,
      key: 'test-switch',
      label: 'Test Switch',
      group: 'test-group',
      target: 'filter' as const,
      options: [{ key: 'option1', label: 'Option 1' }],
      selected: [{ key: 'option1', label: 'Option 1' }],
    });

    mockFilterService.inputs = signal([
      {
        type: InputType.Checkbox,
        key: 'test-switch',
        label: 'Test Switch',
        group: 'test-group',
        target: 'filter' as const,
        options: [{ key: 'option1', label: 'Option 1' }],
        selected: [{ key: 'option1', label: 'Option 1' }],
      },
    ]) as any;
    fixture.detectChanges();

    expect(component.checked()).toBe(true);
  });

  it('should call setInputCheckboxOptionSelected when toggled', () => {
    component.onToggle(true);

    expect(
      mockFilterService.setInputCheckboxOptionSelected,
    ).toHaveBeenCalledWith({ key: 'option1', label: 'Option 1' }, true, {
      commit: true,
    });
  });

  it('should retrieve the first option', () => {
    const option = component.option();
    expect(option).toEqual({ key: 'option1', label: 'Option 1' });
  });

  it('should emit toggled event when onToggle is called', () => {
    const spy = jest.fn();
    component.toggled.subscribe(spy);

    component.onToggle(true);

    expect(spy).toHaveBeenCalled();
  });

  it('should check if input is in default state', () => {
    expect(component.isDefaultInputState()).toBe(true);
  });
});
