import isEmpty from "lodash/isEmpty";
import omit from "lodash/omit";
import { v4 as uuidv4 } from "uuid";

import {
  TalentModuleMixItem,
  TalentProfileModule,
} from "models/talent/talent-profile-module.model";
import { updateTalentProfileActions } from "pages/BecomeATalent/Reducer/action";
import { Action, handleActions } from "redux-actions";
import { signupTalentActions, signupTalentTypes } from "redux/Talent/actions";
import { ArrayServices } from "utils/array";
import { JSONService } from "utils/json-patch";
import {
  addTalentProfileModuleType,
  authorizationTokenCalendarProviderActions,
  autoSaveProfileActions,
  autoSaveProfileType,
  cancelInviteCollaboratorActions,
  checkUserExistedActions,
  checkUserExistedTypes,
  connectCalendarProviderActions,
  createTalentProfileModuleActions,
  createTalentProfileModuleTypes,
  deleteLocalizationActions,
  deleteTalentProfileModuleActions,
  deleteTalentProfileModuleTypes,
  detectLocalCurrencyActions,
  disconnectCalendarProviderActions,
  forceSaveAndpublishProfileActions,
  getAnalyticsLocalizationModulesActions,
  getAvailabilityCalendarsActions,
  getCollaboratorInvitationsActions,
  getCollaboratorInvitationsTypes,
  getCollaboratorProfileActions,
  getCollaboratorProfileTypes,
  getExchangeRateActions,
  getExchangeRateUSDActions,
  getLocalizationModulesActions,
  getTalentAnalyticActions,
  getTalentAnalyticMonthlyActions,
  getTalentAnalyticMonthlyTypes,
  getTalentAnalyticTypes,
  getUserProfileActions,
  getUserProfileTypes,
  inviteCollaboratorActions,
  logoutActions,
  logoutTypes,
  publishProfileActions,
  publishProfileType,
  removeProfileGalleryActions,
  removeTalentProfileModuleType,
  removeTempTalentImageActions,
  resendInviteCollaboratorActions,
  resetUserActionType,
  revertTalentProfileModuleType,
  revertTalentProfileType,
  revokeInviteCollaboratorActions,
  sendEmailOTPActions,
  sendEmailOTPTypes,
  sendOTPActions,
  sendOTPTypes,
  setIsBlockingEditType,
  setIsPublishedType,
  setLoadingAutoSaveType,
  setLocalizationSelectedType,
  setLocalizationUnpublishIdsType,
  setPreviosModuleVersionType,
  setTalentProfileModuleListType,
  setTalentProfileModulesOriginType,
  setTalentProfileModuleType,
  setTalentProfileType,
  setUploadingProductsType,
  setUserCustomerActions,
  setUserCustomerType,
  setUserValueType,
  updateCollaboratorProfileActions,
  updateCollaboratorProfileTypes,
  updatePasswordActions,
  updatePasswordTypes,
  updateProfileGalleryActions,
  updateTalentProfileModuleActions,
  updateTalentProfileModuleTypes,
  updateTalentProfileTypes,
  updateTalentRevertType,
  updateTempTalentImagesActions,
  updateUserProfileActions,
  updateUserProfileTypes,
} from "./actions";
import {
  CALENDAR_PROVIDERS,
  STATUS_CALENDAR_PROVIDERS,
  TalentImageTypes,
  TempImage,
  UserState,
} from "./types";

