const Products = require("../models/Products");
const ProductMenu = require("../models/ProductMenu");
const Seller = require("../models/Seller");
const SellersCompany = require("../models/SellersCompany");
const DetailSellerReviews = require("../models/DetailSellerReviews");
const errorHandler = require("../util/errorHandler");
const multer = require("multer");
const Sequelize = require("sequelize");

// Create a new seller
exports.createSellers = async (req, res, next) => {
  const { data } = req.body;
  const {
    seller_id,
    name,
    username,
    password,
    role,
    lat,
    long,
    address,
    isAuthorizedWarehouse,
    description, // Include description
  } = data;

  if (isAuthorizedWarehouse !== "Yes" && isAuthorizedWarehouse !== "No") {
    throw new Error('isAuthorizedWarehouse must be "Yes" or "No"');
  }

  if (!req.files || !req.files.sellerLogo) {
    return errorHandler("Sellers photo is missing from the request.", 500);
  }

  const { sellerLogo } = req.files;

  try {
    // Fetch SellersCompany based on the provided seller_id
    const sellersCompany = await SellersCompany.findOne({ where: { id: seller_id } });
    if (!sellersCompany) {
      throw new Error("No SellersCompany found for the provided seller_id");
    }

    console.log("seller_id:", seller_id);
    console.log("sellersCompany.id:", sellersCompany.id);

    // Check if the provided seller_id matches the id from SellersCompany
    if (seller_id.toString() !== sellersCompany.id.toString()) {
      return res.status(400).json({ success: false, message: "Seller ID does not match the ID from SellersCompany" });
    }

    await Seller.create({
      seller_id,
      name,
      username,
      password,
      role,
      seller_logo: sellerLogo[0].filename || null,
      lat,
      long,
      address,
      isAuthorizedWarehouse,
      description, // Include description
    });

    res.status(201).json({ success: true });
  } catch (err) {
    next(err);
  }
};

