const sgMail = require('@sendgrid/mail')
const { SENDGRID_API_KEY, BASE_URL, portalName, SEND_EMAIL } = require("../constants/constant")
const { sendPartnerMail,activateProfile, invoiceTable} = require("../constants/emailTemplates")
const fs = require("fs");
const CustomerOrderProduct = require('../models/customerOrderProduct')
const CustomerOrder = require('../models/customerOrder')
const Product = require('../models/product')
const Recipe = require('../models/recipe')
const path = require("path");
const { empty } = require('../Helpers/Common');
const nodemailer = require('nodemailer');

const transporter = nodemailer.createTransport({
  host: 'mail.signwisesolutions.com', // Replace with your domain's mail server (WHM SMTP host)
  port: 465, // 465 for secure SMTP (SSL), or 587 for TLS
  secure: true, // Use true for 465, false for other ports
  auth: {
    user: 'noreply@signwisesolutions.com', 
    pass: 'signwise@2024', 
  },
});


const Settings = require("../models/settings");
const Requests = require('../models/request')
const logoPath = path.join(__dirname, "../build/images/logo.png");
const logo = fs.readFileSync(logoPath);

const sendMail = async (req, reply) => {
  sgMail.setApiKey(SENDGRID_API_KEY)
  console.log("######Request",req.body);
  let { id, allInstallationCompleted } = req.body;

  let orderData = await CustomerOrder.getCustomerOrderRequestId(id)
  let order_id = orderData.id
  // const UNITS = [
  //   { id: 1, name: 'Square feet', short_name: 'Sq ft', unit_id: 1 },
  //   { id: 2, name: 'Linear feet', short_name: 'Lin ft', unit_id: 1 },
  //   { id: 3, name: 'Square inches', short_name: 'Sq in', unit_id: 1 },
  //   { id: 4, name: 'Unit', short_name: 'Unit', unit_id: 2 },
  //   { id: 5, name: 'Gallons', short_name: 'Gal', unit_id: 3 },
  //   { id: 6, name: 'Quarts', short_name: 'Qt', unit_id: 3 },
  //   { id: 7, name: 'Milliliter', short_name: 'ml', unit_id: 3 },
  //   { id: 8, name: 'Ounce', short_name: 'oz', unit_id: 3 },
  //   { id: 9, name: 'Kilogram', short_name: 'kg', unit_id: 4 },
  //   { id: 10, name: 'Gram', short_name: 'g', unit_id: 4 },
  //   { id: 11, name: 'Milligram', short_name: 'mg', unit_id: 4 },
  // ];

  const UNITS = [
    { id: 1, name: 'Square feet', short_name: 'Sq ft', unit_id: 1 },
    { id: 2, name: 'Linear feet', short_name: 'Lin ft', unit_id: 1 },
    { id: 3, name: 'Square inches', short_name: 'Sq in', unit_id: 1 },
    { id: 4, name: 'Unit', short_name: 'Unit', unit_id: 2 },
    { id: 5, name: 'Gallons', short_name: 'Gal', unit_id: 3 },
    { id: 6, name: 'Quarts', short_name: 'Qt', unit_id: 3 },
    { id: 7, name: 'Milliliter', short_name: 'ml', unit_id: 3 },
    { id: 8, name: 'Liter', short_name: 'L', unit_id: 3 },
    { id: 9, name: 'Pint', short_name: 'pt', unit_id: 3 },
    { id: 10, name: 'Half Pint', short_name: 'half-pt', unit_id: 3 },
    { id: 11, name: 'Ounce', short_name: 'oz', unit_id: 3 },
    { id: 12, name: 'Kilogram', short_name: 'kg', unit_id: 4 },
    { id: 13, name: 'Gram', short_name: 'g', unit_id: 4 },
    { id: 14, name: 'Milligram', short_name: 'mg', unit_id: 4 },
    { id: 15, name: 'Each', short_name: 'EA', unit_id: 2 },


];

  if (!empty(order_id)) {
    if(orderData?.project_category == 12 && !empty(allInstallationCompleted)){
      let jobCostResults = await CustomerOrderProduct.getJobCostProductsbyId(order_id);
      let jobcostService = await Requests.getRequestServices(orderData?.request_id);

      if (jobCostResults && jobCostResults.length > 0) {
        jobCostResults = jobCostResults.map(mat => {
          // Parse values or default to 0
          const unitPrice = Number(mat.unit_price || 0);
          const total = Number(mat.total || 0);
          const materialMarkupPercentage = Number(mat.material_markup_percentage || 0);
          const finalUnitPrice = unitPrice + (unitPrice * materialMarkupPercentage / 100);
          const finalTotalPrice = total + (total * materialMarkupPercentage / 100);
          return {
            ...mat,
            oldUnitPrice:unitPrice,
            oldTotal:total,
            unit_price: parseFloat(unitPrice.toFixed(2)),
            total: parseFloat(total.toFixed(2)), 
            new_unit_price: parseFloat(finalUnitPrice.toFixed(2)),
            new_total: parseFloat(finalTotalPrice.toFixed(2)), 
          };
        });
        orderData['jobcost_product'] = jobCostResults;
      }else{
        orderData['jobcost_product'] = [];
      }
        
      if (jobcostService && jobcostService.length > 0) {
        jobcostService = jobcostService?.map(service => {
          const totalCost = parseFloat(service.service_original_cost || 0);
          const jobcostQuantity = parseFloat(service.jobcost_quantity || 0);
          const totalServiceCost = totalCost * jobcostQuantity;
      
          return {
            ...service,
            total_service_cost: totalServiceCost.toFixed(2),
          };
        });
        orderData['jobcost_service'] = jobcostService;
      }else{
        orderData['jobcost_service'] = [];
      }

      let jobcostTotal = 0
      let jobcostServiceTotal = 0
      if(jobCostResults && jobCostResults?.length > 0){
        jobcostTotal = jobCostResults?.reduce((sum, product) => {
          return sum + (product.total || 0);
        }, 0);
      }
      if(jobcostService && jobcostService?.length > 0){
          jobcostServiceTotal = jobcostService?.filter(it=>it.total_cost == 0)?.reduce((sum, product) => {
          return sum + (parseFloat(product.total_service_cost) || 0);
        }, 0);
      }
      const total = parseFloat(orderData?.total) || 0;
      const extraDiscount = parseFloat(orderData?.extra_discount) || 0;
      const taxAmount = parseFloat(orderData?.tax_amount) || 0;
      const jobCostTotalValue = parseFloat(jobcostTotal) || 0;
      const jobCostServiceTotalValue = parseFloat(jobcostServiceTotal) || 0;
      
      let subTotal = total + jobCostTotalValue + jobCostServiceTotalValue;
      let grandTotal = (subTotal - extraDiscount) + taxAmount;
      
      // Assign formatted values
      orderData.sub_total = jobCostTotalValue;
      orderData.labourCost = jobCostServiceTotalValue;
      orderData.extra_discount = extraDiscount;
      orderData.tax_amount = taxAmount;
      orderData.total = grandTotal;      
    }else{
      let results = await CustomerOrderProduct.getCustomerOrderProductsbyId(order_id)
      let allProductServices = [];
      if (!empty(results)) {
        for (const product of results) {
            let services = await Product.getServiceByProduct(product.product_id);
            
            let resultArray = []; 

            for (let serviceData of services) {
                let subResult = await Requests.getRequestServices(orderData?.request_id, serviceData.id,product.product_id,product.product_index);
                console.log('subResult-----------',subResult);
                const newSubResult = subResult?.map(service => ({
                  ...service,
                  qtyData: product.quantity,
                  locationQuantity: product.locationQuantity || 1
                }));
                if (!empty(newSubResult)) {
                    resultArray.push(newSubResult);
                }
            }
            
            product.services = resultArray.flatMap(service => service);

            product.services.forEach(service => {
              const newQty = parseFloat((service.prQty * product.quantity * product.locationQuantity)?.toFixed(2));
              const quantityDifference = service.qty - newQty;
              if (newQty !== service.qty) {
                allProductServices.push({
                  ...service,
                  quantityDifference: quantityDifference,
                  total_cost: service.unit_cost * quantityDifference
                });
              }
            });
        }
        console.log('cust_product results---', results);
        orderData['cust_product'] = results;
      } else {
          orderData['cust_product'] = [];
      }
      orderData['allProductServices'] = allProductServices;
    }
  } 

const unitMapping = UNITS.reduce((acc, unit) => {
  acc[unit.id] = unit.short_name;
  return acc;
}, {});


if(orderData?.project_category == 12 && !empty(allInstallationCompleted)){
  orderData?.jobcost_product?.forEach(product => {
    const unitToUse = product?.partial_unit ? product?.partial_unit : product?.unit;
    if (unitToUse) {
      product.unitData = unitMapping[unitToUse] || product.unit;
    }
  });
}else{
  orderData.cust_product.forEach(product => {
    const unitToUse = product?.partial_unit ? product?.partial_unit : product?.unit;
    if (unitToUse) {
      product.unitData = unitMapping[unitToUse] || product.unit;
    }
  });
  let result = await Requests.getAllRequests(orderData.requestId, 1, 1)

  orderData.labourCost=result.data[0].labour_cost

  let requestServices = await Requests.getRequestServices(orderData.requestId)
  const newRequestServices=requestServices.filter(ord=>ord.recipe_id===null)

  orderData.requestServices=newRequestServices
}

let profileData = await Settings.getCompanyProfileDetails()
orderData.companyProfile = profileData[0]
  delete orderData?.addl_amount
  delete orderData?.grandTotal
  let message = invoiceTable(orderData);
  // let message = activateProfile();

////send grid
  // const msg = {
  //   to: orderData.clientEmail, // 'albin.joy@skyniche.com', //orderData.clientEmail, // Change to your recipient
  //   from: 'nushara@skyniche.com', // Change to your verified sender
  //   subject: 'INVOICE' ,
  //   text: 'You are invited to join' + portalName,
  //   html: message,
  // }
  // let flag=0
  // sgMail
  //   .send(msg)
  //   .then(() => {
  //     console.log('Email sent')
  //    flag=1
  //   })
  //   .catch((error) => {
  //     console.error("##########Err",error)
  //   })
  //   if(flag===1){
  //     reply.send({ status: 1, message: "Email send successfully" });
  //   }
  //   else{
  //     reply.send({ status: 1, message: "Email send successfully" });
  //   }


  //node mailer

  const mailOptions = {
    to:  orderData.clientEmail, // 'albin.joy@skyniche.com', // Change to your recipient
    from: '"SignWise Solutions" <noreply@signwisesolutions.com>', //'nushara@skyniche.com', // Change to your verified sender
    subject: 'INVOICE' ,
    text: 'You are invited to join' + portalName,
    html: message,
  }
  try {
    if(SEND_EMAIL){

    await transporter.sendMail(mailOptions);
    console.log('Email sent');
    reply.send({ status: 1, message: "Email send successfully" });
    }else{
      reply.send({ status: 1, message: "Email not sended" });
    }
    
  } catch (error) {
    console.error('##########Err', error);
    reply.send({ status: 1, message: "Failed Sending Email" });
  }
}

