import {
  handleRequest,
  handleResponse,
  handleAddResponse,
  handleUpdateResponse,
  handleDeleteResponse,
} from 'store/utils/reducers';
import produce from 'immer';
import { StoreAction } from 'store/utils/actions';
import { handlePagesCompletion, handlePagesSearch } from 'store/utils/adminHelpers';
import actions from './actions';

interface CmsState {
  pages: Record<string, any>;
  search: Record<string, any>;
  copy: any;
}

export const initialState: CmsState = {
  pages: null,
  copy: null,
  search: null,
};

const treatList = (item: Record<string, any>): Record<string, any> => {
  const newItem = { ...item };

  return newItem;
};

/**
 * @param {boolean} options.forceClose - force item to be closed
 * @param {string} options.filter - filter to apply (hide or not elements)
 */
const handleSearch = (draft, options) => {
  options = options || {};
  options.key = 'pages';
  handlePagesSearch(draft, options);
};

const reducer = (state: CmsState = initialState, action: StoreAction): CmsState =>
  produce(
    state,
    (draft: CmsState): CmsState => {
      switch (action.type) {
        case actions.list.request.constant: {
          // reset for first call
          const reset = action.payload && action.payload.reset;
          // force close can be given
          const forceClose = action.payload && action.payload.forceClose;

          draft.currentActive = action.payload && action.payload.currentActive;
          handleRequest(draft, action, 'pages', reset);

          draft.pages.forceClose = forceClose;
          break;
        }

        case actions.list.result.constant: {
          const currentSearch = draft.search && draft.search.filter;
          const forceClose = draft.pages.forceClose;

          handleResponse(draft, action, 'pages');

          handleSearch(draft, {
            forceClose,
            filter: currentSearch,
          });
          handlePagesCompletion(draft.pages.data);
          break;
        }

        case actions.add.result.constant:
          handleAddResponse(draft, action, 'pages', treatList);
          break;
        case actions.update.result.constant: {
          const currentSearch = draft.search && draft.search.filter;
          handleUpdateResponse(draft, action, 'pages', treatList);
          handleSearch(draft, {
            filter: currentSearch,
          });
          handlePagesCompletion(draft.pages.data);
          break;
        }
        case actions.search.constant:
          handleSearch(draft, {
            filter: action.payload,
            forceClose: !action.payload,
          });
          break;
        case actions.delete.result.constant:
          handleDeleteResponse(draft, action, 'pages');
          break;
        case actions.copyContent.constant:
          draft.copy = action.payload;
          break;
        default:
      }
    },
  );

export default reducer;