exports.getAllSellers = async (req, res) => {
  try {
    const { page, sellerLimit, productLimit } = req.pagination;
    const startIndex = (page - 1) * sellerLimit;
    const endIndex = page * sellerLimit;

    const sellers = await SellersCompany.findAll({
      offset: startIndex,
      limit: sellerLimit,
    });

    const totalSellers = await SellersCompany.count();

    const totalPages = Math.ceil(totalSellers / sellerLimit);
    const hasNextPage = endIndex < totalSellers;
    const hasPreviousPage = startIndex > 0;

    const sellerDetailsPromises = sellers.map(async (seller) => {
      const products = await Products.findAll({
        where: {
          seller_id: seller.id,
        },
        limit: productLimit,
      });

      // Fetch average rating from DetailSellerReviews
      const averageRating = await DetailSellerReviews.findOne({
        attributes: [
          [
            DetailSellerReviews.sequelize.fn(
              "COALESCE",
              DetailSellerReviews.sequelize.fn("AVG", DetailSellerReviews.sequelize.col("rate")),
              0
            ),
            "avgRating",
          ],
        ],
        where: { seller_id: seller.id },
      });

      return {
        seller,
        products,
        averageRating: averageRating ? averageRating.get("avgRating") : "0.00",
      };
    });

    const sellerDetails = await Promise.all(sellerDetailsPromises);

    const mappedSellers = sellerDetails.map(({ seller, products, averageRating }) => ({
      id: seller.id,
      name: seller.shop_name === "" || seller.shop_name === null ? seller.company_name : seller.shop_name,
      lat: seller.latitude, // Include latitude
      long: seller.longitude, // Include longitude
      seller_logo: seller && seller.seller_logo ? `https://buildhub.ph/img/seller/${seller.seller_logo}` : null,
      seller_banner_image:
        seller && seller.seller_banner_image ? `https://buildhub.ph/img/seller/${seller.seller_banner_image}` : null,
      description: seller.company_description, // Include description
      products: products.map((product) => ({
        id: product.menu_id,
        name: product.menu,
        variant: product.variant,
        description: product.description,
        price: product.price,
        discountedPrice: product.discounted_price,
        photo: product && product.photo ? `https://buildhub.ph/img/products/${product.photo}` : null,
        quantityLimit: product.quantity_limit,
        stocks: product.stocks,
        available: product.available,
        sku: product.sku,
        variationId: product.product_variation_id,
        subVariation: product.product_sub_variation_id,
      })),
      averageRating,
    }));

    const response = {
      sellers: mappedSellers,
      pagination: {
        totalPages: totalPages,
        currentPage: page,
        hasNextPage: hasNextPage,
        hasPreviousPage: hasPreviousPage,
      },
    };

    res.status(200).json(response);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

// Get seller by ID
exports.getSellerId = async (req, res) => {
  const { sellerID } = req.params;

  try {
    const seller = await SellersCompany.findByPk(sellerID);

    if (!seller) {
      return res.status(404).json({ error: "Seller not found" });
    }

    // Fetch average rating from DetailSellerReviews
    const averageRating = await DetailSellerReviews.findOne({
      attributes: [
        [
          DetailSellerReviews.sequelize.fn(
            "COALESCE",
            DetailSellerReviews.sequelize.fn("AVG", DetailSellerReviews.sequelize.col("rate")),
            0
          ),
          "avgRating",
        ],
      ],
      where: { seller_id: sellerID },
    });

    // Fetch total number of products for the seller
    const totalProducts = await Products.count({
      where: { seller_id: sellerID },
    });

    // Construct the response JSON with average rating and total products
    const response = {
      id: seller.id,
      name: seller.shop_name === "" || seller.shop_name === null ? seller.company_name : seller.shop_name,
      lat: seller.latitude, // Include latitude
      long: seller.longitude, // Include longitude
      seller_logo: seller && seller.seller_logo ? `https://buildhub.ph/img/seller/${seller.seller_logo}` : null,
      seller_banner_image:
        seller && seller.seller_banner_image ? `https://buildhub.ph/img/seller/${seller.seller_banner_image}` : null, // Include seller_banner_image
      description: seller.company_description, // Include description
      averageRating: averageRating ? averageRating.get("avgRating") : "0.00",
      totalProducts: totalProducts,
    };

    res.status(200).json(response);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

// Update seller by ID
exports.updateSellerById = async (req, res, next) => {
  const { id } = req.params; // Assuming the endpoint uses "id" of the seller
  const { data } = req.body;
  const { seller_id, name, username, password, role, lat, long, address, isAuthorizedWarehouse } = data;

  const { sellerLogo } = req.files;

  try {
    // Find the SellersCompany based on the provided seller_id
    const sellersCompany = await SellersCompany.findOne({ where: { id: seller_id } });
    console.log("sellersCompany:", sellersCompany); // Check if sellersCompany is fetched correctly
    if (!sellersCompany) {
      throw new Error("No SellersCompany found");
    }

    // Ensure that the seller_id matches the ID from the SellersCompany
    console.log("sellersCompany.id:", sellersCompany.id);
    console.log("seller_id:", seller_id);
    // Compare seller_id and sellersCompany.id as strings
    if (seller_id !== sellersCompany.id.toString()) {
      return errorHandler("Seller ID does not match the ID from SellersCompany", 400);
    }

    // Find the seller by seller_id
    const seller = await Seller.findByPk(id); // Use the id from params, not seller_id

    if (!seller) {
      return errorHandler("Seller ID does not exist!", 404);
    }

    // Validate isAuthorizedWarehouse
    if (isAuthorizedWarehouse !== "Yes" && isAuthorizedWarehouse !== "No") {
      return errorHandler('isAuthorizedWarehouse must be "Yes" or "No"', 400);
    }

    // Update seller information
    if (sellerLogo && sellerLogo.length > 0) {
      seller.seller_logo = sellerLogo[0].filename;
    } else {
      seller.seller_logo = null;
    }

    // Update seller information
    seller.seller_id = seller_id; // Add this line if you need to update seller_id
    seller.name = name;
    seller.username = username;
    seller.password = password;
    seller.role = role;
    seller.lat = lat;
    seller.long = long;
    seller.address = address;
    seller.isAuthorizedWarehouse = isAuthorizedWarehouse;

    await seller.save();
    res.status(200).json({ success: true });
  } catch (err) {
    next(err);
  }
};

// Delete seller by ID
exports.deleteSellerById = async (req, res) => {
  const { sellerID } = req.params;

  try {
    const seller = await Seller.findByPk(sellerID);

    if (!seller) {
      return res.status(404).json({ error: "Seller not found" });
    }

    await seller.destroy();

    res.status(204).send();
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};

exports.getProductsByCategoryAndSeller = async (req, res) => {
  const { sellerID, product_category } = req.query;

  try {
    const seller = await SellersCompany.findByPk(sellerID);

    if (!seller) {
      return res.status(404).json({ error: "Seller not found" });
    }

    const products = await Products.findAll({
      where: {
        seller_id: sellerID,
      },
      include: [
        {
          model: ProductMenu,
          as: "menus",
          where: {
            product_menu: product_category,
          },
          attributes: ["product_menu"],
        },
      ],
    });

    // Map the products array to include all properties
    const mappedProducts = products.map((product) => ({
      product_Menu: product.menus.product_menu,
      seller_name: seller.shop_name === "" || seller.shop_name === null ? seller.company_name : seller.shop_name,
      seller_logo: seller && seller.seller_logo ? `https://buildhub.ph/img/seller/${seller.seller_logo}` : null,
      seller_banner_image:
        seller && seller.seller_banner_image ? `https://buildhub.ph/img/seller/${seller.seller_banner_image}` : null,
      seller_Id: product.seller_id,
      product_Id: product.id,
      product_Name: product.menu,
      description: product.description,
      price: product.price,
      discountedPrice: product.discounted_price,
      photo: product && product.photo ? `https://buildhub.ph/img/products/${product.photo}` : null,
      quantityLimit: product.quantity_limit,
      stocks: product.stocks,
      available: product.available,
      sku: product.sku,
      variationId: product.product_variation_id,
      subVariation: product.product_sub_variation_id,
    }));

    res.status(200).json({ products: mappedProducts });
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: "Internal Server Error" });
  }
};
