const UserCart = require("../models/UserCart");
const Products = require("../models/Products"); // Import Products model
const errorHandler = require("../util/errorHandler");
const ProductVariation = require("../models/ProductVariation");
const ProductSubVariation = require("../models/ProductSubVariation");

exports.createUserCart = async (req, res, next) => {
  try {
    const customerId = req.customerId;
    const { data } = req.body;
    const { menu_id, quantity } = data;

    const product = await Products.findByPk(menu_id);
    if (!product) {
      return res.status(404).json({ error: 'Product not found' });
    }

    if (product.stocks < quantity) {
      return res.status(400).json({ error: 'Not enough stocks available' });
    }

    let chosenVariation = null;
    let chosenSubVariation = null;

    if (data.variation_id) {
      chosenVariation = await ProductVariation.findOne({
        where: {
          id: data.variation_id,
          product_id: menu_id
        }
      });

      if (!chosenVariation) {
        return res.status(404).json({ error: 'Chosen variation not found for the specified product' });
      }

      if (chosenVariation.hasSubVariation && data.sub_variation_id) {
        chosenSubVariation = await ProductSubVariation.findOne({
          where: {
            id: data.sub_variation_id,
            product_variation_id: data.variation_id
          }
        });

        if (!chosenSubVariation) {
          return res.status(404).json({ error: 'Chosen sub-variation not found or does not belong to the chosen variation' });
        }
      }
    }

    const price = chosenSubVariation ? (chosenSubVariation.discounted_price !== null ? chosenSubVariation.discounted_price : chosenSubVariation.price) : (chosenVariation ? (chosenVariation.discounted_price !== null ? chosenVariation.discounted_price : chosenVariation.price) : product.price);

    const totalPrice = price * quantity;

    const existingCartsTotalPrice = await UserCart.sum('price', {
      where: {
        user_id: customerId
      }
    });

    if (existingCartsTotalPrice + totalPrice > 150000) {
      return res.status(400).json({ error: 'Total price of carts exceeds the maximum allowed value for this user' });
    }

    const currentDateTime = new Date();

    const newUserCart = await UserCart.create({
      user_id: customerId,
      menu_id: menu_id,
      quantity: quantity,
      has_sub_variation_chosen: chosenSubVariation ? "true" : "false",
      product_variation_id: chosenVariation ? chosenVariation.id : null,
      product_sub_variation_id: chosenSubVariation ? chosenSubVariation.id : null,
      created_at: currentDateTime,
      price: totalPrice,
    });

    if (product.stocks >= quantity) {
      product.stocks -= quantity;
      await product.save();
    }

    const response = {
      success: "User Cart successfully created!",
      newUserCart: {
        user_cart_id: newUserCart.id,
        user_id: newUserCart.user_id,
        product_id: newUserCart.menu_id,
        product_name: product.menu,
        quantity: newUserCart.quantity,
        has_sub_variation_chosen: newUserCart.has_sub_variation_chosen,
        product_variation_id: newUserCart.product_variation_id,
        product_sub_variation_id: newUserCart.product_sub_variation_id,
        created_at: newUserCart.created_at,
        price: newUserCart.price,
        remaining_stock: product.stocks
      }
    };

    res.status(201).json(response);

  } catch (err) {
    next(err);
  }
};

exports.getAllUserCart = async (req, res, next) => {
  try {
    const usercart = await UserCart.findAll({
      include: [
        {
          model: Products,
          attributes: ['menu', 'photo'], // Fetch 'menu' and 'photo' attributes from the Products table
          as: 'product' // Alias for the joined table
        }
      ]
    });

    const usercartResponse = usercart.map(({
      id,
      user_id,
      menu_id,
      quantity,
      has_sub_variation_chosen,
      product_variation_id,
      product_sub_variation_id,
      created_at: currentDateTime,
      price,
      product // Access the joined product data
    }) => ({
      user_cart_id: id,
      user_id,
      product_id: menu_id,
      product_name: product.menu, // Access the 'menu' attribute from the joined product
      photos: `https://buildhub.ph/img/products/${product.photo}`, // Construct the photo URL
      quantity,
      has_sub_variation_chosen,
      product_variation_id,
      product_sub_variation_id,
      created_at: currentDateTime,
      price,
    }));

    res.status(200).json(usercartResponse);
  } catch (error) {
    next(error);
  }
};