const handlers = {
  [resetUserActionType]: (state: UserState): UserState => ({
    ...state,
    type: null,
  }),

  [setLocalizationUnpublishIdsType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    localizationUnpublishIds: payload,
  }),

  [setLocalizationSelectedType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    localizationSelected: payload,
  }),

  [setUserValueType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    ...payload,
  }),
  // logout
  [logoutActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    type: null,
    loading: true,
  }),
  [logoutActions.SUCCESS]: (state: UserState): UserState => ({
    ...state,
    user: undefined,
    collaborator: undefined,
    loading: false,
    type: logoutTypes.SUCCESS,
  }),
  [logoutActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: logoutTypes.FAILURE,
  }),
  // get user by id
  [getUserProfileActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    type: null,
    loading: true,
  }),
  [getUserProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const isPublished = !payload.talentProfile?.localizationActive
      ? !payload.talentProfile?.versions?.length
      : !payload.talentProfile?.versions?.length &&
        !payload.talentProfile?.localizations?.some(
          (el: any) => !el.isPublished
        );
    return {
      ...state,
      user: {
        ...payload,
        talentProfile: {
          ...payload.talentProfile,
          ...payload.talentProfile?.versions?.[0]?.profile,
        },
        previousVersionTalentProfile: {
          ...payload.talentProfile,
          ...payload.talentProfile?.versions?.[0]?.profile,
        },
      },
      isPublished,
      type: getUserProfileTypes.SUCCESS,
      isAutoSaved: !!payload.talentProfile?.versions?.length,
      isAdminLogin: payload.isAdminLogin,
      loading: false,
    };
  },
  [getUserProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    type: getUserProfileTypes.FAILURE,
    loading: false,
  }),

  // get collaborator profile
  [getCollaboratorProfileActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    isCollaborator: true,
    error: null,
    type: null,
  }),
  [getCollaboratorProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    collaborator: payload,
    type: getCollaboratorProfileTypes.SUCCESS,
  }),
  [getCollaboratorProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    type: getCollaboratorProfileTypes.FAILURE,
  }),

  // update profile gallery
  [updateProfileGalleryActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    let gallery = state.gallery;

    gallery = {
      ...gallery,
      [payload.uploadItemIndex]:
        gallery && gallery[payload.uploadItemIndex] && payload.photo.percent
          ? { ...gallery[payload.uploadItemIndex], ...payload.photo }
          : payload.photo,
    };

    return {
      ...state,
      gallery,
    };
  },
  [removeProfileGalleryActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    gallery: omit(state.gallery, payload.uploadItemIndex),
  }),

  // set talent profile
  [setTalentProfileType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    user: {
      ...state.user,
      talentProfile: {
        ...state.user?.talentProfile,
        // profileUpdated is set to false on save
        // in onSaveProfile() in AutoSaveProvider.tsx
        ...{ ...payload, profileUpdated: true },
      },
    },
    loading: false,
  }),

  // revert talent profile
  [revertTalentProfileType]: (state: UserState): UserState => ({
    ...state,
    user: {
      ...state.user,
      talentProfile: {
        ...state.user?.talentProfileOrigin,
      },
    },
    loading: false,
    talentRevert: true,
  }),

  // update talent revert
  [updateTalentRevertType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    talentRevert: payload,
  }),

  // update talent profile
  [updateTalentProfileActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: payload.facebookPixels ? false : true,
      type: null,
    };
  },
  [updateTalentProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const talentProfile = omit(payload.talentProfile, [
      "avatar",
      "displayName",
      "displayNameImage",
      "displayNameImageScale",
      "displayNameType",
      "showDisplayName",
      "modules",
      "socialProfileLinks",
      "themeColor",
      "themeType",
      "versions",
    ]);

    const localizationUpdate = JSONService.getPatch(
      talentProfile.localizations,
      state.user?.talentProfile?.localizations,
      {
        actions: ["add", "remove"],
      }
    );
    const isLocalizationUpdate = !isEmpty(localizationUpdate);
    let newLocalizationsIds = state.localizationUnpublishIds;
    if (isLocalizationUpdate) {
      newLocalizationsIds = state.localizationUnpublishIds?.filter(
        (item: any) =>
          item === null ||
          talentProfile.localizations.some((value: any) => value.id === item)
      );
    }
    const isPublished = !talentProfile?.localizationActive
      ? !payload?.talentProfile?.versions?.length &&
        !state.localizationUnpublishIds?.includes(null)
      : !talentProfile.localizations.some((el: any) => !el.isPublished) &&
        !payload?.talentProfile?.versions?.length &&
        !newLocalizationsIds?.length;

    return {
      ...state,
      isPublished,
      localizationUnpublishIds: newLocalizationsIds,
      user: {
        ...state.user,
        ...payload,
        talentProfile: {
          ...state.user?.talentProfile,
          ...talentProfile,
        },
        talentProfileOrigin: {
          ...state.user?.talentProfile,
          ...talentProfile,
        },
      },
      loading: false,
      type: updateTalentProfileTypes.SUCCESS,
    };
  },
  [updateTalentProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: updateTalentProfileTypes.FAILURE,
  }),
  // sign up talent
  [signupTalentActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: null,
  }),
  [signupTalentActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    user: {
      ...state.user,
      talentProfile: {
        ...state.user?.talentProfile,
        ...payload,
      },
      talentProfileOrigin: {
        ...state.user?.talentProfile,
        ...payload,
      },
    },
    isCheckLocalCurrency: false,
    loading: false,
    type: signupTalentTypes.SUCCESS,
  }),
  [signupTalentActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: signupTalentTypes.FAILURE,
  }),
  [updateTempTalentImagesActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const data: TempImage | null = state.tempTalentImages;
    if (!payload.url) return state;

    switch (payload.type as TalentImageTypes) {
      case TalentImageTypes.AVATAR:
        data[TalentImageTypes.AVATAR] = payload.url;
        break;
      case TalentImageTypes.COVERS:
        if (data[TalentImageTypes.COVERS])
          data[TalentImageTypes.COVERS]?.push(payload.url);
        else data[TalentImageTypes.COVERS] = [payload.url];
        break;
    }

    return {
      ...state,
      tempTalentImages: {
        ...data,
      },
    };
  },
  [removeTempTalentImageActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const data: TempImage | null = state.tempTalentImages;

    switch (payload?.type as TalentImageTypes) {
      case TalentImageTypes.AVATAR:
        data[TalentImageTypes.AVATAR] = null;
        break;
      case TalentImageTypes.COVERS:
        data[TalentImageTypes.COVERS] =
          data[TalentImageTypes.COVERS]?.filter(
            (value, index) => index + 1 !== payload.id
          ) || null;
        break;
    }

    return {
      ...state,
      tempTalentImages: {
        ...data,
      },
    };
  },
  // update password
  [updatePasswordActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    password: null,
    loading: true,
    type: updatePasswordTypes.REQUEST,
  }),
  [updatePasswordActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    password: payload,
    loading: false,
    type: updatePasswordTypes.SUCCESS,
  }),
  [updatePasswordActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: updatePasswordTypes.FAILURE,
  }),
  // get talent analytics
  [getTalentAnalyticActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    type: null,
    loading: true,
  }),
  [getTalentAnalyticActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    analytic: payload,
    loading: false,
    type: getTalentAnalyticTypes.SUCCESS,
  }),
  [getTalentAnalyticActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: getTalentAnalyticTypes.FAILURE,
  }),

  // get talent analytics monthly
  [getTalentAnalyticMonthlyActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    type: null,
    loading: true,
  }),
  [getTalentAnalyticMonthlyActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    analyticMonthly: payload,
    loading: false,
    type: getTalentAnalyticMonthlyTypes.SUCCESS,
  }),
  [getTalentAnalyticMonthlyActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: getTalentAnalyticMonthlyTypes.FAILURE,
  }),

  // get availability calendar
  [getAvailabilityCalendarsActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
  }),

  [getAvailabilityCalendarsActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const calendars: any = {};

    payload?.forEach((value: any) => {
      calendars[value?.providerName] = true;
    });

    let fetchAvalabilityCalendars: any = {};

    Object.keys(CALENDAR_PROVIDERS).map((key) => {
      const provider = (CALENDAR_PROVIDERS as any)[key];

      fetchAvalabilityCalendars = {
        ...fetchAvalabilityCalendars,
        [provider]: calendars[provider]
          ? STATUS_CALENDAR_PROVIDERS.CONNECT
          : STATUS_CALENDAR_PROVIDERS.IDEAL,
      };
    });

    return {
      ...state,
      avalabilityCalendar: fetchAvalabilityCalendars,
      loading: false,
    };
  },

  [getAvailabilityCalendarsActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
  }),

  [connectCalendarProviderActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    errorConnectCalendar: null,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload?.provider_name]: STATUS_CALENDAR_PROVIDERS.IN_PROGRESS,
    },
  }),

  [connectCalendarProviderActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    errorConnectCalendar: payload,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    },
  }),

  [disconnectCalendarProviderActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    errorConnectCalendar: null,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.IN_PROGRESS,
    },
  }),
  [disconnectCalendarProviderActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    },
  }),
  [disconnectCalendarProviderActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.CONNECT,
    },
  }),

  [authorizationTokenCalendarProviderActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: null,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload?.provider]: STATUS_CALENDAR_PROVIDERS.IN_PROGRESS,
    },
  }),
  [authorizationTokenCalendarProviderActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: null,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.CONNECT,
    },
  }),
  [authorizationTokenCalendarProviderActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: null,
    avalabilityCalendar: {
      ...state.avalabilityCalendar,
      [payload]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    },
  }),
  // send phone number otp
  [sendOTPActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: sendOTPTypes.REQUEST,
  }),
  [sendOTPActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    phoneOTP: payload,
    loading: false,
    type: sendOTPTypes.SUCCESS,
  }),
  [sendOTPActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: sendOTPTypes.FAILURE,
  }),
  // send email OTP
  [sendEmailOTPActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: sendEmailOTPTypes.REQUEST,
  }),
  [sendEmailOTPActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    emailOTP: payload,
    loading: false,
    type: sendEmailOTPTypes.SUCCESS,
  }),
  [sendEmailOTPActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: sendEmailOTPTypes.FAILURE,
  }),
  // check user existed
  [checkUserExistedActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: null,
  }),
  [checkUserExistedActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    loading: false,
    isUserExisted: payload?.isExisted,
    type: checkUserExistedTypes.SUCCESS,
  }),
  [checkUserExistedActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: checkUserExistedTypes.FAILURE,
  }),

  // get exchange rates
  [getExchangeRateActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      exchangeRates: undefined,
    };
  },
  [getExchangeRateActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      exchangeRates: payload,
    };
  },
  [getExchangeRateActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
    };
  },

  // get exchange rates USD
  [getExchangeRateUSDActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      exchangeRatesUSD: undefined,
    };
  },
  [getExchangeRateUSDActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      exchangeRatesUSD: payload,
    };
  },
  [getExchangeRateUSDActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
    };
  },

  // detect local currency
  [detectLocalCurrencyActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      isCheckLocalCurrency: null,
    };
  },
  [detectLocalCurrencyActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      isCheckLocalCurrency: payload,
    };
  },
  [detectLocalCurrencyActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
    };
  },

  // create talent profile module
  [createTalentProfileModuleActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      type: null,
      error: null,
      talentProfileModules: ArrayServices.updateWithField(
        state.talentProfileModules || [],
        "order",
        payload.order,
        { ...payload, isLoading: true, isCreate: false }
      ),
    };
  },
  [createTalentProfileModuleActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      talentProfileModules: ArrayServices.updateWithField(
        state.talentProfileModules || [],
        "order",
        payload.order,
        { ...payload, isLoading: false }
      ),
      talentProfileModulesOrigin: ArrayServices.updateWithField(
        state.talentProfileModulesOrigin || [],
        "order",
        payload.order,
        { ...payload, isLoading: false }
      ),
      type: createTalentProfileModuleTypes.SUCCESS,
    };
  },
  [createTalentProfileModuleActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const { error, item } = payload;
    return {
      ...state,
      error: error,
      loading: false,
      talentProfileModules: ArrayServices.updateWithField(
        state.talentProfileModules || [],
        "order",
        item.order,
        { ...item, isLoading: false }
      ),
      type: createTalentProfileModuleTypes.FAILURE,
    };
  },

  // update talent profile module
  [updateTalentProfileModuleActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      talentProfileModules: ArrayServices.updateWithId(
        state.talentProfileModules || [],
        payload.id,
        { ...payload, isLoading: true, isUpdate: false }
      ),
      type: null,
    };
  },
  [updateTalentProfileModuleActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      talentProfileModules: ArrayServices.updateWithId(
        state.talentProfileModules || [],
        payload.id,
        { ...payload, isLoading: false }
      ),
      talentProfileModulesOrigin: ArrayServices.updateWithId(
        state.talentProfileModulesOrigin || [],
        payload.id,
        { ...payload, isLoading: false }
      ),
      type: updateTalentProfileModuleTypes.SUCCESS,
    };
  },
  [updateTalentProfileModuleActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const { error, item } = payload;
    return {
      ...state,
      error: error,
      loading: false,
      talentProfileModules: ArrayServices.updateWithId(
        state.talentProfileModules || [],
        item.id,
        { ...item, isLoading: false }
      ),
      type: updateTalentProfileModuleTypes.FAILURE,
    };
  },

  // delete talent profile module
  [deleteTalentProfileModuleActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      talentProfileModules: ArrayServices.updateWithId(
        state.talentProfileModules || [],
        payload.id,
        { ...payload, isLoading: true }
      ),
      type: null,
    };
  },
  [deleteTalentProfileModuleActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      talentProfileModules: ArrayServices.removeWithId(
        state.talentProfileModules || [],
        payload.id
      ),
      talentProfileModulesOrigin: ArrayServices.removeWithId(
        state.talentProfileModulesOrigin || [],
        payload.id
      ),
      type: deleteTalentProfileModuleTypes.SUCCESS,
    };
  },
  [deleteTalentProfileModuleActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
      type: deleteTalentProfileModuleTypes.FAILURE,
    };
  },

  // set talent profile module list
  [setTalentProfileModuleListType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const newState = { ...state };

    // If localization is active and the flag is enabled, queue up the modules for insertion
    if (payload.insertAfterLocalization &&
        state.localizationSelected?.active &&
        payload.modules) {
      newState.queuedModules = payload.modules.map(
        (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
          ...module,
          order: index,
        })
      );
    }

    if (payload.modules) {
      newState.talentProfileModules = payload.modules.map(
        (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
          ...module,
          order: index,
        })
      );
    }
    if (payload.prevModules) {
      newState.previousModulesVersion = payload.prevModules.map(
        (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
          ...module,
          order: index,
        })
      );
    }
    if (payload.defaultModules) {
      newState.defaultModulesVersion = payload.defaultModules.map(
        (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
          ...module,
          order: index,
        })
      );
    }
    return newState;
  },

  // set talent profile module list
  [setTalentProfileModulesOriginType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      talentProfileModulesOrigin: payload.map(
        (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
          ...module,
          order: index,
        })
      ),
    };
  },

  // set talent profile module
  [setTalentProfileModuleType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      talentProfileModules: ArrayServices.updateWithField(
        state.talentProfileModules || [],
        "order",
        payload.order,
        payload
      ),
    };
  },

  // revert talent profile module
  [revertTalentProfileModuleType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const moduleOrigin = state.talentProfileModulesOrigin?.[payload.order];
    return {
      ...state,
      talentProfileModules: ArrayServices.updateWithField(
        state.talentProfileModules || [],
        "order",
        payload.order,
        moduleOrigin as TalentProfileModule<TalentModuleMixItem>
      ),
    };
  },

  // add talent profile module
  [addTalentProfileModuleType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      talentProfileModules: ArrayServices.append(
        state.talentProfileModules || [],
        payload
      ),
    };
  },

  // remove talent profile module
  [removeTalentProfileModuleType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      talentProfileModules: ArrayServices.removeWithField(
        state.talentProfileModules || [],
        "order",
        payload.order
      ),
    };
  },

  // get talent collaborator
  [getCollaboratorInvitationsActions.REQUEST]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      type: null,
    };
  },
  [getCollaboratorInvitationsActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      talentCollaborators: payload,
      type: getCollaboratorInvitationsTypes.SUCCESS,
    };
  },
  [getCollaboratorInvitationsActions.FAILURE]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      type: getCollaboratorInvitationsTypes.FAILURE,
    };
  },

  // invite talent collaborator
  [inviteCollaboratorActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      type: null,
    };
  },
  [inviteCollaboratorActions.SUCCESS]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      type: inviteCollaboratorActions.SUCCESS,
    };
  },
  [inviteCollaboratorActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
      type: inviteCollaboratorActions.FAILURE,
    };
  },

  // cancel talent collaborator
  [cancelInviteCollaboratorActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      type: null,
    };
  },

  // revoke talent collaborator
  [cancelInviteCollaboratorActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
      type: cancelInviteCollaboratorActions.FAILURE,
    };
  },
  [revokeInviteCollaboratorActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
      type: null,
    };
  },
  [revokeInviteCollaboratorActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
      type: revokeInviteCollaboratorActions.FAILURE,
    };
  },

  // resend talent collaborator

  [resendInviteCollaboratorActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: true,
    };
  },

  [resendInviteCollaboratorActions.SUCCESS]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loading: false,
      type: resendInviteCollaboratorActions.SUCCESS,
    };
  },

  [resendInviteCollaboratorActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loading: false,
      type: resendInviteCollaboratorActions.FAILURE,
    };
  },

  // update collaborator profile
  [updateCollaboratorProfileActions.REQUEST]: (
    state: UserState
  ): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: null,
  }),
  [updateCollaboratorProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    collaborator: {
      ...state.collaborator,
      ...payload,
    },
    loading: false,
    type: updateCollaboratorProfileTypes.SUCCESS,
  }),
  [updateCollaboratorProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: updateCollaboratorProfileTypes.FAILURE,
  }),

  // update user profile
  [updateUserProfileActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: null,
  }),
  [updateUserProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    user: {
      ...state.user,
      ...payload,
      talentProfile: {
        ...state.user?.talentProfile,
      },
    },
    loading: false,
    type: updateUserProfileTypes.SUCCESS,
  }),
  [updateUserProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: updateUserProfileTypes.FAILURE,
  }),
  // publish talent profile
  [publishProfileActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loadingPublish: true,
      type: null,
    };
  },
  [publishProfileActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const { localizationId } = payload;
    const isDefaultUpdated = localizationId.includes(null);
    const currentIds = state.localizationUnpublishIds?.filter(
      (item) => !localizationId.includes(item)
    );
    const newLocalizations = [
      ...(state.user?.talentProfile?.localizations || []),
    ]?.map((item) => {
      const isUpdated = localizationId.includes(item.id);
      return {
        ...item,
        isPublished: isUpdated ? true : item.isPublished,
        active: isUpdated ? true : item.active,
        isFirstTimePublished: isUpdated ? true : item.isFirstTimePublished,
      };
    });

    const versions = isDefaultUpdated
      ? []
      : state.user?.talentProfile?.versions;

    const isPublished = !state.user?.talentProfile?.localizationActive
      ? true
      : !newLocalizations.some((el) => !el.isPublished) &&
        !versions?.length &&
        !currentIds?.length;

    return {
      ...state,
      loadingPublish: false,
      isPublished,
      type: publishProfileType.SUCCESS,
      localizationUnpublishIds: currentIds,
      user: {
        ...state.user,        
        emailVerified: true,
        talentProfile: {
          ...state.user?.talentProfile,
          modules: state.talentProfileModules,
          versions: versions,
          localizations: newLocalizations,
        },
      },
    };
  },

  [publishProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const { error } = payload;
    return {
      ...state,
      error: error,
      loadingPublish: false,
      type: publishProfileType.FAILURE,
    };
  },

  // auto save talent profile
  [autoSaveProfileActions.REQUEST]: (state: UserState): UserState => {
    return {
      ...state,
      error: null,
      loadingAutoSave: true,
      isAutoSaved: false,
      type: null,
    };
  },

  [autoSaveProfileActions.SUCCESS]: (
    state: UserState,
    { payload: { currentVersion, previousVersion } }: Action<any>
  ): UserState => {
    const newState = {
      ...state,
      loadingAutoSave: false,
      uploadingProducts: false,
      isAutoSaved: true,
      type: autoSaveProfileType.SUCCESS,
      previousModulesVersion: previousVersion.modules,
      user: {
        ...state.user,
        talentProfile: {
          ...state.user?.talentProfile,
          ...previousVersion.profile,
        },
        previousVersionTalentProfile: { ...previousVersion?.profile },
      },
    };

    return newState;
  },

  [autoSaveProfileActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const { error } = payload;
    return {
      ...state,
      error: error,
      loadingAutoSave: false,
      uploadingProducts: false,
      isAutoSaved: false,
      type: autoSaveProfileType.FAILURE,
      loading: false,
      user: {
        ...state.user,
        previousVersionTalentProfile: { ...state.user?.talentProfile },
      },
    };
  },

  [setPreviosModuleVersionType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    previousModulesVersion: payload.map(
      (module: TalentProfileModule<TalentModuleMixItem>, index: number) => ({
        ...module,
        order: index,
      })
    ),
  }),

  [setIsPublishedType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    isPublished: payload,
  }),

  [forceSaveAndpublishProfileActions.REQUEST]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      error: null,
      loadingAutoSave: true,
      loadingPublish: true,
      type: null,
    };
  },
  [forceSaveAndpublishProfileActions.FAILURE]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      loadingPublish: false,
      loadingAutoSave: false,
      uploadingProducts: false,
    };
  },
  [setUploadingProductsType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      uploadingProducts: payload,
    };
  },
  [setLoadingAutoSaveType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      loadingAutoSave: payload,
    };
  },
  [setIsBlockingEditType]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      isBlockingEdit: payload,
    };
  },
  [setUserCustomerActions.REQUEST]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      loadingCustomer: true,
    };
  },
  [setUserCustomerActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    loadingCustomer: false,
    customer: payload
  }),
  [setUserCustomerActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: payload,
      loadingCustomer: false,
    };
  },
  // delete localization
  [deleteLocalizationActions.REQUEST]: (state: UserState): UserState => ({
    ...state,
    error: null,
    loading: true,
    type: deleteLocalizationActions.REQUEST,
    previousModulesVersion: [],
    talentProfileModules: [],
  }),
  [deleteLocalizationActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const newLocalizationsIds = state.localizationUnpublishIds?.filter(
      (item: any) => payload.some((value: any) => value.id === item)
    );

    const isPublished = !state.user?.talentProfile?.localizationActive
      ? state.isPublished
      : !payload.some((el: any) => !el.isPublished) &&
        !state.user?.talentProfile?.versions?.length &&
        !newLocalizationsIds?.length;

    return {
      ...state,
      loading: false,
      type: null,
      isPublished,
      localizationUnpublishIds: newLocalizationsIds,
      user: {
        ...state.user,
        talentProfile: {
          ...state.user?.talentProfile,
          localizations: payload,
        },
      },
    };
  },
  [deleteLocalizationActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    loading: false,
    type: deleteLocalizationActions.FAILURE,
  }),

  // get localization modules
  [getLocalizationModulesActions.REQUEST]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    return {
      ...state,
      error: null,
      moduleLoading: payload.loading ? true : payload.loading,
    };
  },
  [getLocalizationModulesActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => {
    const modules = (
      payload.versionModules?.length ? payload.versionModules : payload.modules
    ).map((module: any) => ({ ...module, id: module.id || uuidv4() }));

    if (state.queuedModules?.length) {
      const queuedModules = state.queuedModules
        .filter((module) => modules.every((m: any) => m.id !== module.id))
        .map((module, index) => ({
          ...module,
          order: modules.length + index,
        }));

      modules.push(...queuedModules);
    }

    return {
      ...state,
      moduleLoading: false,
      previousModulesVersion: modules,
      talentProfileModules: modules,
      queuedModules: [],
    };
  },
  [getLocalizationModulesActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    moduleLoading: false,
    type: getLocalizationModulesActions.FAILURE,
  }),

  [getAnalyticsLocalizationModulesActions.REQUEST]: (
    state: UserState
  ): UserState => {
    return {
      ...state,
      error: null,
    };
  },
  [getAnalyticsLocalizationModulesActions.SUCCESS]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    analyticsProfileModules: payload.versionModules?.length
      ? payload.versionModules
      : payload.modules,
  }),
  [getAnalyticsLocalizationModulesActions.FAILURE]: (
    state: UserState,
    { payload }: Action<any>
  ): UserState => ({
    ...state,
    error: payload,
    type: getAnalyticsLocalizationModulesActions.FAILURE,
  }),
};

