import { useRouter } from 'next/router';
import React, { createContext, useEffect, useState } from 'react';
import checkoutCart from 'src/api/checkoutCart';
import fetchProducts from 'src/api/fetchProducts';

const CartContext = createContext();
const CartConsumer = CartContext.Consumer;

const CartProvider = ({ children }) => {
  const [cart, setCart] = useState([]);
  const [total_price, setTotalPrice] = useState(0);
  const [products, setProducts] = useState([]);

  const changeCartItemQty = (pid, quantity, unit_price) => {
    if (quantity < 1) {
      alert('please enter a number greater than 0');
    } else {
      const productExistInCart = cart.find(item => item.pid === pid);

      if (productExistInCart) {
        const max_item_allowed = products.filter(p => p.pid === pid)[0].count;

        const item = cart.find(item => item.pid === pid);
        const allow_to_add_item = quantity <= max_item_allowed;

        if (allow_to_add_item) {
          const final_item = quantity;
          setCart(cart.map(item => (item.pid === pid ? { ...item, quantity: final_item, unit_price } : item)));
        } else {
          // display alert ?
          alert('sorry but the item to add is over the max item allowed');
        }
      } else {
        console.log('newly insert in cart');
        setCart([...cart, { pid, quantity, unit_price }]);
      }
    }
  };

  const addToCart = (pid, quantity, unit_price) => {
    if (cart) {
      const productExistInCart = cart.find(item => item.pid === pid);

      if (productExistInCart) {
        const max_item_allowed = products.filter(p => p.pid === pid)[0].unsold_count;

        // extract item from cart
        const item = cart.find(item => item.pid === pid);
        const allow_to_add_item = item.quantity + quantity <= max_item_allowed;

        if (allow_to_add_item) {
          const final_item = item.quantity + quantity;
          setCart(cart.map(item => (item.pid === pid ? { ...item, quantity: final_item, unit_price } : item)));
        } else {
          // display alert ?
          alert('sorry but the item to add is over the max item allowed');
        }
      } else {
        setCart([...cart, { pid, quantity, unit_price }]);
      }
    } else {
      setCart([{ pid, quantity, unit_price }]);
    }
  };

  const emptyCart = () => {
    setCart([]);
  };

  const proceedCheckOutCart = async () => {
    try {
      let { data } = await checkoutCart(cart);

      if (data.status === 'OK') {
        // clear cart after done
        localStorage.setItem('cart', JSON.stringify([]));
      } else {
        console.error({ data });
        throw new Error('error during checkout');
      }
    } catch (error) {
      console.error(error);
      console.error('checkout error');
    }
  };

  // localStorage for saving and loading across sessions
  // loading, on each fresh site arriving
  useEffect(() => {
    setCart(JSON.parse(localStorage.getItem('cart')));
  }, []);

  // saving, trigger on each cart update
  useEffect(() => {
    if (cart?.length > 0) {
      let temp = 0;
      cart.forEach(c_i => {
        temp = temp + c_i.unit_price * c_i.quantity;
        console.log(c_i.unit_price * c_i.quantity);
      });
      setTotalPrice(temp);
    } else {
      setTotalPrice(0);
    }

    localStorage.setItem('cart', JSON.stringify(cart));
  }, [cart]);

  const removeFromCart = pid => {
    const productToRemove = cart.find(item => item.pid === pid);
    if (productToRemove.quantity > 1) {
      setCart(cart.map(item => (item.pid === pid ? { ...item, quantity: item.quantity - 1 } : item)));
    } else {
      setCart(cart.filter(item => item.pid !== pid));
    }
  };

  useEffect(() => {
    const update = async () => {
      let temp = await fetchProducts();
      setProducts(temp);
    };
    update();
  }, []);

  const helloworld = () => {
    console.log('hello cart');
  };

  return (
    <CartContext.Provider
      value={{
        addToCart,
        removeFromCart,
        helloworld,
        emptyCart,
        cart,
        total_price,
        changeCartItemQty,
        products,
        proceedCheckOutCart,
      }}
    >
      {children}
    </CartContext.Provider>
  );
};

export { CartProvider, CartConsumer, CartContext };
