import {createEvent} from "../utils/create-event";

var Wick = window.Wick || {};

Wick.FavouriteProduct = {
  TOGGLE_FAVOURITE_PRODUCT_EVENT: 'toggleFavouriteProduct',
  elementsData: {
    favouriteButtonClass: '.favourite-product',
    checkedClass: 'favourite-product-checked',
    disableClass: 'favourite-product-disable',
    favouriteStatusAttribute: 'data-favourite-status',
  },
  previousState: {},
  productDebounceCollector: {},

  toggleCheckedClass(favouriteButton) {
    favouriteButton.toggleClass(Wick.FavouriteProduct.elementsData.checkedClass);
  },

  showSuccessMessage(text) {
    Wick.SnackBar.show({
      type: Wick.SnackBar.types.SUCCESS,
      autoClose: true,
      text
    });
  },
  showErrorMessage(text) {
    Wick.SnackBar.show({
      type: Wick.SnackBar.types.ERROR,
      autoClose: true,
      text
    });
  },

  enableFavouriteButton(favouriteButton) {
    favouriteButton.removeClass(Wick.FavouriteProduct.elementsData.disableClass);
  },
  disableFavouriteButton(favouriteButton) {
    favouriteButton.addClass(Wick.FavouriteProduct.elementsData.disableClass);
  },

  getStatus(favouriteButton) {
    return favouriteButton.hasClass(Wick.FavouriteProduct.elementsData.checkedClass)
  },
  setPreviousStatus(favouriteButton, productId) {
    if (!Wick.FavouriteProduct.previousState.hasOwnProperty(productId)) {
      Wick.FavouriteProduct.previousState[productId] = Wick.FavouriteProduct.getStatus(favouriteButton)
    }
  },
  removePreviousStatus(productId) {
    delete Wick.FavouriteProduct.previousState[productId]
  },
  isStatusChanged(favouriteButton, productId) {
    return Wick.FavouriteProduct.previousState[productId] !== Wick.FavouriteProduct.getStatus(favouriteButton)
  },

  debounceRequest(favouriteButton, productId) {
    if(!Wick.FavouriteProduct.productDebounceCollector[productId]) {
      Wick.FavouriteProduct.productDebounceCollector[productId] = Wick.FavouriteProduct.createDebounce()
    }

    Wick.FavouriteProduct.productDebounceCollector[productId](favouriteButton, productId)
  },

  createDebounce() {
    return _.debounce((favouriteButton, productId) => {
      if (Wick.FavouriteProduct.isStatusChanged(favouriteButton, productId)) {
        Wick.FavouriteProduct.sendRequest(favouriteButton, productId)
      }

      Wick.FavouriteProduct.removePreviousStatus(productId)
    }, 500)
  },

  sendRequest(favouriteButton, productId) {
    const payload = {
      productId,
      isChecked: Wick.FavouriteProduct.getStatus(favouriteButton),
    }

    Wick.FavouriteProduct.disableFavouriteButton(favouriteButton)

    return new Promise((resolve, reject) => {
      const eventDetail = {resolve, reject};
      const event = createEvent(Wick.FavouriteProduct.TOGGLE_FAVOURITE_PRODUCT_EVENT, payload, eventDetail);
      window.dispatchEvent(event);
    })
      .then(({ message }) => {
        if (message) {
          Wick.FavouriteProduct.showSuccessMessage(message)
        }
      })
      .catch(({ message }) => {
        if (message) {
          Wick.FavouriteProduct.showErrorMessage(message)
        }
        Wick.FavouriteProduct.toggleCheckedClass(favouriteButton)
      })
      .finally(() => {
        Wick.FavouriteProduct.enableFavouriteButton(favouriteButton)
      })
  },

  setListenerForButtons (parentClass, getProductId) {
    $(parentClass).on('click', Wick.FavouriteProduct.elementsData.favouriteButtonClass, function(){
      const favouriteButton = $(this);
      const productId = getProductId(favouriteButton);

      Wick.FavouriteProduct.setPreviousStatus(favouriteButton, productId)
      Wick.FavouriteProduct.toggleCheckedClass(favouriteButton)
      Wick.FavouriteProduct.debounceRequest(favouriteButton, productId)
    });
  },

  init (parentClass, getProductId) {
    Wick.SnackBar.init()
    Wick.FavouriteProduct.setListenerForButtons(parentClass, getProductId)
  }
}

