const Variant = require("../models/FilterVariant");
const Type = require("../models/FilterType");
const SubSubCatagory = require("../models/SubSubCatagory");
const SubCatagory = require("../models/SubCatagory");
const Catagory = require("../models/Catagory");
const Manufacturer = require("../models/FilterManufacture");
const Color = require("../models/FilterColor");
const Category = require("../models/FilterCategory");
const mongoose = require('mongoose');


exports.addVariant = async (req, res) => {
  const { variant } = req.body;

  try {
    const dataVariant = new Variant({ variant });
    const result = await dataVariant.save();

    res.status(200).json({ message: "success", result });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Variant", error: error.message });
  }
};

exports.updateVariant = async (req, res) => {
  let { id } = req.params;
  const { variant } = req.body;
  try {
    const dataVariant = await Variant.findOneAndUpdate({ _id: id }, { variant }, { new: true });

    res.status(200).json({ message: "success", result: dataVariant });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Variant", error: error.message });
  }
};

// POST: /api/filters/searchRetail
// Body: {keyword:string}
// Response: {success:boolean, subsubcatagories:Array,subcatagories:Array,catagories:Array}
exports.keywordSearchRetail = async (req, res) => {
  try {
    const { keyword } = req.body;

    // Create a regular expression to perform a case-insensitive search
    const regex = new RegExp(keyword, 'i');

    const subsubcatagories = await SubSubCatagory.find({ subsubcatagory: { $regex: regex }, productPrice: { $ne: 0 } }, { subsubcatagory: 1 }).limit(10);
    const subcatagories = await SubCatagory.find({ subcatagory: { $regex: regex } }, { subcatagory: 1 }).limit(10);
    const catagories = await Catagory.find({ catagory: { $regex: regex } }, { catagory: 1 }).limit(10);

    res.json({
      success: true,
      subsubcatagories,
      subcatagories,
      catagories
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
};

// POST: /api/filters/searchTrade
// Body: {keyword:string}
// Response: {success:boolean, subsubcatagories:Array,subcatagories:Array,catagories:Array}
exports.keywordSearchTrade = async (req, res) => {
  try {
    const { keyword } = req.body;

    // Create a regular expression to perform a case-insensitive search
    const regex = new RegExp(keyword, 'i');

    const subsubcatagories = await SubSubCatagory.find({ subsubcatagory: { $regex: regex }, wholesellerPrice: { $ne: 0 } }, { subsubcatagory: 1 }).limit(10);
    const subcatagories = await SubCatagory.find({ subcatagory: { $regex: regex } }, { subcatagory: 1 }).limit(10);
    const catagories = await Catagory.find({ catagory: { $regex: regex } }, { catagory: 1 }).limit(10);

    res.json({
      success: true,
      subsubcatagories,
      subcatagories,
      catagories
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
}

// POST: /api/filters/searchTrade
// Body: {keyword:string}
// Response: {success:boolean, subsubcatagories:Array,subcatagories:Array,catagories:Array}
exports.keywordSearchDash = async (req, res) => {
  try {
    const { keyword } = req.body;

    // Create a regular expression to perform a case-insensitive search
    const regex = new RegExp(keyword, 'i');

    const subsubcatagories = await SubSubCatagory.find({ subsubcatagory: { $regex: regex } }, { subsubcatagory: 1 }).limit(10);
    const subcatagories = await SubCatagory.find({ subcatagory: { $regex: regex } }, { subcatagory: 1 }).limit(10);
    const catagories = await Catagory.find({ catagory: { $regex: regex } }, { catagory: 1 }).limit(10);

    res.json({
      success: true,
      subsubcatagories,
      subcatagories,
      catagories
    });
  } catch (error) {
    res.status(500).json({ success: false, message: error.message });
  }
}


exports.addType = async (req, res) => {
  const { type, image } = req.body;

  try {
    const dataType = new Type({ type, image });
    const result = await dataType.save();

    res.status(200).json({ message: "success", result });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Variant", error: error.message });
  }
};




exports.getVarientbyString = async (req, res) => {
  try {
    const allVariants = await Variant.find({ variant: new RegExp('^' + req.params.data, 'i') });
    res.status(200).json({ message: "success", allVariants });
  } catch (error) {
    console.log("Error while fetching all Variants from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};


exports.getAllVariants = async (req, res) => {
  try {
    const allVariants = await Variant.find();
    res.status(200).json({ message: "success", allVariants });
  } catch (error) {
    console.log("Error while fetching all Variants from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};

exports.addManufacturer = async (req, res) => {
  const { manufacturer } = req.body;

  try {
    const dataManufacturer = new Manufacturer({ manufacturer });
    const result = await dataManufacturer.save();

    res.status(200).json({ message: "success", result });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};

exports.updateManufacturer = async (req, res) => {
  let { id } = req.params;
  const { manufacturer } = req.body;

  try {
    const dataManufacturer = await Manufacturer.findOneAndUpdate({ _id: id }, { manufacturer }, { new: true });

    res.status(200).json({ message: "success", result: dataManufacturer });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};


exports.deletemanufacturer = async (req, res) => {

  try {
    const result = await Manufacturer.deleteOne({ _id: req.params.id });
    res.status(200).json({ message: "success", result });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};


exports.deletecolor = async (req, res) => {
  console.log("abc=====", req.params.id);
  try {
    const result = await Color.deleteOne({ _id: req.params.id });
    res.status(200).json({ message: "success", result });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};

exports.updateSequence = async (req, res) => {
  try {
    const { sourceTypeId, targetTypeId } = req.body;

    const [sourceProduct, targetProduct] = await Promise.all([
      Type.findById(sourceTypeId),
      Type.findById(targetTypeId)
    ]);
    if (!sourceTypeId || !targetTypeId) {
      return res.status(404).json({ success: false, message: 'Type not found' });
    }
    if (sourceTypeId === targetTypeId) {
      return res.status(423).json({ success: false, message: 'Same Types cannot be replaced' });
    }
    const updatedSourceProduct = await Type.findByIdAndUpdate(sourceTypeId, {
      type: targetProduct.type,
      image: targetProduct.image,
      showNavbar: targetProduct.showNavbar,
      showNavbarTrade: targetProduct.showNavbarTrade
    }, { new: true });
    const updatedTargetProduct = await Type.findByIdAndUpdate(targetTypeId, {
      type: sourceProduct.type,
      image: sourceProduct.image,
      showNavbar: sourceProduct.showNavbar,
      showNavbarTrade: sourceProduct.showNavbarTrade
    }, { new: true });
    res.status(200).json({ success: true, message: 'Types sequence updated successfully' });
  } catch (error) {
    console.error('Error updating product sequence:', error);
    res.status(500).json({ success: false, message: 'Internal server error' });
  }
};

exports.deletevarient = async (req, res) => {

  try {
    const result = await Variant.deleteOne({ _id: req.params.id });
    res.status(200).json({ message: "success", result });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};


exports.deletetype = async (req, res) => {
  try {
    const result = await Type.deleteOne({ _id: req.params.id });
    res.status(200).json({ message: "success", result });
  } catch (error) {
    res.status(500).json({ message: "Error in adding Manufacturer", error });
  }
};

exports.getAllManufacturer = async (req, res) => {
  try {
    const allManufacturer = await Manufacturer.find();
    res.status(200).json({ message: "success", allManufacturer });
  } catch (error) {
    console.log("Error while fetching all Manufacturer from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};
exports.getManufacturebyString = async (req, res) => {
  try {
    const allManufacturer = await Manufacturer.find({ manufacturer: new RegExp('^' + req.params.data, 'i') });
    res.status(200).json({ message: "success", allManufacturer });
  } catch (error) {
    console.log("Error while fetching all Variants from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};






exports.gettype = async (req, res) => {
  try {
    const allType = await Type.find();
    res.status(200).json({ message: "success", allType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};

exports.gettypebyString = async (req, res) => {
  try {
    const allType = await Type.find({ type: new RegExp('^' + req.params.data, 'i') });
    console.log("abc====", allType);
    res.status(200).json({ message: "success", allType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};

exports.gettypePermitedToShow = async (req, res) => {
  try {
    const allType = await Type.find({ showNavbar: true });
    res.status(200).json({ message: "success", allType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};

exports.gettypePermitedToShowTrade = async (req, res) => {
  try {
    const allType = await Type.find({ showNavbarTrade: true });
    res.status(200).json({ message: "success", allType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};


exports.updatetype = async (req, res) => {
  let id = req.params.id;
  let body = req.body;
  console.log("body====", body);
  try {
    const allType = await Type.updateOne({ _id: id }, body);
    console.log("Updated Type: ", allType);
    const UpdateAccessoryType = await SubSubCatagory.updateMany({ type: id }, { typeName: body.type });
    console.log("UpdateAccessoryType: ", UpdateAccessoryType);
    res.status(200).json({ message: "success", UpdateAccessoryType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error }); s
  }
};



exports.updatetypeONOFF = async (req, res) => {
  let id = req.params.id;
  let body = req.body;
  console.log("body====", body);
  try {
    const allType = await Type.updateOne({ _id: id }, body);
    res.status(200).json({ message: "success", allType });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error }); s
  }
};


exports.addColor = async (req, res) => {
  const { color } = req.body;

  try {
    const datacolor = new Color({ color });
    const result = await datacolor.save();

    res.status(200).json({ message: "success", result });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Color", error: error.message });
  }
};


exports.updateColor = async (req, res) => {
  let { id } = req.params;
  const { color } = req.body;

  try {
    const datacolor = await Color.findOneAndUpdate({ _id: id }, { color }, { new: true });

    res.status(200).json({ message: "success", result: datacolor });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Color", error: error.message });
  }
};



exports.getColorbyString = async (req, res) => {
  try {
    const allColors = await Color.find({ color: new RegExp('^' + req.params.data, 'i') });
    res.status(200).json({ message: "success", allColors });
  } catch (error) {
    console.log("Error while fetching all Type from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};


exports.getAllColors = async (req, res) => {
  try {
    const allColors = await Color.find();
    res.status(200).json({ message: "success", allColors });
  } catch (error) {
    console.log("Error while fetching all Colors from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};

exports.addCategory = async (req, res) => {
  const { category } = req.body;

  try {
    const dataCategory = new Category({ category });
    const result = await dataCategory.save();

    res.status(200).json({ message: "success", result });
  } catch (error) {
    res
      .status(500)
      .json({ message: "Error in adding Category", error: error.message });
  }
};

exports.getAllCategories = async (req, res) => {
  try {
    const allCategories = await Category.find();
    res.status(200).json({ message: "success", allCategories });
  } catch (error) {
    console.log("Error while fetching all Categories from Database", error);
    res.status(500).json({ sucess: false, message: error });
  }
};


// exports.getNavBarDataForRetail = async (req, res) => {
//   try {
//     const navData = await Type.aggregate([
//       {
//         $match: {
//           showNavbar: true
//         }
//       },
//       // Step 2: Lookup SubSubCategories for each Type
//       {
//         $lookup: {
//           from: "subsubcatagorys",
//           // The name of the SubSubCategory collection
//           localField: "type",
//           foreignField: "typeName",
//           as: "subsubcategories"
//         }
//       },
//       //Step 3: Unwind the subsubcategories array
//       {
//         $unwind: {
//           path: "$subsubcategories",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       {
//         $lookup: {
//           from: "catagorys",
//           // The name of the Category collection
//           localField: "subsubcategories.catagory",
//           foreignField: "catagory",
//           as: "categoryDetails"
//         }
//       },
//       {
//         $unwind: {
//           path: "$categoryDetails",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       {
//         $lookup: {
//           from: "subcatagorys",
//           // The name of the SubCategory collection
//           localField: "subsubcategories.subcatagory",
//           foreignField: "subcatagory",
//           as: "subCategoryDetails"
//         }
//       },
//       {
//         $unwind: {
//           path: "$subCategoryDetails",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       // Step 6: Group by Type and Category, and build the nested structure
//       {
//         $group: {
//           _id: {
//             type: "$type",
//             catagory: "$categoryDetails.catagory"
//           },
//           subcategories: {
//             $addToSet: "$subCategoryDetails.subcatagory"
//           },
//           image: { $first: "$image" }
//         }
//       },
//       {
//         $group: {
//           _id: "$_id.type",
//           categories: {
//             $push: {
//               category: "$_id.catagory",
//               subcategories: "$subcategories"
//             }
//           },
//           image: { $first: "$image" }
//         }
//       },
//       {
//         $project: {
//           _id: 0,
//           type: "$_id",
//           categories: "$categories",
//           image: 1
//         }
//       }
//     ]);
//     res.status(200).json({ navData });
//   } catch (error) {
//     console.log("Error while fetching all Data from Database", error);
//     res.status(500).json({ sucess: false, message: error });
//   }
// }


// exports.getNavBarDataForTrade = async(req,res)=>{
//   try{
//     const navData = await Type.aggregate([
//       {
//         $match: {
//           showNavbarTrade: true
//         }
//       },
//       // Step 2: Lookup SubSubCategories for each Type
//       {
//         $lookup: {
//           from: "subsubcatagorys",
//           // The name of the SubSubCategory collection
//           localField: "type",
//           foreignField: "typeName",
//           as: "subsubcategories"
//         }
//       },
//       //Step 3: Unwind the subsubcategories array
//       {
//         $unwind: {
//           path: "$subsubcategories",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       {
//         $lookup: {
//           from: "catagorys",
//           // The name of the Category collection
//           localField: "subsubcategories.catagory",
//           foreignField: "catagory",
//           as: "categoryDetails"
//         }
//       },
//       {
//         $unwind: {
//           path: "$categoryDetails",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       {
//         $lookup: {
//           from: "subcatagorys",
//           // The name of the SubCategory collection
//           localField: "subsubcategories.subcatagory",
//           foreignField: "subcatagory",
//           as: "subCategoryDetails"
//         }
//       },
//       {
//         $unwind: {
//           path: "$subCategoryDetails",
//           preserveNullAndEmptyArrays: true
//         }
//       },
//       // Step 6: Group by Type and Category, and build the nested structure
//       {
//         $group: {
//           _id: {
//             type: "$type",
//             catagory: "$categoryDetails.catagory"
//           },
//           subcategories: {
//             $addToSet: "$subCategoryDetails.subcatagory"
//           }
//         }
//       },
//       {
//         $group: {
//           _id: "$_id.type",
//           categories: {
//             $push: {
//               category: "$_id.catagory",
//               subcategories: "$subcategories"
//             }
//           }
//         }
//       },
//       {
//         $project: {
//           _id: 0,
//           type: "$_id",
//           categories: "$categories"
//         }
//       }
//     ]);
//     res.status(200).json({navData});
//   }catch(error){
//     console.log("Error while fetching all Data from Database", error);
//     res.status(500).json({ sucess: false, message: error });
//   }
// }



// Newer one with sequence maintaining >>> 


exports.getNavBarDataForTrade = async (req, res) => {
  try {
    // Step 1: Retrieve categories and subcategories in the required sequence
    const categoriesInSequence = await Catagory.find({}).sort({ sequence: 1 }).select('_id catagory');
    const subcategoriesInSequence = await SubCatagory.find({}).sort({ sequence: 1 }).select('_id subcatagory catagory');

    // Step 2: Get the nav data by types
    const navData = await Type.aggregate([
      {
        $match: {
          showNavbarTrade: true
        }
      },
      // Step 2: Lookup SubSubCategories for each Type
      {
        $lookup: {
          from: "subsubcatagorys",
          // The name of the SubSubCategory collection
          localField: "type",
          foreignField: "typeName",
          as: "subsubcategories"
        }
      },
      //Step 3: Unwind the subsubcategories array
      {
        $unwind: {
          path: "$subsubcategories",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $lookup: {
          from: "catagorys",
          // The name of the Category collection
          localField: "subsubcategories.catagory",
          foreignField: "catagory",
          as: "categoryDetails"
        }
      },
      {
        $unwind: {
          path: "$categoryDetails",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $lookup: {
          from: "subcatagorys",
          // The name of the SubCategory collection
          localField: "subsubcategories.subcatagory",
          foreignField: "subcatagory",
          as: "subCategoryDetails"
        }
      },
      {
        $unwind: {
          path: "$subCategoryDetails",
          preserveNullAndEmptyArrays: true
        }
      },
      // Step 6: Group by Type and Category, and build the nested structure
      {
        $group: {
          _id: {
            type: "$type",
            catagory: "$categoryDetails.catagory"
          },
          subcategories: {
            $addToSet: "$subCategoryDetails.subcatagory"
          }
        }
      },
      {
        $group: {
          _id: "$_id.type",
          categories: {
            $push: {
              category: "$_id.catagory",
              subcategories: "$subcategories"
            }
          }
        }
      },
      {
        $project: {
          _id: 0,
          type: "$_id",
          categories: "$categories"
        }
      }
    ]);

    // Step 3: Map the retrieved data to ensure proper sequencing based on the pre-fetched sequences
    const formattedNavData = navData.map((typeData) => {
      const formattedCategories = categoriesInSequence.map((category) => {
        const matchedCategory = typeData.categories.find(
          (cat) => String(cat.category) === String(category.catagory)
        );

        if (matchedCategory) {
          const formattedSubcategories = subcategoriesInSequence
            .filter((subcat) => String(subcat.catagory) === String(category.catagory))
            .map((subcat) => {
              const matchedSubCategory = matchedCategory.subcategories.find((sub) => sub === subcat.subcatagory);
              return matchedCategory.subcategories.find(
                (sub) => String(sub) === String(subcat.subcatagory)
              );
            })
            .filter(Boolean);

          return {
            category: category.catagory,
            subcategories: formattedSubcategories,
          };
        }

        return null;
      }).filter(Boolean);

      return {
        type: typeData.type,
        categories: formattedCategories,
      };
    });

    res.status(200).json({ navData: formattedNavData });
  } catch (error) {
    console.log('Error while fetching all Data from Database', error);
    res.status(500).json({ success: false, message: error });
  }
};



exports.getNavBarDataForRetail = async (req, res) => {
  try {
    // Step 1: Retrieve categories and subcategories in the required sequence
    const categoriesInSequence = await Catagory.find({}).sort({ sequence: 1 }).select('_id catagory');
    const subcategoriesInSequence = await SubCatagory.find({}).sort({ sequence: 1 }).select('_id subcatagory catagory');

    // Step 2: Get the nav data by types
    const navData = await Type.aggregate([
      {
        $match: {
          showNavbar: true
        }
      },
      // Step 2: Lookup SubSubCategories for each Type
      {
        $lookup: {
          from: "subsubcatagorys",
          // The name of the SubSubCategory collection
          localField: "type",
          foreignField: "typeName",
          as: "subsubcategories"
        }
      },
      //Step 3: Unwind the subsubcategories array
      {
        $unwind: {
          path: "$subsubcategories",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $lookup: {
          from: "catagorys",
          // The name of the Category collection
          localField: "subsubcategories.catagory",
          foreignField: "catagory",
          as: "categoryDetails"
        }
      },
      {
        $unwind: {
          path: "$categoryDetails",
          preserveNullAndEmptyArrays: true
        }
      },
      {
        $lookup: {
          from: "subcatagorys",
          // The name of the SubCategory collection
          localField: "subsubcategories.subcatagory",
          foreignField: "subcatagory",
          as: "subCategoryDetails"
        }
      },
      {
        $unwind: {
          path: "$subCategoryDetails",
          preserveNullAndEmptyArrays: true
        }
      },
      // Step 6: Group by Type and Category, and build the nested structure
      {
        $group: {
          _id: {
            type: "$type",
            catagory: "$categoryDetails.catagory"
          },
          subcategories: {
            $addToSet: "$subCategoryDetails.subcatagory"
          }
        }
      },
      {
        $group: {
          _id: "$_id.type",
          categories: {
            $push: {
              category: "$_id.catagory",
              subcategories: "$subcategories"
            }
          }
        }
      },
      {
        $project: {
          _id: 0,
          type: "$_id",
          categories: "$categories"
        }
      }
    ]);

    // Step 3: Map the retrieved data to ensure proper sequencing based on the pre-fetched sequences
    const formattedNavData = navData.map((typeData) => {
      const formattedCategories = categoriesInSequence.map((category) => {
        const matchedCategory = typeData.categories.find(
          (cat) => String(cat.category) === String(category.catagory)
        );

        if (matchedCategory) {
          const formattedSubcategories = subcategoriesInSequence
            .filter((subcat) => String(subcat.catagory) === String(category.catagory))
            .map((subcat) => {
              const matchedSubCategory = matchedCategory.subcategories.find((sub) => sub === subcat.subcatagory);
              return matchedCategory.subcategories.find(
                (sub) => String(sub) === String(subcat.subcatagory)
              );
            })
            .filter(Boolean);

          return {
            category: category.catagory,
            subcategories: formattedSubcategories,
          };
        }

        return null;
      }).filter(Boolean);

      return {
        type: typeData.type,
        categories: formattedCategories,
      };
    });

    res.status(200).json({ navData: formattedNavData });
  } catch (error) {
    console.log('Error while fetching all Data from Database', error);
    res.status(500).json({ success: false, message: error });
  }
}



