const jwt = require("jsonwebtoken");
const { promisify } = require("util");
const Campaigns = require("../models/campaignsModel");
const Prizes = require("../models/prizeModel");
const CampaignCategories = require("../models/campaignCategoryModel");
const Products = require("../models/productsModel");
const User = require("../models/userModel");
const moment = require("moment/moment");
const sharp = require("sharp");
const fs = require("fs");
const writeFileAsync = promisify(fs.writeFile);

const verification = async (token) => {
  try {
    // if (token.startsWith("Bearer ")) {
    //   TokenArray = token.split(" ");
    //   const decoded = jwt.verify(TokenArray[1], process.env.JWT_SECRET);
    //   const user = await User.findOne({ _id: decoded.id });
    //   if (user !== null && decoded.exp > Date.now() / 1000) {
    //     return true;
    //   } else {
    //     return false;
    //   }
    // } else {
    //   return false;
    // }
    return true;
  } catch (error) {
    return false;
  }
};

exports.getCampaigns = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const campaigns = await Campaigns.find({ IsDelete: false });

    // Map each campaign to a promise that resolves with the modified campaign data
    const campaignsWithDetails = await Promise.all(
      campaigns.map(async (item) => {
        const prize = await Prizes.findById(item.prizeId);
        const campaigncategory = await CampaignCategories.findById(
          item.campaignCategoryId
        );
        const product = await Products.findById(item.productId);
        return {
          ...item._doc,
          campaignCategoryName: campaigncategory ? campaigncategory.name : null,
          prizeName: prize ? prize.name : null,
          productName: product ? product.name : null,
        };
      })
    );

    res.setHeader("Content-Type", "application/javascript");
    res.status(200).send({
      message: "",
      IsSuccess: true,
      Status_Code: 200,
      Data: campaignsWithDetails,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.getCampaignsDropdown = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const campaigns = await Campaigns.find(
      { IsDelete: false }, // Query criteria
      { name: 1, _id: 1 } // Projection to include only name and _id fields
    );

    res.setHeader("Content-Type", "application/javascript");
    res.status(200).send({
      message: "",
      IsSuccess: true,
      Status_Code: 200,
      Data: campaigns,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.getOutOfStockCampaignsDropdown = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const campaigns = await Campaigns.find(
      { IsDelete: false }, // Query criteria
      { name: 1, _id: 1, drawDateTime: 1 } // Projection to include only name and _id fields
    );

    const outOfStock = campaigns.filter((item) => {
      return (
        moment(item.drawDateTime).format("YYYY-MM-DDThh:mm") <
        moment().format("YYYY-MM-DDThh:mm")
      );
    });

    res.setHeader("Content-Type", "application/javascript");
    res.status(200).send({
      message: "",
      IsSuccess: true,
      Status_Code: 200,
      Data: outOfStock,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.getInStockCampaigns = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const campaigns = await Campaigns.find({ IsDelete: false });

    const inStock = campaigns.filter((item) => {
      return (
        moment(item.drawDateTime).format("YYYY-MMM-DDThh:mm") >=
        moment().format("YYYY-MMM-DDThh:mm")
      );
    });

    // Map each campaign to a promise that resolves with the modified campaign data
    const campaignsWithDetails = await Promise.all(
      inStock.map(async (item) => {
        const product = await Products.findById(item.productId);
        return {
          ...item._doc,
          productPrice: product ? product.price : null,
        };
      })
    );

    // console.log(campaignsWithDetails);
    res.setHeader("Content-Type", "application/javascript");
    res.status(200).send({
      message: "",
      IsSuccess: true,
      Status_Code: 200,
      Data: campaignsWithDetails,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.getOutOfStockCampaigns = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const campaigns = await Campaigns.find({ IsDelete: false });

    const outOfStock = campaigns.filter((item) => {
      return (
        moment(item.drawDateTime).format("YYYY-MMM-DDThh:mm") <
        moment().format("YYYY-MMM-DDThh:mm")
      );
    });

    res.setHeader("Content-Type", "application/javascript");
    res.status(200).send({
      message: "",
      IsSuccess: true,
      Status_Code: 200,
      Data: outOfStock,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.saveCampaign = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const body = req.body;
    const imagesArray = [];
    //Save Images
    if (req.body.images && req.body.images.length > 0) {
      for (let i = 0; i < req.body.images.length; i++) {
        const imageData = req.body.images[i];
        if (imageData !== null) {
          var base64Data = imageData.File.replace(
            /^data:image\/(png|jpeg|jpg);base64,/,
            ""
          );

          const buffer = Buffer.from(base64Data, "base64");

          // Resize the image to 600x400 pixels using sharp
          const resizedImage = await sharp(buffer).resize(600, 400).toBuffer();

          try {
            await writeFileAsync(
              `assets/uploads/campaigns/${body.name.replace(" ", "_")}_${
                i + 1
              }.jpeg`,
              resizedImage
            );
            imagesArray.push(
              `http://85.239.232.188:${
                process.env.PORT
              }/assets/uploads/campaigns/${body.name.replace(" ", "_")}_${
                i + 1
              }.jpeg`
              // `${req.protocol}://${req.hostname}:${
              //   process.env.PORT
              // }/assets/uploads/campaigns/${body.name.replace(" ", "_")}_${
              //   i + 1
              // }.jpeg`
            );
            console.log("Image saved successfully.");
          } catch (err) {
            console.error("Error writing the file:", err);
          }
        }
      }
    }
    const data = {
      name: body.name,
      description: body.description,
      campaignCategoryId: body.campaignCategoryId,
      drawType: body.drawType,
      drawDateTime: body.drawDateTime,
      imageURL: req.body.images !== null ? imagesArray : [],
      counterBackgroundColor: body.counterBackgroundColor,
      productId: body.productId,
      prizeId: body.prizeId,
      IsActive: body.IsActive,
      IsDelete: false,
      CreatedBy: body.User,
      CreatedOn: moment().format("YYYY-MMM-DD"),
    };
    const newCampaign = await Campaigns.create(data);
    const prize = await Prizes.findById(newCampaign.prizeId);
    const campaigncategory = await CampaignCategories.findById(
      newCampaign.campaignCategoryId
    );
    const product = await Products.findById(newCampaign.productId);
    const newData = {
      ...newCampaign._doc,
      campaignCategoryName: campaigncategory ? campaigncategory.name : null,
      prizeName: prize ? prize.name : null,
      productName: product ? product.name : null,
    };
    res.json({
      message: "New Campaign created successfully.",
      IsSuccess: true,
      Status_Code: 200,
      Data: newData,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.editCampaign = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const body = req.body;
    const imagesArray = [];

    if (req.body.images !== null && req.body.images.length > 0) {
      for (let i = 0; i < req.body.images.length; i++) {
        const imageData = req.body.images[i];
        if (imageData !== null) {
          var base64Data = imageData.File.replace(
            /^data:image\/(png|jpeg|jpg);base64,/,
            ""
          );

          const buffer = Buffer.from(base64Data, "base64");

          // Resize the image to 600x400 pixels using sharp
          const resizedImage = await sharp(buffer).resize(600, 400).toBuffer();

          try {
            await writeFileAsync(
              `assets/uploads/campaigns/${body.name.replace(" ", "_")}_${
                i + 1
              }.jpeg`,
              resizedImage
            );
            imagesArray.push(
              // http://85.239.232.188:
              `${req.protocol}://${req.hostname}:${
                process.env.PORT
              }/assets/uploads/campaigns/${body.name.replace(" ", "_")}_${
                i + 1
              }.jpeg`
            );
            console.log("Image saved successfully.");
          } catch (err) {
            console.error("Error writing the file:", err);
          }
        }
      }
      const updateCampaign = await Campaigns.updateOne(
        { _id: body._id },
        {
          $set: {
            name: body.name,
            description: body.description,
            campaignCategoryId: body.campaignCategoryId,
            imageURL: imagesArray,
            drawType: body.drawType,
            drawDateTime: body.drawDateTime,
            counterBackgroundColor: body.counterBackgroundColor,
            productId: body.productId,
            prizeId: body.prizeId,
            IsActive: body.IsActive,
            ModifiedBy: body.User,
            ModifiedOn: moment().format("YYYY-MMM-DD"),
          },
        }
      );
    } else {
      const updateCampaign = await Campaigns.updateOne(
        { _id: body._id },
        {
          $set: {
            name: body.name,
            description: body.description,
            campaignCategoryId: body.campaignCategoryId,
            // prize: body.prize,
            drawType: body.drawType,
            drawDateTime: body.drawDateTime,
            counterBackgroundColor: body.counterBackgroundColor,
            productId: body.productId,
            prizeId: body.prizeId,
            IsActive: body.IsActive,
            ModifiedBy: body.User,
            ModifiedOn: moment().format("YYYY-MMM-DD"),
          },
        }
      );
    }

    const updatedCampaign = await Campaigns.find({ _id: body._id });
    // Map each campaign to a promise that resolves with the modified campaign data
    const campaignsWithDetails = await Promise.all(
      updatedCampaign.map(async (item) => {
        const prize = await Prizes.findById(item.prizeId);
        const campaigncategory = await CampaignCategories.findById(
          item.campaignCategoryId
        );
        const product = await Products.findById(item.productId);
        return {
          ...item._doc,
          campaignCategoryName: campaigncategory ? campaigncategory.name : null,
          prizeName: prize ? prize.name : null,
          productName: product ? product.name : null,
        };
      })
    );
    res.json({
      message: "Campaign updated successfully.",
      IsSuccess: true,
      Status_Code: 200,
      Data: campaignsWithDetails[0],
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};

exports.deleteCampaign = async (req, res, next) => {
  const isVerified = await verification(req.headers["authorization"]);
  if (isVerified) {
    const body = req.body;
    const updateCampaign = await Campaigns.updateOne(
      { _id: body._id },
      {
        $set: {
          IsActive: body.IsActive,
          IsDelete: body.IsDelete,
          ModifiedBy: body.User,
          ModifiedOn: moment().format("YYYY-MMM-DD"),
        },
      }
    );
    const updatedCampaign = await Campaigns.findOne({
      _id: body._id,
    });
    res.json({
      message: "Campaign deleted successfully.",
      IsSuccess: true,
      Status_Code: 200,
      Data: updatedCampaign,
    });
  } else {
    res.setHeader("Content-Type", "application/javascript");
    res.status(401).send({
      message: "Unauthorized access! Please Login again.",
      IsSuccess: false,
      Status_Code: 401,
      Data: null,
    });
  }
};
