const { default: axios } = require('axios');
const customerType = require('../models/customerType');
const { getNewAccessToken, companyId, PRODUCTION } = require('../quickbook/quickbook');


///////////////////////////qb
const findTermsByName = async (termName) => {
    try {
        const accessToken = await getNewAccessToken();
      // Construct the URL to query terms by name
      const url = PRODUCTION
      ? `https://quickbooks.api.intuit.com/v3/company/${companyId}/query?query=SELECT * FROM Term WHERE Name = '${termName}'`
      : `https://sandbox-quickbooks.api.intuit.com/v3/company/${companyId}/query?query=SELECT * FROM Term WHERE Name = '${termName}'`;
  
      // Make the API request
      const response = await axios.get(url, {
        headers: {
          'Authorization': `Bearer ${accessToken}`,
          'Accept': 'application/json',
          'Content-Type': 'application/json',
        },
      });
  
      // Check if terms were found
      if (response.data.QueryResponse && response.data.QueryResponse.Term) {
        console.log("response",response.data.QueryResponse.Term[0])
        return response.data.QueryResponse.Term[0].Id; // Return the term data found
      } else {
        return null; // No terms found
      }
    } catch (error) {
      console.error('Error finding terms:', error.response ? error.response.data : error.message);
      return null // Throw error if any
    }
};

// (async () => {
//     const terms = await findTermsByName('NET 60');
//     console.log(terms,'terms');
// })();

const addPaymentTermToQB = async (data) => {
    try {
      const accessToken = await getNewAccessToken();
  
      let payload = {
        Name: data.name,
        Active: true
      };
  
      // Due in fixed number of days
      if (data.payment_type == "days") {
        payload.Type = "Standard";
        payload.DueDays = Number(data.payment_days_only);
      } 
      // Due by certain day of month
      else {
        payload.Type = "DateDriven";
        payload.DayOfMonthDue = Number(data.payment_months);   // should be day of month
        payload.DueNextMonthDays = Number(data.payment_days);  // issued within X days
      }
      console.log('payload for addPaymentTermToQB',payload)
  
      const url = PRODUCTION
        ? `https://quickbooks.api.intuit.com/v3/company/${companyId}/term`
        : `https://sandbox-quickbooks.api.intuit.com/v3/company/${companyId}/term`;
  
      const response = await axios.post(url, payload, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          Accept: "application/json",
          "Content-Type": "application/json",
        },
      });
  
      console.log("QB Term Created:", response.data);
      return response.data?.Term?.Id || null;
    } catch (error) {
      console.error(
        "Error creating QB term:",
        JSON.stringify(error.response?.data, null, 2)
      );
      return null;
    }
  };

  const updatePaymentTermInQB = async (data) => {
    try {
      const accessToken = await getNewAccessToken();
  
      if (!data.quickbookId) {
        throw new Error("quickbookId is required for updating term");
      }
  
      const fetchUrl = PRODUCTION
        ? `https://quickbooks.api.intuit.com/v3/company/${companyId}/term/${data.quickbookId}`
        : `https://sandbox-quickbooks.api.intuit.com/v3/company/${companyId}/term/${data.quickbookId}`;
  
      const fetchResponse = await axios.get(fetchUrl, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          Accept: "application/json",
          "Content-Type": "application/json",
        },
      });
  
      const existingTerm = fetchResponse.data?.Term;
  
      if (!existingTerm?.Id || existingTerm?.SyncToken == null) {
        throw new Error("Unable to fetch existing QuickBooks term or SyncToken");
      }
  
      let payload = {
        Id: existingTerm.Id,
        SyncToken: existingTerm.SyncToken,
        Name: data.name,
        Active: true,
        sparse: false,
      };
  
      // clear old mode-specific fields first
      delete payload.DueDays;
      delete payload.DayOfMonthDue;
      delete payload.DueNextMonthDays;
  
      if (data.payment_type == "days") {
        const dueDays = Number(data.payment_days_only);
  
        if (!Number.isInteger(dueDays) || dueDays < 0) {
          throw new Error("payment_days_only must be a valid number");
        }
  
        payload.DueDays = dueDays;
      } else {
        const dayOfMonthDue = Number(data.payment_months);
        const dueNextMonthDays = Number(data.payment_days);
  
        if (!Number.isInteger(dayOfMonthDue) || dayOfMonthDue < 1 || dayOfMonthDue > 31) {
          throw new Error("payment_months must be between 1 and 31");
        }
  
        if (!Number.isInteger(dueNextMonthDays) || dueNextMonthDays < 1) {
          throw new Error("payment_days must be greater than 0");
        }
  
        payload.DayOfMonthDue = dayOfMonthDue;
        payload.DueNextMonthDays = dueNextMonthDays;
      }
  
      console.log("payload for updatePaymentTermInQB", payload);
  
      const updateUrl = PRODUCTION
        ? `https://quickbooks.api.intuit.com/v3/company/${companyId}/term`
        : `https://sandbox-quickbooks.api.intuit.com/v3/company/${companyId}/term`;
  
      const response = await axios.post(updateUrl, payload, {
        headers: {
          Authorization: `Bearer ${accessToken}`,
          Accept: "application/json",
          "Content-Type": "application/json",
        },
      });
  
      console.log("QB Term Updated:", response.data);
      return response.data?.Term?.Id || null;
    } catch (error) {
      console.error(
        "Error updating QB term:",
        JSON.stringify(error.response?.data || error.message, null, 2)
      );
      return null;
    }
  };