const initialState: UserState = {
  error: null,
  type: null,
  loading: true,
  moduleLoading: false,
  uploadingProducts: false,
  loadingAutoSave: false,
  loadingPublish: false,
  isCollaborator: false,
  user: null,
  customer: null,
  talentCredential: null,
  errorConnectCalendar: null,
  consumerCredential: null,
  gallery: {},
  tempTalentImages: {
    [TalentImageTypes.AVATAR]: null,
    [TalentImageTypes.COVERS]: [],
  },
  password: null,
  analytic: null,
  analyticMonthly: null,
  avalabilityCalendar: {
    [CALENDAR_PROVIDERS.GOOGLE_CALENDAR]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    [CALENDAR_PROVIDERS.OUTLOOK_PLUG_IN]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    [CALENDAR_PROVIDERS.OFFICE_365_CALENDAR]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    [CALENDAR_PROVIDERS.EXCHANGE_CALENDAR]: STATUS_CALENDAR_PROVIDERS.IDEAL,
    [CALENDAR_PROVIDERS.ICLOUD_CALENDAR]: STATUS_CALENDAR_PROVIDERS.IDEAL,
  },
  phoneOTP: null,
  emailOTP: null,
  isUserExisted: null,
  isCheckLocalCurrency: null,
  talentProfileModules: [],
  analyticsProfileModules: [],
  talentProfileModulesOrigin: [],
  defaultModulesVersion: [],
  previousModulesVersion: [],
  talentCollaborators: [],
  localizationUnpublishIds: [],
  talentRevert: false,
  isBlockingEdit: false,
  isAutoSaved: false,
  collaborator: null,
  isAdminLogin: false,
  localizationSelected: {
    id: null,
    name: "Default",
    currency: "USD",
    active: false,
    countries: [],
    copyFrom: null,
    isPublished: false,
  },
};

export const userReducer = handleActions<UserState>(handlers, initialState);
