const Products = require("../models/Products");
const ProductImages = require("../models/ProductImages");
const SellersCompany = require("../models/SellersCompany");
const ProductMenu = require("../models/ProductMenu");
const {
  sellerProductImageBuilder,
  sellerImageBuilder,
} = require("./image-src-builder");
const ProductVideos = require("../models/ProductVideos");
const {
  sellerEnabledPurchaseOrders,
  checkPOItemStock,
} = require("../services/purchase-order.service");

exports.productVariationBuilder = async (id) => {
  try {
    const product = await Products.findOne({
      where: {
        id,
        product_status: true,
        available: true,
      },
      include: [
        {
          model: ProductImages,
          as: "product_images",
        },
        {
          model: ProductVideos,
          as: "product_videos",
        },
        {
          model: Products,
          as: "children",
          include: [
            {
              model: Products,
              as: "children",
            },
          ],
        },
        {
          model: SellersCompany,
          as: "seller",
          attributes: [
            "id",
            "company_name",
            "shop_name",
            "company_description",
            "shop_location_municipality",
            "shop_location_province",
            "address",
            "url_handle",
            "seller_logo",
            "seller_dashboard_src",
          ],
        },
        {
          model: ProductMenu,
          as: "menus",
          attributes: ["id", "product_menu", "size_category"],
        },
      ],
    });

    if (!product) {
      return { error: "Product not found or unavailable." };
    }

    const {
      id: productId,
      menu,
      description,
      price,
      discounted_price,
      photo,
      quantity_limit,
      stocks,
      available,
      sku,
      seller_dashboard_src,
      product_status,
      product_images = [],
      product_videos = [],
      children: product_variation = [],
      menus,
      seller,
      allow_decimal_order
    } = product;

    const sellerEnablePO = await sellerEnabledPurchaseOrders(seller.id);

    const category = menus || {};
    const thumbnailImage =
      photo && photo !== ""
        ? sellerProductImageBuilder(photo, seller_dashboard_src)
        : (product_images.find((img) => img.is_thumbnail) &&
            sellerProductImageBuilder(
              product_images.find((img) => img.is_thumbnail).file_name,
              true
            )) ||
          null;

    const productImages = product_images.map(
      ({ id: productImageId, file_name, is_thumbnail }) => ({
        id: productImageId,
        url: sellerProductImageBuilder(file_name, true),
        is_thumbnail,
      })
    );

    const productVideos = product_videos.map(
      ({ id: productVideoId, file_name, is_thumbnail }) => ({
        id: productVideoId,
        url: sellerProductImageBuilder(file_name, true),
        is_thumbnail,
      })
    );

    // Handle product variations
    const productVariationResponse = await Promise.all(
      product_variation.map(async (variation) => {
        const subVariations =
          Array.isArray(variation.children) && variation.children.length > 0
            ? await Promise.all(
                variation.children.map(async (sub) => {
                  let subVariationItemStock = parseFloat(sub.stocks);

                  if (sellerEnablePO) {
                    const poSubVariationStock = await checkPOItemStock(sub.id);
                    subVariationItemStock = poSubVariationStock.availableStock;
                  }
                  return {
                    id: sub.id,
                    parent_id: sub.parent_id,
                    name: sub.menu,
                    description: sub.description,
                    price: parseFloat(sub.price),
                    discounted_price: parseFloat(sub.discounted_price),
                    quantity_limit: parseFloat(sub.quantity_limit),
                    stocks: subVariationItemStock,
                    available: sub.available,
                    sku: sub.sku,
                    status: sub.product_status,
                    allow_decimal_order: sub.allow_decimal_order,
                  };
                })
              )
            : [];

        let variationItemStock = parseFloat(variation.stocks);

        if (sellerEnablePO) {
          const poVariationStock = await checkPOItemStock(variation.id);
          variationItemStock = poVariationStock.availableStock;
        }

        return {
          id: variation.id,
          parent_id: variation.parent_id,
          name: variation.menu,
          description: variation.description,
          price: parseFloat(variation.price),
          discounted_price: parseFloat(variation.discounted_price),
          quantity_limit: parseFloat(variation.quantity_limit),
          stocks: variationItemStock,
          available: variation.available,
          sku: variation.sku,
          status: variation.product_status,
          allow_decimal_order: variation.allow_decimal_order,
          sub_variations: subVariations,
        };
      })
    );

    let sellerResponse = {
      id: seller.id,
      name: seller.company_name,
      description: seller.company_description,
      address: seller.address,
      alt_address: null,
      url_handle: seller.url_handle,
      seller_logo: sellerImageBuilder(
        seller.seller_logo,
        seller.seller_dashboard_src
      ),
    };

    if (seller.shop_name && seller.shop_name !== "")
      sellerResponse.name = seller.shop_name;

    if (
      seller.shop_location_municipality &&
      seller.shop_location_municipality !== "" &&
      seller.shop_location_province &&
      seller.shop_location_province !== ""
    )
      sellerResponse.alt_address = `${seller.shop_location_municipality}, ${seller.shop_location_province}`;

    let itemStock = parseFloat(stocks);

    if (sellerEnablePO) {
      const poItemStock = await checkPOItemStock(productId);
      itemStock = poItemStock.availableStock;
    }
    return {
      id: productId,
      name: menu,
      description,
      category: {
        id: category.id || null,
        name: category.product_menu || null,
        size_category: category.size_category || null,
      },
      price: parseFloat(price),
      discounted_price: parseFloat(discounted_price),
      quantity_limit: parseFloat(quantity_limit),
      stocks: itemStock,
      photo: thumbnailImage,
      product_images: productImages,
      product_videos: productVideos,
      available,
      sku,
      allow_decimal_order,
      variations: productVariationResponse,
      seller: sellerResponse,
      status: product_status,
    };
  } catch (err) {
    console.error("Error in productVariationBuilder:", err);
    return { error: "Something went wrong", details: err.message };
  }
};
