import { useState, useEffect } from "react";
import {
  Box,
  Typography,
  Button,
  TextField,
  CircularProgress
} from "@mui/material";
import AddIcon from '@mui/icons-material/Add';
import RemoveIcon from '@mui/icons-material/Remove';
import { useSelector, useDispatch } from "react-redux";
import { createCart, addItemToCart } from "../../redux/slices/cartSlice";
import Alert from '@mui/material/Alert';
import AlertTitle from '@mui/material/AlertTitle';

// Utility function to check if an object is empty
const isEmptyObject = (obj) => Object.keys(obj).length === 0 && obj.constructor === Object;

// Check if every key in the target object matches the source object
const hasMatchingProperties = (source, target) => {
  return Object.entries(target).every(([key, value]) => source[key] === value);
};

const ProductDetails = () => {

  const dispatch = useDispatch()
  const product = useSelector((state) => state.products.product.data)
  const cart = useSelector((state) => state.cart.cart)

  const [quantity, setQuantity] = useState(1)
  const [variantSelection, setVariantSelection] = useState({
    amount: "0",
    currencyCode: ""
  })
  const [variants, setVariants] = useState([])
  const [showLoader, setShowLoader] = useState(false)
  const [alert, setAlert] = useState({ open: false, severity: '', message: '' });

  useEffect(() => {
    if (!isEmptyObject(product)) {

      console.log("Product: ", product)


      let productVariants = product?.variants

      // get all variant type
      if (!productVariants || productVariants?.length == 0) return

      // we want to get the title for each variant
      const uniqueOptions = {};
      productVariants.forEach(variant => {

        variant.selectedOptions.forEach(option => {
          if (!uniqueOptions[option.name]) {
            uniqueOptions[option.name] = new Set();
          }
          uniqueOptions[option.name].add(option.value);
        });
      });

      const VariantsArr = Object.entries(uniqueOptions).map(([key, valueSet]) => ({
        name: key,
        options: Array.from(valueSet),
      }));

      // get variants value
      setVariants(VariantsArr)

      // setting Initial value for variants selection
      setVariantSelection((prev) => {

        let newVariantSelection = { ...prev }

        // setting inital selection
        VariantsArr.forEach(({ name, options }) => {
          newVariantSelection = { ...newVariantSelection, [name]: options[0] }
        })

        // find variant price if it all match initial variant selection
        for (const { selectedOptions, price, compareAtPrice, id, quantityAvailable } of productVariants) {

          let { amount, currencyCode } = price;

          if (compareAtPrice?.amount > 0) {
            amount = compareAtPrice?.amount
            currencyCode = compareAtPrice?.currencyCode
          }

          // Convert array to object
          const optionsObject = selectedOptions.reduce(
            (a, { name, value }) => ({ ...a, [name]: value }),
            {}
          );

          if (hasMatchingProperties(newVariantSelection, optionsObject)) {
            newVariantSelection = { ...newVariantSelection, amount, currencyCode, id, quantityAvailable };
            break; // Exit the loop when condition is met
          }
        }

        return newVariantSelection

      })

    }

  }, [product])

  useEffect(() => {
    console.log("variantSelection: ", variantSelection)
  }, [variantSelection])

  const handleVariantClick = (name, value) => {

    setVariantSelection({ ...variantSelection, [name]: value })

    setVariantSelection((prev) => {

      let newVariantSelection = { ...prev }
      newVariantSelection = { ...newVariantSelection, [name]: value }
      let productVariants = product?.variants

      // find variant price if it all match initial variant selection
      for (const { selectedOptions, price, compareAtPrice, id, quantityAvailable } of productVariants) {

        let { amount, currencyCode } = price;

        if (compareAtPrice?.amount > 0) {
          amount = compareAtPrice?.amount
          currencyCode = compareAtPrice?.currencyCode
        }

        // Convert array to object
        const optionsObject = selectedOptions.reduce(
          (a, { name, value }) => ({ ...a, [name]: value }),
          {}
        );

        if (hasMatchingProperties(newVariantSelection, optionsObject)) {
          newVariantSelection = { ...newVariantSelection, amount, currencyCode, id, quantityAvailable };
          if (quantityAvailable == 0) setQuantity(0)
          else setQuantity(1)
          break; // Exit the loop when condition is met
        }
      }

      return newVariantSelection

    })

  }

  const handleCart = () => {

    let cartHistory = localStorage.getItem('amber-cart');
    cartHistory = cartHistory ? JSON.parse(cartHistory) : {};

    setShowLoader(true) //cause I want to prevent user from mutiple clicking

    // if we got no cart, then create a new one
    if (isEmptyObject(cart) || isEmptyObject(cartHistory)) {

      dispatch(createCart())
        .then(() => {
          showAlert('success', 'Cart created successfully!');
        })
        .catch(() => {
          showAlert('error', 'Failed to create cart. Please try again.');
        })
        .finally(() => setShowLoader(false));

    } else {

      console.log("ADD ITEM:", variantSelection)

      dispatch(addItemToCart({
        cartId: cartHistory.id,
        lines: [
          {
            merchandiseId: variantSelection.id,
            quantity
          }
        ]
      }))
        .then(() => {
          showAlert('success', 'Item added to cart successfully!');
        })
        .catch(() => {
          showAlert('error', 'Failed to add item to cart. Please try again.');
        })
        .finally(() => setShowLoader(false));
    }

  }

  const showAlert = (severity, message) => {
    setAlert({ open: true, severity, message });

    // Auto-close the alert after 3 seconds
    setTimeout(() => {
      setAlert({ ...alert, open: false });
    }, 2000);
  };

  const handleIncrement = () => {
    setQuantity((prevQuantity) => (prevQuantity >= variantSelection.quantityAvailable ? variantSelection.quantityAvailable : prevQuantity + 1));
  };

  const handleDecrement = () => {
    setQuantity((prevQuantity) => (prevQuantity > 1 ? prevQuantity - 1 : 1));
  };


  return (
    <Box sx={{ position: "relative" }}>
      {/* Flex Container */}
      <Box sx={{ display: "flex", flexDirection: "column", gap: 2 }}>
        {/* Section 1: Product Info */}
        <Box>
          <Typography variant="body2" sx={{
            fontWeight: "400", fontSize: {
              xs: "0.875rem",
              sm: "0.875rem",
              md: "1.1rem",
            }
          }}>
            {product?.title}
          </Typography>
          {/* <Typography variant="body2" color="text.secondary">
            {product?.collections?.nodes[0]?.title}
          </Typography> */}


          <Typography variant="body2" sx={{
            fontWeight: "100", fontSize: {
              xs: "0.875rem",
              sm: "0.875rem",
              md: "1.1rem",
            }
          }}>
            {(variantSelection?.quantityAvailable == 0) ? <span style={{ color: "red", fontWeight: "bolder" }}>{`OUT OF STOCK`}</span> : `${variantSelection.currencyCode} ${parseFloat(variantSelection.amount).toFixed(2)}`}
          </Typography>

        </Box>

        {/* Section 2: Variants */}
        <Box >

          {variants.map(({ name, options }, index) => {

            return (
              <Box sx={{ display: (name == "Title") ? "none" : "block" }}>
                <Typography variant="body2" sx={{
                  fontWeight: "400", fontSize: {
                    xs: "0.875rem",
                    sm: "0.875rem",
                    md: "1.1rem",
                  },
                  mb: 1
                }}>
                  {name}
                </Typography>

                <Box sx={{
                  display: "flex",
                  flexWrap: "wrap",

                  mb: 2
                }} gap={2}>
                  {options?.map((value) => (
                    <Button
                      key={value}
                      variant={variantSelection[name] === value ? "contained" : "outlined"}
                      color={variantSelection[name] === value ? "primary" : "primary"}
                      sx={{ color: variantSelection[name] === value ? "#FFF" : "#000" }}
                      onClick={() => handleVariantClick(name, value)}
                    >
                      {value}
                    </Button>
                  ))}
                </Box>
              </Box>
            )

          })}

        </Box>


        {/* Section 3: Quantity */}
        <Box sx={{ mb: 5 }}>
          <Typography variant="body2" sx={{
            fontWeight: "400", fontSize: {
              xs: "0.875rem",
              sm: "0.875rem",
              md: "1.1rem",
            },
            mb: 1
          }}>
            Quantity
          </Typography>
          <Box display="flex" alignItems="center" gap={2}>
            <Button
              variant="contained"
              color="primary"
              sx={{ width: "35px" }}
              disabled={variantSelection?.quantityAvailable == 0 || quantity == 1}
              onClick={handleDecrement}
            >
              <RemoveIcon />
            </Button>

            <TextField
              value={quantity}
              inputProps={{ readOnly: true, style: { textAlign: 'center' } }}
              size="small"
              sx={{ width: "100px" }}
              variant="outlined"
            />

            <Button
              variant="contained"
              color="primary"
              sx={{ width: "35px" }}
              disabled={variantSelection?.quantityAvailable == 0 || quantity == variantSelection?.quantityAvailable}
              onClick={handleIncrement}
            >
              <AddIcon />
            </Button>
          </Box>
        </Box>

        {/* Section 4: Description */}
        <Box sx={{ mb: 5 }}>
          <Typography variant="body1" sx={{ fontWeight: "400", color: "#000" }}>
            Description
          </Typography>
          <Typography variant="body1" color="text.secondary" sx={{ fontWeight: "400" }}>
            <div dangerouslySetInnerHTML={{ __html: product?.descriptionHtml }}></div>
          </Typography>
        </Box>

        <Button
          onClick={() => { handleCart() }}
          variant="contained"
          color="common.black"
          fullWidth
          disabled={variantSelection?.quantityAvailable == 0 || showLoader}
          sx={{
            backgroundColor: (theme) => theme.palette.common.black,
            color: "white",
            textTransform: "none",
            mt: 2,
            "&:hover": {
              backgroundColor: (theme) => theme.palette.grey[900],
            },
          }}
        >
          ADD TO CART {showLoader && <CircularProgress sx={{ ml: 1 }} color="white" size={20} />}
        </Button>

        {cart?.lines?.nodes?.length > 0 && <Button
          onClick={() => { window.location.href = '/cart' }}
          variant="contained"
          color="common.black"
          fullWidth
          disabled={showLoader}
          sx={{
            backgroundColor: (theme) => theme.palette.primary.main,
            color: "white",
            textTransform: "none",
            "&:hover": {
              backgroundColor: (theme) => theme.palette.grey[900],
            },
          }}
        >
          PAY NOW
        </Button>}
      </Box>
      {alert.open && (
        <Alert
          severity={alert.severity}
          onClose={() => setAlert({ ...alert, open: false })}
          sx={{ marginTop: 2 }}
        >
          <AlertTitle>{alert.severity === 'success' ? 'Success' : 'Error'}</AlertTitle>
          {alert.message}
        </Alert>
      )}
    </Box>
  );
};

export default ProductDetails;
