/**
 * React Native Full App (https://store.enappd.com/product/react-native-full-app)
 *
 * Copyright © 2019-present Enappd. All rights reserved.
 *
 * This source code is licensed as per the terms found in the
 * LICENSE.md file in the root directory of this source tree.
 */

import { ThunkAction } from 'redux-thunk';
import { AppReduxState } from '../reducers';
import { Action } from 'redux';
import { AsyncStorage } from 'react-native';
import {
  CartActionTypes,
  GET_CART_PRODUCTS,
  ADD_TO_CART,
  REMOVE_FROM_CART,
  REDUCE_QUANTITY,
  RAISE_QUANTITY,
  TOTAL_CART_VALUE,
  CLEAR_CART,
  QUANTITY_UPDATE,
} from '../types/Cart';

export function getCartProducts(
  param: string
): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch) => {
    const cartData: any = await AsyncStorage.getItem('cartData');
    dispatch(getCartProductsDispatch(cartData ? JSON.parse(cartData) : []));
    let sum = 0;
    let quantityObj: { [key: string]: number } = {};
    JSON.parse(cartData).forEach((el: any) => {
      sum = sum + el.price * el.units;
      quantityObj[el.id] = el.units;
    });
    dispatch(updateQuantityDispatch(quantityObj));
    dispatch(totalCartValueDispatch(sum));
  };
}

function getCartProductsDispatch(data: Array<any>): CartActionTypes {
  return {
    type: GET_CART_PRODUCTS,
    payload: data,
  };
}

export function addToCart(
  product: any
): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch, getState) => {
    const { cartProducts, cartValue, productQuntity } = getState().cart;
    const sum = cartValue + product.price * product.units;
    cartProducts.push(product);
    productQuntity[product.id] = product.units;
    dispatch(updateQuantityDispatch(productQuntity));
    dispatch(addToCartDispatch(cartProducts));
    dispatch(totalCartValueDispatch(sum));
    await AsyncStorage.setItem('cartData', JSON.stringify(cartProducts));
  };
}

function addToCartDispatch(data: Array<any>): CartActionTypes {
  return {
    type: ADD_TO_CART,
    payload: data,
  };
}

export function removeFromCart(
  productIndex: number
): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch, getState) => {
    const { cartProducts, cartValue, productQuntity } = getState().cart;
    const sum =
      cartValue -
      cartProducts[productIndex].price * cartProducts[productIndex].units;
    delete productQuntity[cartProducts[productIndex].id];
    cartProducts.splice(productIndex, 1);
    dispatch(updateQuantityDispatch(productQuntity));
    dispatch(totalCartValueDispatch(sum));
    dispatch(removeFromCartDispatch(cartProducts));
    await AsyncStorage.setItem('cartData', JSON.stringify(cartProducts));
  };
}
function removeFromCartDispatch(data: Array<any>): CartActionTypes {
  return {
    type: REMOVE_FROM_CART,
    payload: data,
  };
}

export function reduceQuantity(
  index: number
): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch, getState) => {
    const { cartProducts, cartValue, productQuntity } = getState().cart;
    cartProducts[index].units -= 1;
    const sum = cartValue - cartProducts[index].price;
    productQuntity[cartProducts[index].id] = cartProducts[index].units;
    dispatch(updateQuantityDispatch(productQuntity));
    dispatch(reduceQuantityDispatch(cartProducts));
    dispatch(totalCartValueDispatch(sum));
    await AsyncStorage.setItem('cartData', JSON.stringify(cartProducts));
  };
}

function reduceQuantityDispatch(data: Array<any>): CartActionTypes {
  return {
    type: REDUCE_QUANTITY,
    payload: data,
  };
}

export function raiseQuantity(
  index: number
): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch, getState) => {
    const { cartProducts, cartValue, productQuntity } = getState().cart;
    cartProducts[index].units += 1;
    const sum = cartValue + cartProducts[index].price;
    productQuntity[cartProducts[index].id] = cartProducts[index].units;
    dispatch(updateQuantityDispatch(productQuntity));
    dispatch(raiseQuantityDispatch(cartProducts));
    dispatch(totalCartValueDispatch(sum));
    await AsyncStorage.setItem('cartData', JSON.stringify(cartProducts));
  };
}

function raiseQuantityDispatch(data: Array<any>): CartActionTypes {
  return {
    type: RAISE_QUANTITY,
    payload: data,
  };
}

export function totalCartValue(): ThunkAction<
  void,
  AppReduxState,
  null,
  Action<string>
> {
  return (dispatch, getState) => {
    let sum = 0;
    getState().cart.cartProducts.forEach((el) => (sum += el.price * el.units));
    dispatch(totalCartValueDispatch(sum));
  };
}
function totalCartValueDispatch(data: number): CartActionTypes {
  return {
    type: TOTAL_CART_VALUE,
    payload: data,
  };
}
export function clearCart(): ThunkAction<
  void,
  AppReduxState,
  null,
  Action<string>
> {
  return async (dispatch) => {
    dispatch(clearCartDispatch());
    await AsyncStorage.removeItem('cartData');
  };
}
function clearCartDispatch(): CartActionTypes {
  return {
    type: CLEAR_CART,
  };
}
export function updateQuantity(quntityObj: {
  [key: string]: number;
}): ThunkAction<void, AppReduxState, null, Action<string>> {
  return async (dispatch) => {
    dispatch(updateQuantityDispatch(quntityObj));
    await AsyncStorage.removeItem('cartData');
  };
}
function updateQuantityDispatch(data: {
  [key: string]: number;
}): CartActionTypes {
  return {
    type: QUANTITY_UPDATE,
    payload: data,
  };
}
