const mongoose = require("mongoose");
const Keyword = mongoose.model("Keyword");
let Product = mongoose.model("Products");
const solr = require('solr-client');
const axios = require("axios");
const { messageBuilder  } = require("../../apps/common/CommonFunctions")
const Maintags =mongoose.model("MainTag")
const ShopperrSubscribeProducts = mongoose.model("ShopperrSubscribeProducts");
const { updateShopperrPriceAlgo } = require("../../apps/middlewares/priceAlgo");
const connectSolr = () => {
  const client = solr.createClient({
    host: process.env.SOLR_DEV_URL,
    port: "8983",
    core: "d2c",
    path: "/solr",  
  });
 // console.log("+++++++++++",client)
  client.ping(function (err, obj) {
    if (err) {
      // console.log(err);
    }
  });
  return client;
};
const AWS = require('aws-sdk');
const ID = '';
const SECRET = '';
// The name of the bucket that you have created
const BUCKET_NAME = 'test-bucket';
const s3 = new AWS.S3({
    accessKeyId: 'AKIAZQ3DPSAOW34EMAWP',
    secretAccessKey: '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'
});


const isValidImageUrl = async (url) => {
    try {
      const response = await axios.head(url);
      return response.status === 200;
    } catch (err) {
      return false;
    }
  };

  const formatData = (obj) => {
    if (obj.length > 0) {
      const formattedData = obj.map(({ imgUrl = [], ...otherValues }) => {
        // console.log(obj)
        const supplier_id = obj[0].author;
  
        const appendImgUrl = imgUrl.slice(0, 50).map((img) => {
          
          // console.log(supplier_id)
          
          if(supplier_id=='67405479bf97f7739fb486a0'){
            return {
              // src: `${process.env.S3_BUCKET_FILE_URL}/${img}`,
              src: `${img}`,
            };
          }else{
            return {
              src: `${process.env.S3_BUCKET_FILE_URL}/${img}`,
              // src: `${img}`,
            };
          }
         
          
        });
        const {
          title,
          id,
          url,
          description,
          inStock,
          sku,
          price,
          mrp,
          variantOptions = [],
          variantDescription = [],
          tags,
          igst
        } = otherValues;
        // let subscribedFlag = false;
        // if (merchantId && mongoose.isValidObjectId(merchantId)) {
        //   const SubscribeProduct = await ShopperrSubscribeProducts.findOne({
        //     mId: mongoose.Types.ObjectId(merchantId),
        //     pId: mongoose.Types.ObjectId(id),
        //   });
        //   if (SubscribeProduct) {
        //     subscribedFlag = true;
        //   }
        // }
        return {
          tags,
          title,
          imgUrl: appendImgUrl,
          _id: id,
          url: url,  
          description,
          quantity: inStock,
          sku,
          sellingPrice: price,
          price:price,
          mrp,
          igst,
          inStock,
          recommendedRetailPrice: parseFloat(new Number(mrp).toFixed(2)),
          variantOptions:
            variantOptions.length > 0 ? prepareVO(variantOptions) : [],
          variantDescription:
            variantDescription.length > 0 ? prepareVD(variantDescription) : [],
          // isSubscribed: merchantId ? subscribedFlag : false,
        };
      });
      return formattedData;
    } else return [];
  };
const batchValidateImageUrls = async (imageUrls) => {
    const batchSize = 10; 
    let results = [];
    for (let i = 0; i < imageUrls.length; i += batchSize) {
      const batch = imageUrls.slice(i, i + batchSize);
      const batchPromises = batch.map(url => isValidImageUrl(url));
      const batchResults = await Promise.all(batchPromises);
      results = results.concat(batchResults);
    }
    return results;
  };
   
