// #region [Imports] ===================================================================================================

// Types
import {
  ICouponTemplate,
  ICouponTemplatesStore,
  ICouponTemplateCategory,
  ICartConditionGroup,
  ICartConditionGroupLogic,
} from '../../types/couponTemplates';
import {
  ECouponTemplatesActionTypes,
  ISetCouponTemplatesCategoriesPayload,
  ISetCouponTemplatesPayload,
  IUnsetRecentCouponTemplatePayload,
  ITogglePremiumModalPayload,
  ISetSearchFiltersPayload,
  ISetSortOptionsPayload,
} from '../actions/couponTemplates';

import { cloneDeep } from 'lodash';

import { validateConditionField } from '../../pages/CouponTemplates/TemplateForm/CartConditions/ConditionField';

// #endregion [Imports]

// #region [Reducer] ===================================================================================================

const reducer = (
  state: ICouponTemplatesStore = {
    loading: false,
    templates: [],
    recent: [],
    review: [],
    edit: null,
    categories: [],
    formResponse: null,
    premiumModal: false,
    searchFilters: {
      searchTerm: '',
      licenseFilter: 'all',
    },
    sortOptions: {
      sortBy: 'title',
      sortOrder: 'asc',
    },
  },
  action: { type: string; payload: any }
): ICouponTemplatesStore => {
  let index;
  switch (action.type) {
    case ECouponTemplatesActionTypes.SET_COUPON_TEMPLATES: {
      const { data: templates, type = 'main' } = action.payload as ISetCouponTemplatesPayload;

      switch (type) {
        case 'main':
          return { ...state, templates };
        case 'recent':
          return { ...state, recent: templates };
        case 'review':
          return { ...state, review: templates };
      }
    }

    case ECouponTemplatesActionTypes.SET_COUPON_TEMPLATE_CATEGORIES: {
      const { data: categories } = action.payload as ISetCouponTemplatesCategoriesPayload;
      return { ...state, categories: categories };
    }

    case ECouponTemplatesActionTypes.UNSET_RECENT_COUPON_TEMPLATE: {
      const { id } = action.payload as IUnsetRecentCouponTemplatePayload;
      const recentTemplates = [...state.recent];
      index = recentTemplates.findIndex((c) => c.id === id);
      recentTemplates.splice(index, 1);
      return { ...state, recent: recentTemplates };
    }

    case ECouponTemplatesActionTypes.SET_COUPON_TEMPLATES_LOADING: {
      const { loading } = action.payload;
      return { ...state, loading };
    }

    case ECouponTemplatesActionTypes.SET_EDIT_COUPON_TEMPLATE: {
      const { data: edit } = action.payload;
      return { ...state, edit };
    }

    case ECouponTemplatesActionTypes.SET_EDIT_COUPON_TEMPLATE_FIELD_VALUE: {
      const { field, value } = action.payload;
      const edit = { ...state.edit } as ICouponTemplate;

      if (!edit || !edit.fields) return state;

      const index = edit.fields.findIndex((f) => f.field === field);

      if (index > -1) {
        edit.fields[index].value = value;
      }

      return { ...state, edit: { ...edit } };
    }

    case ECouponTemplatesActionTypes.VALIDATE_EDIT_COUPON_TEMPLATE_DATA: {
      const edit = { ...state.edit } as ICouponTemplate;

      if (!edit || !edit.fields) return state;

      const fields = edit.fields.map((f) => {
        if (f.is_required && (!f.value || f.fixtures?.options?.disabled === f.value)) {
          f.error = 'This field is required';
        } else {
          f.error = undefined;
        }
        return f;
      });

      return { ...state, edit: { ...edit, fields } };
    }

    case ECouponTemplatesActionTypes.VALIDATE_CART_CONDITIONS_DATA: {
      const edit = { ...state.edit } as ICouponTemplate;

      if (!edit || !edit.cart_conditions || !edit.cart_conditions.length) return state;

      let cartConditions = cloneDeep(edit.cart_conditions);

      cartConditions = cartConditions.map((group) => {
        if ('group_logic' === group.type) return group;

        // @ts-ignore
        let fields = group.fields as ICartConditionGroup['fields'];

        fields = fields.map((field) => {
          if ('logic' === field.type) return field;

          field.errors = validateConditionField(field.type, field.data);

          return field;
        });

        return { ...group, fields };
      });

      return { ...state, edit: { ...edit, cart_conditions: cartConditions } };
    }

    case ECouponTemplatesActionTypes.SET_COUPON_CREATED_RESPONSE_DATA: {
      const { data } = action.payload;
      return { ...state, formResponse: data };
    }

    case ECouponTemplatesActionTypes.SET_CART_CONDITION_ITEM_DATA: {
      const { groupKey, fieldKey, data } = action.payload;
      const edit = { ...state.edit } as ICouponTemplate;

      if (!edit || !edit.cart_conditions) return state;

      const cartConditions = cloneDeep(edit.cart_conditions);

      const groupLogic =
        cartConditions[groupKey].type === 'group_logic' ? (cartConditions[groupKey] as ICartConditionGroupLogic) : null;
      const group =
        cartConditions[groupKey].type === 'group' ? (cartConditions[groupKey] as ICartConditionGroup) : null;

      if (fieldKey === null && groupLogic !== null) {
        groupLogic.value = data as string;
        cartConditions[groupKey] = groupLogic;
      } else if (fieldKey !== null && group?.type === 'group') {
        group.fields[fieldKey].data = data;
        cartConditions[groupKey] = group;
      }

      return { ...state, edit: { ...edit, cart_conditions: cartConditions } };
    }

    case ECouponTemplatesActionTypes.CLEAR_COUPON_CREATED_RESPONSE_DATA: {
      const edit = { ...state.edit } as ICouponTemplate;

      edit.fields = edit.fields.map((f) => {
        f.value = f.pre_filled_value ?? '';
        return f;
      });

      return { ...state, formResponse: null, edit: null };
    }

    case ECouponTemplatesActionTypes.TOGGLE_PREMIUM_MODAL: {
      const { show } = action.payload as ITogglePremiumModalPayload;
      return { ...state, premiumModal: show };
    }

    case ECouponTemplatesActionTypes.SET_SEARCH_FILTERS: {
      const { searchTerm, licenseFilter } = action.payload as ISetSearchFiltersPayload;
      return { ...state, searchFilters: { searchTerm, licenseFilter } };
    }

    case ECouponTemplatesActionTypes.SET_SORT_OPTIONS: {
      const { sortBy, sortOrder } = action.payload as ISetSortOptionsPayload;
      return { ...state, sortOptions: { sortBy, sortOrder } };
    }
  }

  return state;
};

export default reducer;

// #endregion [Reducer]
