import { Data } from '../../../../types';
import { addItem, removeItem } from './DynamicListReducer.actions';
import { DynamicListReducerInit } from './DynamicListReducer.init';
import {
  DynamicListReducerAction,
  DynamicListReducerActionType,
  DynamicListReducerState,
} from './DynamicListReducer.types';

export const DynamicListReducer = <T extends Data>(
  state: DynamicListReducerState<T>,
  action: DynamicListReducerAction<T>,
): DynamicListReducerState<T> => {
  let { positionPropertyName, allowNewData, maxItemLimit } = state;

  let newItems: T[] = [];

  switch (action.type) {
    case DynamicListReducerActionType.Add:
      newItems = addItem(action.item, state.items, positionPropertyName);
      break;
    case DynamicListReducerActionType.Remove:
      newItems = removeItem(action.item, state.items, positionPropertyName);
      break;
    case DynamicListReducerActionType.Update:
      newItems = removeItem(
        action.currentItem,
        state.items,
        positionPropertyName,
      );
      newItems = addItem(action.newItem, newItems, positionPropertyName);
      break;
    case DynamicListReducerActionType.Reset:
      newItems = action.items;
      positionPropertyName = action.positionPropertyName;
      maxItemLimit = action.maxItemLimit;
      allowNewData = action.allowNewData;
      break;
    default:
      throw new Error();
  }

  // Init function can also be used as a refresher. This re-orders the items and re-calculates the next position and canAddItems
  return DynamicListReducerInit({
    initialValue: newItems,
    positionPropertyName,
    maxItemLimit,
    allowNewData,
  });
};
