import { Action, handleActions } from "redux-actions";
import {
  createExperience1To1Actions,
  getExperiencesActions,
  updateExperience1To1Actions,
  updateExperienceProcessStatusActions,
  updateStagingCoversActions,
  getExperienceByIdActions,
  createExperienceActions,
  publishExperienceActions,
  updateProductImagesActions,
  createExperienceLiveClassActions,
  updateExperienceLiveClassActions,
  createExclusiveContentActions,
  updateExclusiveContentActions,
  updateLessonsActions,
  updateAttachmentsActions,
  createExperienceCourseActions,
  updateExperienceCourseActions,
  createExperienceInteractiveLiveClassActions,
  updateExperienceInteractiveLiveClassActions,
  updateExperienceActions,
  updateExperienceBundleActions,
  createExperienceBundleActions,
} from "./actions";
import { ExperienceState, EXPERIENCE_PROCESS_STATUS } from "./types";

const handlers = {
  // get experiences
  [getExperiencesActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    updateSuccess: false,
    loading: true,
    experience: null,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.EMPTY,
  }),
  [getExperiencesActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experience: {
      ...payload,
    },
    error: null,
    loading: false,
  }),
  [getExperiencesActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
  }),
  // get experience by id
  [getExperienceByIdActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    experienceDetail: null,
    error: null,
    loading: true,
  }),
  [getExperienceByIdActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    fetchExperienceDetail: payload,
    loading: false,
  }),
  [getExperienceByIdActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
  }),
  // create experience
  [createExperienceActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    ...payload,
  }),
  // create experience 1 to 1
  [createExperience1To1Actions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExperience1To1Actions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExperience1To1Actions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // update experience 1 to 1
  [updateExperience1To1Actions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExperienceActions.REQUEST]: (
    state: ExperienceState,
    { payload: { id } }: Action<any>
  ): ExperienceState => ({
    ...state,
    updatingId: id,
    updateSuccess: false,
    error: null,
    loading: true,
  }),
  [updateExperienceActions.SUCCESS]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    updatingId: undefined,
    updateSuccess: true,
    error: null,
    loading: false,
  }),
  [updateExperienceActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    updatingId: undefined,
    updateSuccess: false,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  [updateExperience1To1Actions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExperience1To1Actions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // create experience Live Broadcasts
  [createExperienceLiveClassActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExperienceLiveClassActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExperienceLiveClassActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // update experience Live Broadcasts
  [updateExperienceLiveClassActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExperienceLiveClassActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExperienceLiveClassActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // create experience Interactive Live Class
  [createExperienceInteractiveLiveClassActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExperienceInteractiveLiveClassActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExperienceInteractiveLiveClassActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // update experience interactive live class
  [updateExperienceInteractiveLiveClassActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExperienceInteractiveLiveClassActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExperienceInteractiveLiveClassActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // create experience exclusive content
  [createExclusiveContentActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExclusiveContentActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExclusiveContentActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),

  // update experience exclusive content
  [updateExclusiveContentActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExclusiveContentActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExclusiveContentActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),

  // create experience bundle
  [createExperienceBundleActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExperienceBundleActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExperienceBundleActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),

  // update experience bundle
  [updateExperienceBundleActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExperienceBundleActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExperienceBundleActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),

  // update experience process status
  [updateExperienceProcessStatusActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    contentProcessStatus: payload,
  }),

  // update photos and videos of experience
  [updateStagingCoversActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => {
    let stagingCovers = state.stagingCovers;

    if (payload?.uploadItemIndex) {
      stagingCovers = {
        ...stagingCovers,
        [payload.uploadItemIndex]:
          stagingCovers &&
          stagingCovers[payload.uploadItemIndex] &&
          payload.photo.percent
            ? { ...stagingCovers[payload.uploadItemIndex], ...payload.photo }
            : payload.photo,
      };
    } else {
      Object.keys(stagingCovers).map((key) => {
        stagingCovers[key] = { id: stagingCovers[key].id };
        return null;
      });
    }
    return {
      ...state,
      stagingCovers,
    };
  },

  // create experience course
  [createExperienceCourseActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [createExperienceCourseActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.CREATED,
  }),
  [createExperienceCourseActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // update experience exclusive content
  [updateExperienceCourseActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    error: null,
    loading: true,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
  }),
  [updateExperienceCourseActions.SUCCESS]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    experienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    fetchExperienceDetail: {
      ...payload,
      isBooked: state?.experienceDetail?.isBooked || false,
    },
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.UPDATED,
    loading: false,
  }),
  [updateExperienceCourseActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    error: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
  // update experience process status
  [updateExperienceProcessStatusActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    contentProcessStatus: payload,
  }),

  // update photos product images
  [updateProductImagesActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => {
    let productImages = state.productImages;

    if (payload?.uploadItemIndex) {
      productImages = {
        ...productImages,
        [payload.uploadItemIndex]: payload.photo,
      };
    } else {
      Object.keys(productImages).map((key) => {
        productImages[key] = { id: productImages[key].id };
        return null;
      });
    }
    return {
      ...state,
      productImages,
    };
  },
  // update lessons list
  [updateLessonsActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => {
    let lessons = state.lessons;

    if (payload?.uploadItemIndex) {
      lessons = {
        ...lessons,
        [payload.uploadItemIndex]:
          lessons && lessons[payload.uploadItemIndex] && payload.photo.percent
            ? { ...lessons[payload.uploadItemIndex], ...payload.photo }
            : payload.photo,
      };
    } else {
      Object.keys(lessons).map((key) => {
        lessons[key] = { id: lessons[key].id };
        return null;
      });
    }
    return {
      ...state,
      lessons,
    };
  },
  // update attachments list
  [updateAttachmentsActions.REQUEST]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => {
    let attachments = state.attachments;

    if (payload?.uploadItemIndex) {
      attachments = {
        ...attachments,
        [payload.uploadItemIndex]:
          attachments &&
          attachments[payload.uploadItemIndex] &&
          payload.photo.percent
            ? { ...attachments[payload.uploadItemIndex], ...payload.photo }
            : payload.photo,
      };
    } else {
      Object.keys(attachments).map((key) => {
        attachments[key] = { id: attachments[key].id };
        return null;
      });
    }
    return {
      ...state,
      attachments,
    };
  },
  [publishExperienceActions.REQUEST]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUESTING,
    error: null,
    publishError: null,
    loading: true,
  }),
  [publishExperienceActions.SUCCESS]: (
    state: ExperienceState
  ): ExperienceState => ({
    ...state,
    publishError: null,
    error: null,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.PUBLISHED,
    loading: false,
  }),
  [publishExperienceActions.FAILURE]: (
    state: ExperienceState,
    { payload }: Action<any>
  ): ExperienceState => ({
    ...state,
    publishError: payload,
    loading: false,
    contentProcessStatus: EXPERIENCE_PROCESS_STATUS.REQUEST_FAIL,
  }),
};

const initialState: ExperienceState = {
  error: null,
  loading: false,
  experience: null,
  experienceDetail: null,
  fetchExperienceDetail: null,
  stagingCovers: {},
  productImages: {},
  attachments: {},
  lessons: {},
  contentProcessStatus: EXPERIENCE_PROCESS_STATUS.EMPTY,
};

export const experienceReducer = handleActions<ExperienceState>(
  handlers,
  initialState
);
