import { SearchState, INITIAL_SEARCH_STATE } from './search.state';
import { TypedAction } from '@ngrx/store/src/models';
import { PrimaryFilterOption } from 'apps/sales/src/app/modules/shelf/defs';
import { primaryFiltersMock, mockFilters } from 'apps/sales/src/app/modules/shelf/shared/mockdata';
import * as actions from './search.actions';
import { searchReducer } from './search.reducer';

fdescribe('#SearchStateReducer', () => {
  const id = 123;
  let initialState: SearchState;

  beforeEach(() => {
    const action = actions.addSearchProcess({ id });
    initialState = searchReducer(INITIAL_SEARCH_STATE, action);
  });

  describe('setPrimaryFilters', () => {
    const filters = primaryFiltersMock;
    let action: {
      id: number;
      filters: PrimaryFilterOption[];
    } & TypedAction<string>;

    beforeEach(() => {
      action = actions.setPrimaryFilters({ id, filters });
    });

    it('should update the primary filters', () => {
      const state = searchReducer(initialState, action);

      const entity = state.entities[id];

      expect(entity).toBeTruthy();
      expect(entity.filters.primaryFilters).toEqual(primaryFiltersMock);
    });

    it('should keep the original order of primary filter items', () => {
      const state = searchReducer(initialState, action);

      const entity = state.entities[id];

      expect(entity.filters.primaryFilters[0]).toEqual(primaryFiltersMock[0]);
      expect(entity.filters.primaryFilters[1]).toEqual(primaryFiltersMock[1]);
    });
  });

  describe('resetPrimaryFilters', () => {
    let action: {
      id: number;
    } & TypedAction<string>;

    beforeEach(() => {
      action = actions.resetPrimaryFilters({ id });
    });

    it('should reset the primary Filters to their default state', () => {
      const updatedPrimaryFilters = primaryFiltersMock.map((primaryFilter, i) =>
        i % 2 === 0 ? primaryFilter : { ...primaryFilter, selected: true }
      );
      const setPrimaryFilterAction = actions.setPrimaryFilters({
        id,
        filters: updatedPrimaryFilters,
      });

      let state = searchReducer(initialState, setPrimaryFilterAction);
      state = searchReducer(state, action);

      expect(state.entities[id].filters.primaryFilters).toEqual(primaryFiltersMock);
    });
  });

  describe('resetSelectedFilters', () => {
    let action: {
      id: number;
    } & TypedAction<string>;

    beforeEach(() => {
      action = actions.resetSelectFilters({ id });
    });

    it('should reset all selected filters to their default state', () => {
      const selectFilters = [
        ...mockFilters.map((filter) => ({
          ...filter,
          options: filter.options.map((o) => ({ ...o, selected: true })),
        })),
      ];

      const setSelectedFilters = actions.setSelectFilters({
        id,
        filters: selectFilters,
      });

      let state = searchReducer(initialState, setSelectedFilters);
      state = searchReducer(state, action);

      expect(state.entities[id].filters.selectedFilters).toEqual(mockFilters);
    });
  });

  describe('setPendingInput', () => {
    let action: {
      id: number;
      input: string;
    } & TypedAction<string>;
    const pendingInput = 'Initial Value';

    beforeEach(() => {
      action = actions.setPendingInput({ id, input: pendingInput });
    });

    it('should set the provided string as pending input for the given process (id)', () => {
      const state = searchReducer(initialState, action);

      expect(state.entities[id].pendingInput).toEqual(pendingInput);
      expect(state.entities[id].input).toEqual(initialState.entities[id].input);
    });
  });
});
