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 EventState {
  detail: {} | null;
  speakers: {} | null;
  partners: {} | null;
  venues: {} | null;
  events: {} | null;
  tickets: {} | null;
}

export const initialState: EventState = {
  detail: null,
  speakers: null,
  partners: null,
  venues: null,
  events: null,
  tickets: null,
};

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

  return newItem;
};

const reducer = (state: EventState = initialState, action: StoreAction): EventState =>
  produce(
    state,
    (draft): EventState => {
      let key;
      let index;
      let resource;
      switch (action.type) {
        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;
        case actions.edit.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          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;
        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;
        // PARTICIPANT
        case actions.participant.load.result.constant:
          if (state.detail && state.detail.data) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case actions.participant.add.result.constant:
          if (state.detail && state.detail.data && state.detail.data.getParticipants) {
            draft.detail.data.getParticipants = [
              ...state.detail.data.getParticipants,
              action.payload,
            ];
          }
          break;
        case actions.participant.remove.result.constant:
          if (state.detail && state.detail.data && state.detail.data.getParticipants) {
            index = state.detail.data.getParticipants.findIndex(e => e._id === action.payload._id);
            if (index !== -1) draft.detail.data.getParticipants.splice(index, 1);
          }
          break;
        case actions.participant.markAsParticipate.result.constant:
          if (Array.isArray(action.payload)) {
            for (let i = 0; i < action.payload.length; i++) {
              const element = action.payload[i];
              index = state.detail.data.getParticipants.findIndex(e => e._id === element._id);
              if (index !== -1) draft.detail.data.getParticipants[index] = element;
            }
          }
          break;
        case actions.participant.sendAttestation.result.constant:
          if (Array.isArray(action.payload)) {
            for (let i = 0; i < action.payload.length; i++) {
              const element = action.payload[i];
              index = state.detail.data.getParticipants.findIndex(e => e._id === element._id);
              if (index !== -1) draft.detail.data.getParticipants[index] = element;
            }
          }
          break;
        case actions.participant.cancelParticipation.result.constant:
          if (Array.isArray(action.payload)) {
            for (let i = 0; i < action.payload.length; i++) {
              const element = action.payload[i];
              index = state.detail.data.getParticipants.findIndex(e => e._id === element._id);
              if (index !== -1) draft.detail.data.getParticipants[index] = element;
            }
          }
          break;
        // EVENT
        case actions.event.publish.result.constant:
          if (action.payload) {
            draft.detail.data = { ...state.detail.data, ...action.payload };
          }
          break;
        case actions.event.unpublish.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;
