import {
  createComponentFactory,
  Spectator,
  mockProvider,
} from '@ngneat/spectator/jest';
import { FilterActionsComponent } from './filter-actions.component';
import { FilterService } from '../core';

describe('FilterActionsComponent', () => {
  let spectator: Spectator<FilterActionsComponent>;
  const createComponent = createComponentFactory({
    component: FilterActionsComponent,
    providers: [
      mockProvider(FilterService, {
        inputs: jest.fn().mockReturnValue([
          { target: 'filter', key: 'key1', group: 'filter' },
          { target: 'input', key: 'key2', group: 'other' },
        ]),
        commit: jest.fn(),
        reset: jest.fn(),
        resetInput: jest.fn(),
      }),
    ],
  });

  beforeEach(() => {
    spectator = createComponent();
  });

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

  it('should filter inputs by target "filter"', () => {
    const filteredInputs = spectator.component.filterInputs();
    expect(filteredInputs).toEqual([
      { target: 'filter', key: 'key1', group: 'filter' },
    ]);
  });

  it('should call commit and emit applied when onApply is called without inputKey', () => {
    const filterService = spectator.inject(FilterService);
    const appliedSpy = jest.spyOn(spectator.component.applied, 'emit');

    spectator.setInput('inputKey', null);
    spectator.component.onApply();

    expect(filterService.commit).toHaveBeenCalled();
    expect(appliedSpy).toHaveBeenCalled();
  });

  it('should call commitInput and emit applied when onApply is called with inputKey', () => {
    const filterService = spectator.inject(FilterService);
    const appliedSpy = jest.spyOn(spectator.component.applied, 'emit');

    spectator.setInput('inputKey', 'key1');
    spectator.component.onApply();

    expect(filterService.commit).toHaveBeenCalled();
    expect(appliedSpy).toHaveBeenCalled();
  });

  it('should call reset, commit, and emit reseted when onReset is called without inputKey', () => {
    const filterService = spectator.inject(FilterService);
    const resetedSpy = jest.spyOn(spectator.component.reseted, 'emit');

    spectator.setInput('inputKey', null);
    spectator.component.onReset();

    expect(filterService.resetInput).toHaveBeenCalled();
    expect(filterService.commit).toHaveBeenCalled();
    expect(resetedSpy).toHaveBeenCalled();
  });

  it('should call resetInput, commit, and emit reseted when onReset is called with inputKey', () => {
    const filterService = spectator.inject(FilterService);
    const resetedSpy = jest.spyOn(spectator.component.reseted, 'emit');

    spectator.setInput('inputKey', 'key1');
    spectator.component.onReset();

    expect(filterService.resetInput).toHaveBeenCalledWith(['key1']);
    expect(filterService.commit).toHaveBeenCalled();
    expect(resetedSpy).toHaveBeenCalled();
  });
});