const sendMaterialCostUpdateMail = async (req, reply) => {
  try{
    sgMail.setApiKey(SENDGRID_API_KEY)
    console.log("######sendMaterialCostUpdateMail",req.body);
    let { id } = req.body;
    let products = await Product.getProductById(id);
    let allRecipies = await Product.fetchRecipesBasedOnMaterial(id);

    for (let j = 0; j < allRecipies.length; j++) {
      let allProducts = await Product.fetchAllProductsByRecipe(true, false, allRecipies[j].recipe_id);
      for (let k = 0; k < allProducts.length; k++) {
        let product = CustomerOrderProduct.getCustomerOrderProductsbyId(order_id)
        await CustomerOrderProduct.getProductById(allProducts[k].product_id);
      }
    }
    let message = invoiceTable(orderData);
    //send grid
    // const msg = {
    //   to: orderData.clientEmail, // Change to your recipient
    //   from: 'nushara@skyniche.com', // Change to your verified sender
    //   subject: 'INVOICE' ,
    //   text: 'You are invited to join' + portalName,
    //   html: message,
    // }
    // let flag=0
    // sgMail
    //   .send(msg)
    //   .then(() => {
    //     console.log('Email sent')
    //   flag=1
    //   })
    //   .catch((error) => {
    //     console.error("##########Err",error)
    //   })
    //   if(flag===1){
    //     reply.send({ status: 1, message: "Email send successfully" });
    //   }
    //   else{
    //     reply.send({ status: 1, message: "Email send successfully" });
    //   }

     //node mailer

  const mailOptions = {
    to:  orderData.clientEmail , //orderData.clientEmail, // 'albin.joy@skyniche.com', //orderData.clientEmail, // Change to your recipient
    from: '"SignWise Solutions" <noreply@signwisesolutions.com>', //'nushara@skyniche.com', // Change to your verified sender
    subject: 'INVOICE' ,
    text: 'You are invited to join' + portalName,
    html: message,
  }
  try {
    if(SEND_EMAIL){
    await transporter.sendMail(mailOptions);
    console.log('Email sent');
    reply.send({ status: 1, message: "Email send successfully" });
    }else{
    reply.send({ status: 1, message: "Email not sended" });

    }
  } catch (error) {
    reply.send({ status: 1, message: "Failed Sending Email" });
    console.error('##########Err', error);
    
  }
  }catch(error){
    console.log('sendMaterialCostUpdateMail error : ',error);
  }
}