exports.getUserCartId = async (req, res, next) => {
  const { UserCartId } = req.params;

  try {
    const userCarts = await UserCart.findAll({
      where: {
        user_id: UserCartId
      },
      include: [
        {
          model: Products,
          attributes: ['menu', 'photo'], // Fetch 'menu' and 'photo' attributes from the Products table
          as: 'product' // Alias for the joined table
        }
      ]
    });

    if (!userCarts || userCarts.length === 0) {
      return res.status(404).json({ error: 'User Cart not found' });
    }

    // Map the response fields
    const mappedUserCarts = userCarts.map(cart => ({
      user_cart_id: cart.id,
      user_id: cart.user_id,
      product_id: cart.menu_id,
      product_name: cart.product.menu, // Access the 'menu' attribute from the joined product
      photos: `https://buildhub.ph/img/products/${cart.product.photo}`, // Construct the photo URL
      quantity: cart.quantity,
      has_sub_variation_chosen: cart.has_sub_variation_chosen,
      product_variation_id: cart.product_variation_id,
      product_sub_variation_id: cart.product_sub_variation_id,
      created_at: cart.created_at,
      price: cart.price
    }));

    res.status(200).json(mappedUserCarts);
  } catch (error) {
    next(error);
  }
};



exports.deleteUserCart = async (req, res, next) => {
    const { UserCartId } = req.params;
  
    try {
      const usercart = await UserCart.findByPk(UserCartId);
  
      if (!usercart) {
        return res.status(404).json({ success: false });
      }
  
      await usercart.destroy();
  
      res.status(201).json({ success: "The User Cart ID successfully Deleted" });
    } catch (error) {
      next(error)
    }
  };

  exports.updateUserCart = async (req, res, next) => {
    const { UserCartId } = req.params;
    try {
        const usercart = await UserCart.findByPk(UserCartId, {
            include: [
                {
                    model: Products,
                    attributes: ['menu'], // Fetch only the 'menu' attribute from the Products table
                    as: 'product' // Alias for the joined table
                }
            ]
        });

        if (!usercart) {
            return res.status(404).json({ error: 'User Cart not found' });
        }

        const {
            quantity,
            variation_id,
            sub_variation_id,
        } = req.body;

        // Fetch the product
        const product = await Products.findByPk(usercart.menu_id);
        if (!product) {
            return res.status(404).json({ error: 'Product not found' });
        }

        // Fetch the chosen variation and sub-variation if variation_id is provided
        let chosenVariation = null;
        let chosenSubVariation = null;
        if (variation_id) {
            chosenVariation = await ProductVariation.findOne({
                where: {
                    id: variation_id,
                    product_id: product.id
                }
            });
            if (!chosenVariation) {
                return res.status(404).json({ error: 'Chosen variation not found for the specified product' });
            }

            if (chosenVariation.hasSubVariation && sub_variation_id) {
                chosenSubVariation = await ProductSubVariation.findOne({
                    where: {
                        id: sub_variation_id,
                        product_variation_id: variation_id
                    }
                });
                if (!chosenSubVariation) {
                    return res.status(404).json({ error: 'Chosen sub-variation not found or does not belong to the chosen variation' });
                }
            }
        }

        // Calculate the price and total price
        let price = null;
        if (chosenSubVariation) {
            price = chosenSubVariation.discounted_price !== null ? chosenSubVariation.discounted_price : chosenSubVariation.price;
        } else if (chosenVariation) {
            price = chosenVariation.discounted_price !== null ? chosenVariation.discounted_price : chosenVariation.price;
        } else {
            // If neither variation nor sub-variation is chosen, use product price
            price = product.price;
        }

        const totalPrice = price * quantity;

        // Update the user cart
        await usercart.update({
            quantity,
            has_sub_variation_chosen: chosenSubVariation ? "true" : "false",
            product_variation_id: chosenVariation ? chosenVariation.id : null,
            product_sub_variation_id: chosenSubVariation ? chosenSubVariation.id : null,
            price: totalPrice,
        });

        const response = {
            success: "User Cart successfully updated!",
            updatedUserCart: {
                user_cart_id: usercart.id,
                user_id: usercart.user_id,
                product_id: usercart.menu_id,
                product_name: usercart.product.menu,
                quantity: usercart.quantity,
                has_sub_variation_chosen: usercart.has_sub_variation_chosen,
                product_variation_id: usercart.product_variation_id,
                product_sub_variation_id: usercart.product_sub_variation_id,
                created_at: usercart.created_at,
                price: usercart.price,
                remaining_stock: product.stocks // You may need to update remaining_stock logic if needed
            }
        };

        res.status(200).json(response);

    } catch (error) {
        next(error);
    }
};



