import { StoreAction } from 'store/utils/actions';
import produce from 'immer';
import { handleRequest, handleResponse } from 'store/utils/reducers';
import auth from 'store/auth';
import _ from 'lodash';
import actions from './actions';

interface BlogState {
  articles: {} | null;
  categories: {} | null;
  authors: {} | null;
  detail: {} | null;
}

export const initialState: BlogState = {
  articles: null,
  categories: null,
  authors: null,
  detail: null,
};

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

  return newItem;
};

const reducer = (state: BlogState = initialState, action: StoreAction): BlogState =>
  produce(
    state,
    (draft): BlogState => {
      let key;
      let resource;
      switch (action.type) {
        // Load
        case actions.load.request.constant:
          if (action.payload.resource) handleRequest(draft, action, action.payload.resource, true);
          break;
        case actions.load.result.constant:
          key = Object.keys(action.payload);
          action.payload = action.payload[key[0]];
          resource = key[0].split('GetMany').shift();
          handleResponse(draft, action, resource, treatList);
          break;
        // Load One
        case actions.loadOne.request.constant:
          if (state.detail && state.detail.data) {
            if (action.payload.apiInput.id === state.detail.data._id) {
              draft.loading = true;
            } else {
              handleRequest(draft, action, 'detail');
            }
          } else {
            handleRequest(draft, action, 'detail');
          }
          break;
        case actions.loadOne.result.constant:
          if (state.detail && state.detail.data) {
            if (action.payload._id && action.payload._id === state.detail.data._id) {
              draft.detail.data = { ...state.detail.data, ...action.payload };
              draft.detail.loading = false;
            } else {
              handleResponse(draft, action, 'detail');
            }
          } else {
            handleResponse(draft, action, 'detail');
          }
          break;
        // Add
        // Edit
        case actions.edit.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        // Publish / UnPublish
        case actions.publish.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case actions.unpublish.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        // Delete
        case actions.delete.request.constant:
          if (action.payload.resource) {
            resource = action.payload.resource;
            draft[resource].data = _.filter(state[resource].data, e => e._id !== action.payload.id);
          }
          break;
        case actions.loadPermission.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case actions.removePermission.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case actions.addPermission.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case auth.actions.logout.result.constant:
          draft.list = null;
          draft.detail = null;
          break;
        default:
      }
    },
  );

export default reducer;
