import { Input, InputType } from '../../types';
import { filterInputMapping } from './filter-input.mapping';
import * as checkboxFilterInputMappingModule from './checkbox-filter-input.mapping';
import * as dateRangeFilterInputMappingModule from './date-range-filter-input.mapping';
import * as textFilterInputMappingModule from './text-filter-input.mapping';

describe('filterInputMapping', () => {
  // Mock implementations for each specific mapping function
  const mockTextFilterInputMapping = jest
    .fn()
    .mockImplementation((group, input) => ({
      type: InputType.Text,
      group,
      key: input.key,
      mapped: 'text',
    }));

  const mockCheckboxFilterInputMapping = jest
    .fn()
    .mockImplementation((group, input) => ({
      type: InputType.Checkbox,
      group,
      key: input.key,
      mapped: 'checkbox',
    }));

  const mockDateRangeFilterInputMapping = jest
    .fn()
    .mockImplementation((group, input) => ({
      type: InputType.DateRange,
      group,
      key: input.key,
      mapped: 'dateRange',
    }));

  beforeEach(() => {
    jest.clearAllMocks();

    // Mock all the mapping functions that filterInputMapping delegates to
    jest
      .spyOn(textFilterInputMappingModule, 'textFilterInputMapping')
      .mockImplementation(mockTextFilterInputMapping);
    jest
      .spyOn(checkboxFilterInputMappingModule, 'checkboxFilterInputMapping')
      .mockImplementation(mockCheckboxFilterInputMapping);
    jest
      .spyOn(dateRangeFilterInputMappingModule, 'dateRangeFilterInputMapping')
      .mockImplementation(mockDateRangeFilterInputMapping);
  });

  it('should delegate to textFilterInputMapping for text inputs', () => {
    // Arrange
    const group = 'testGroup';
    const input: Input = {
      key: 'textInput',
      label: 'Text Input',
      type: InputType.Text,
    };

    // Act
    const result = filterInputMapping(group, input);

    // Assert
    expect(mockTextFilterInputMapping).toHaveBeenCalledWith(group, input);
    expect(mockCheckboxFilterInputMapping).not.toHaveBeenCalled();
    expect(mockDateRangeFilterInputMapping).not.toHaveBeenCalled();
    expect(result).toEqual({
      type: InputType.Text,
      group,
      key: 'textInput',
      mapped: 'text',
    });
  });

  it('should delegate to checkboxFilterInputMapping for checkbox inputs', () => {
    // Arrange
    const group = 'testGroup';
    const input: Input = {
      key: 'checkboxInput',
      label: 'Checkbox Input',
      type: InputType.Checkbox,
    };

    // Act
    const result = filterInputMapping(group, input);

    // Assert
    expect(mockCheckboxFilterInputMapping).toHaveBeenCalledWith(group, input);
    expect(mockTextFilterInputMapping).not.toHaveBeenCalled();
    expect(mockDateRangeFilterInputMapping).not.toHaveBeenCalled();
    expect(result).toEqual({
      type: InputType.Checkbox,
      group,
      key: 'checkboxInput',
      mapped: 'checkbox',
    });
  });

  it('should delegate to dateRangeFilterInputMapping for dateRange inputs', () => {
    // Arrange
    const group = 'testGroup';
    const input: Input = {
      key: 'dateRangeInput',
      label: 'Date Range Input',
      type: InputType.DateRange,
    };

    // Act
    const result = filterInputMapping(group, input);

    // Assert
    expect(mockDateRangeFilterInputMapping).toHaveBeenCalledWith(group, input);
    expect(mockTextFilterInputMapping).not.toHaveBeenCalled();
    expect(mockCheckboxFilterInputMapping).not.toHaveBeenCalled();
    expect(result).toEqual({
      type: InputType.DateRange,
      group,
      key: 'dateRangeInput',
      mapped: 'dateRange',
    });
  });
});