//////////////////////////////

const createCustomerType = async (req, res) => {
try {
    const { values } = req.body
    console.log('values', values)
    let data = {
        name: values?.name,
        billing_type: values?.billingType,
        payment_days_only: values?.afterDays ? Number(values.afterDays) : null,
        payment_type: values?.paymentType || null,
        payment_days: values?.paymentDays ? Number(values.paymentDays) : null,
        payment_months: values?.paymentMonths ? Number(values.paymentMonths) : null
    }

    try {
        const quickbookId =values?.quickbookId? values?.quickbookId : await findTermsByName(values?.name)
        if (quickbookId) {
            data.quickbookId = quickbookId
        }else{
            const qbResponse = await addPaymentTermToQB(data)
           if(qbResponse){
            data.quickbookId = qbResponse
           }else{
            data.quickbookId =null
           }
        }
    } catch (error) {
        console.error('Error finding quickbook id:', error.response ? error.response.data : error.message);
       
    }

    const result = await customerType.addCustomerType(data)



    if (result) {
        res.send({status:1,message:"Customer Type Added Successully"})

    }else{
        res.send({status:0,message:"Failed Adding Customer Type"})

    }
} catch (error) {
    res.send({status:0,message:"server error",error:error})
}

}

const findAllCustomersTypes = async (req,res) =>{
    try {
        const result = await customerType.findAllCustomerType()

        if(result){
            res.send({status:1,result:result})
        }else{
            res.send({status:0,message:"not getting data"})

        }
    } catch (error) {
    res.send({status:0,message:"server error",error:error})
        
    }
}


const findCustomerTypeById = async (req,res) =>{
    try {
        const {id}= req.body
        if(!id){
            res.send({status:0,message:"Id not available"})
        }
        const result = await customerType.findCustomerTypeById(id)

        if(result){
            res.send({status:1,message:"success",result:result})
        }else{
            res.send({status:1,message:"not getting data"})
        }
        
    } catch (error) {
        res.send({status:0,message:"server error",error:error})
    }
}

const updateCustomerType = async(req,res)=>{
    try {
        const {values,editId}= req.body

        let data = {
            name: values?.name,
            billing_type: values?.billingType,
            payment_days_only: values?.afterDays ? Number(values.afterDays) : null,
            payment_type: values?.paymentType || null,
            payment_days: values?.paymentDays ? Number(values.paymentDays) : null,
            payment_months: values?.paymentMonths ? Number(values.paymentMonths) : null
        }
        try {
            const quickbookId =values?.quickbookId? values?.quickbookId : await findTermsByName(values?.name)
            console.log('quickbookId 1',quickbookId)
        if(values?.quickbookId){
            data.quickbookId = values?.quickbookId
            const qbupdateRes = await updatePaymentTermInQB(data)
        }
            if (quickbookId) {
                console.log('quickbookId 2',quickbookId)
                data.quickbookId = quickbookId
            }else{
                const qbResponse = await addPaymentTermToQB(data)
                console.log('qbResponse',qbResponse)
               if(qbResponse){
                data.quickbookId = qbResponse
               }else{
                data.quickbookId =null
               }
            }
        } catch (error) {
            console.error('Error finding quickbook id:', error.response ? error.response.data : error.message);
          
        }

        const result = await customerType.editCustomerType(editId,data)
        if (result) {
            res.send({status:1,message:"Customer Type Updated Successully"})
    
        }else{
            res.send({status:0,message:"Failed Updating Customer Type"})
    
        }
    } catch (error) {
    res.send({status:0,message:"server error",error:error})
        
    }
}

const deleteCustomerType = async (req,res) =>{
    try {
        const {deleteId,status}= req.body
        console.log(req.body,'dataaaaaaaaaaa')

        const result = await customerType.deleteCustomerType(deleteId,status)

        if (result) {
            res.send({status:1,message:"Customer Type Deleted Successully"})
    
        }else{
            res.send({status:0,message:"Failed Deleting Customer Type"})
    
        }

    } catch (error) {
    res.send({status:0,message:"server error",error:error})
        
    }
}

module.exports = {
    createCustomerType,
    findAllCustomersTypes,
    findCustomerTypeById,
    updateCustomerType,
    deleteCustomerType
}