exports.searchProducts = async (req, res) => {
  try {
    const expectedSourceObj = { ios: 1, android: 2, web: 3 };
    const expectedSourceArr = Object.keys(expectedSourceObj);
    const keyword = req.body.keyword || "*";
    const limit = parseInt(req.body.limit);
    const pageNumber = parseInt(req.body.pageNumber);
    const type = parseInt(req.body.type);
    const source = req.body.source;
    const arrayType = [1, 2, 3, 4, 5];

    // Validate input parameters
    if (!limit || !pageNumber || !type || !source) {
      return messageBuilder(res, 400, { ...req.body }, "Invalid Input Param", { error: 1 });
    }

    if (!source || !expectedSourceArr.includes(source.toLowerCase())) {
      return messageBuilder(
        res,
        400,
        { ...req.body },
        "Invalid Input Param: source can not be null and should be one of value [android, ios, web]",
        { error: 1 }
      );
    }

    if (!arrayType.includes(type)) {
      return messageBuilder(res, 400, { ...req.body }, "type should be in [1, 2, 3, 4, 5]", { error: 1 });
    }

    try {
      if (keyword) {
        const keywordCreated = new Keyword({
          name: keyword,
          source: expectedSourceObj[source.toLowerCase()],
        });

        await keywordCreated.save();
      }
    } catch (err) {
      return messageBuilder(res, 500, { ...req.body }, err.toString(), { error: 1 });
    }

    const startFrom = (pageNumber - 1) * limit;
    const client = connectSolr();

    let query = client.createQuery();
    if (keyword) {
      query = query.q(`%${keyword}%`);
    }
    query = query.start(startFrom).rows(limit);

    client.search(query, async function (err, obj) {
      if (err) {
        console.log(err);
        return messageBuilder(res, 500, { ...req.body }, err.toString(), { error: 1 });
      } else {
        const proData = await formatData(obj.response.docs, null);

        // Process proData and fetch additional product details from MongoDB
        const updatedProData = await Promise.all(
          proData.map(async (item) => {
            // Fetch additional details from MongoDB
            const found = await Product.find(
              { _id: mongoose.Types.ObjectId(item._id) },
              { code: 1, sp: 1, mrp: 1 }
            );

            if (found.length > 0) {
              // Update the `sp` value if found
              item.sellingPrice = found[0].sp + (item.sp || 0);
              item.recommendedRetailPrice = found[0].mrp + (item.mrp || 0);
            } else {
              // Add marker or additional data for unmatched items
              item.new = true;
            }

            // Validate image URLs in batches (in parallel)
            const imageUrls = item.imgUrl.map(img => img.src);
            const imageValidities = await batchValidateImageUrls(imageUrls);

            // Only keep valid images
            item.imgUrl = item.imgUrl.filter((_, index) => imageValidities[index]);

            // If no valid images are found, return null (removes the product)
            if (item.imgUrl.length === 0) {
              return null;
            }

            return item;
          })
        );

        const filteredProData = updatedProData.filter(item => item !== null);

        const dataToSend = {
          params: {
            keyword,
            limit,
            pageNumber,
            source,
          },
          data: {
            totalRecords: obj.response.numFound,
            products: filteredProData,
          },
        };

        return messageBuilder(res, 200, { ...req.body }, "", dataToSend);
      }    
    });
  } catch (err) {
    return messageBuilder(res, 500, { ...req.body }, err.toString(), { error: 1 });
  }
};

exports.searchProductList = async (req, res) => {
  try {
    const limit = parseInt(req.body.limit) || 10;
    const page = parseInt(req.body.page) || 1;
    const sortBy = req.body.sortby || "default";
    const keyword = req.body.keyword || "";
    const category = req.body.category || "";

    const startFrom = (page - 1) * limit;
    const client = connectSolr();
    let query = client.createQuery();
 
    let solrQuery = "*:*";

    if (keyword && category) {
      solrQuery = `category:"${category}" AND text:"${keyword}"`;
    } else if (category) {
      solrQuery = `category:"${category}"`;
    } else if (keyword) {
      solrQuery = `text:"${keyword}"`;
    }            

    query = query.q(solrQuery).start(startFrom).rows(limit).set("cache=false");
    // Add sorting logic
    if (sortBy === "lowest_price") {
      query = query.sort({ price: "asc" });
    } else if (sortBy === "highest_price") {
      query = query.sort({ price: "desc" });
    } else if (sortBy === "newest") {
      query = query.sort({ created_at: "desc" });
    }
  
    client.search(query, async function (err, obj) {
      if (err) {
      
        return messageBuilder(res, 500, { ...req.body }, err.toString(), {
          error: 1,
        });
      } else {
        const productData = await formatData(obj.response.docs, null);

        const dataToSend = {
          params: { limit, page, sortBy, keyword, category },
          data: {
            totalRecords: obj.response.numFound,
            products: productData,
          },
        };

        return messageBuilder(res, 200, { ...req.body }, "", dataToSend);
      }
    });
  } catch (err) {
    return messageBuilder(res, 500, { ...req.body }, err.toString(), {
      error: 1,
    });
  }
};