const sendServiceCostUpdateMail = async (req, reply) => {
  sgMail.setApiKey(SENDGRID_API_KEY)
  console.log("######Request",req.body);
  let { id } = req.body;

  let orderData = await CustomerOrder.getCustomerOrderRequestId(id)
  let order_id = orderData.id
  // const UNITS = [
  //   { id: 1, name: 'Square feet', short_name: 'Sq ft', unit_id: 1 },
  //   { id: 2, name: 'Linear feet', short_name: 'Lin ft', unit_id: 1 },
  //   { id: 3, name: 'Square inches', short_name: 'Sq in', unit_id: 1 },
  //   { id: 4, name: 'Unit', short_name: 'Unit', unit_id: 2 },
  //   { id: 5, name: 'Gallons', short_name: 'Gal', unit_id: 3 },
  //   { id: 6, name: 'Quarts', short_name: 'Qt', unit_id: 3 },
  //   { id: 7, name: 'Milliliter', short_name: 'ml', unit_id: 3 },
  //   { id: 8, name: 'Ounce', short_name: 'oz', unit_id: 3 },
  //   { id: 9, name: 'Kilogram', short_name: 'kg', unit_id: 4 },
  //   { id: 10, name: 'Gram', short_name: 'g', unit_id: 4 },
  //   { id: 11, name: 'Milligram', short_name: 'mg', unit_id: 4 },
  // ];

  const UNITS = [
    { id: 1, name: 'Square feet', short_name: 'Sq ft', unit_id: 1 },
    { id: 2, name: 'Linear feet', short_name: 'Lin ft', unit_id: 1 },
    { id: 3, name: 'Square inches', short_name: 'Sq in', unit_id: 1 },
    { id: 4, name: 'Unit', short_name: 'Unit', unit_id: 2 },
    { id: 5, name: 'Gallons', short_name: 'Gal', unit_id: 3 },
    { id: 6, name: 'Quarts', short_name: 'Qt', unit_id: 3 },
    { id: 7, name: 'Milliliter', short_name: 'ml', unit_id: 3 },
    { id: 8, name: 'Liter', short_name: 'L', unit_id: 3 },
    { id: 9, name: 'Pint', short_name: 'pt', unit_id: 3 },
    { id: 10, name: 'Half Pint', short_name: 'half-pt', unit_id: 3 },
    { id: 11, name: 'Ounce', short_name: 'oz', unit_id: 3 },
    { id: 12, name: 'Kilogram', short_name: 'kg', unit_id: 4 },
    { id: 13, name: 'Gram', short_name: 'g', unit_id: 4 },
    { id: 14, name: 'Milligram', short_name: 'mg', unit_id: 4 },
    { id: 15, name: 'Each', short_name: 'EA', unit_id: 2 },

];

  if (!empty(order_id)) {
      let results = await CustomerOrderProduct.getCustomerOrderProductsbyId(order_id)
      let allProductServices = [];
      if (!empty(results)) {
        for (const product of results) {
            let services = await Product.getServiceByProduct(product.product_id);
            
            let resultArray = []; 

            for (let serviceData of services) {
                let subResult = await Requests.getRequestServices(orderData?.request_id, serviceData.id,product.product_id,product.product_index);
                console.log('subResult-----------',subResult);
                const newSubResult = subResult?.map(service => ({
                  ...service,
                  qtyData: product.quantity,
                  locationQuantity: product.locationQuantity || 1
                }));
                if (!empty(newSubResult)) {
                    resultArray.push(newSubResult);
                }
            }
            
            product.services = resultArray.flatMap(service => service);

            product.services.forEach(service => {
              const newQty = parseFloat((service.prQty * product.quantity * product.locationQuantity)?.toFixed(2));
              const quantityDifference = service.qty - newQty;
              if (newQty !== service.qty) {
                allProductServices.push({
                  ...service,
                  quantityDifference: quantityDifference,
                  total_cost: service.unit_cost * quantityDifference
                });
              }
            });
        }
        console.log('cust_product results---', results);
        orderData['cust_product'] = results;
      } else {
          orderData['cust_product'] = [];
          orderData['cust_product'] = [];
          
        orderData['cust_product'] = [];
          
      }
      orderData['allProductServices'] = allProductServices;

  } 

const unitMapping = UNITS.reduce((acc, unit) => {
  acc[unit.id] = unit.short_name;
  return acc;
}, {});

orderData.cust_product.forEach(product => {
  if (product.unit !== undefined) {
      product.unitData = unitMapping[product.unit] || product.unit;
  }
});
let result = await Requests.getAllRequests(orderData.requestId, 1, 1)

orderData.labourCost=result.data[0].labour_cost

let requestServices = await Requests.getRequestServices(orderData.requestId)
const newRequestServices=requestServices.filter(ord=>ord.recipe_id===null)

orderData.requestServices=newRequestServices

let profileData = await Settings.getCompanyProfileDetails()
orderData.companyProfile = profileData[0]

  let message = invoiceTable(orderData);
  // let message = activateProfile();


  // const msg = {
  //   to: orderData.clientEmail, // Change to your recipient
  //   from: 'nushara@skyniche.com', // Change to your verified sender
  //   subject: 'INVOICE' ,
  //   text: 'You are invited to join' + portalName,
  //   html: message,
  // }
  // let flag=0
  // sgMail
  //   .send(msg)
  //   .then(() => {
  //     console.log('Email sent')
  //    flag=1
  //   })
  //   .catch((error) => {
  //     console.error("##########Err",error)
  //   })
  //   if(flag===1){
  //     reply.send({ status: 1, message: "Email send successfully" });
  //   }
  //   else{
  //     reply.send({ status: 1, message: "Email send successfully" });
  //   }

       //node mailer

       const mailOptions = {
        to:  orderData.clientEmail , //orderData.clientEmail, // 'albin.joy@skyniche.com', //orderData.clientEmail, // Change to your recipient
        from: '"SignWise Solutions" <noreply@signwisesolutions.com>', //'nushara@skyniche.com', // Change to your verified sender
        subject: 'INVOICE' ,
        text: 'You are invited to join' + portalName,
        html: message,
      }
      try {
        if(SEND_EMAIL){
        await transporter.sendMail(mailOptions);
        console.log('Email sent');
    reply.send({ status: 1, message: "Email send successfully" });
  }else{
          reply.send({ status: 1, message: "Email not sended" });

        }
        
      } catch (error) {
        console.error('##########Err', error);
    reply.send({ status: 1, message: "Failed Sending Email" });
       
      }
}
module.exports = { sendMail, sendServiceCostUpdateMail, sendMaterialCostUpdateMail }