const path = require('path');
const { empty } = require('../Helpers/Common');
const signAgreement = require('../models/signAgreement');
const { htmlToPdf } = require('../Helpers/agreementPdf');
const moment = require('moment');
const Admin = require('../models/admin');
const { convertPdfToImage } = require('../Helpers/convertPdfToImage');
const { default: axios } = require('axios');
const fs = require('fs'); // Make sure you're using the synchronous fs
let currentDate = Math.round(moment().valueOf() / 1000);

const getAgreementPdfPath = (id) => path.join(__dirname, '..', 'uploads', 'agreements', `${id}.pdf`);
const getAgreementImagePath = (id) => path.join(__dirname, '..', 'uploads', 'agreements_images', `${id}.png`); // New image path function
const downloadPdfFromSupabase = async (url, templateId) => {
    try {
        console.log("Attempting to download PDF from Supabase, URL:", url);

        if (!url || !url.trim()) {
            throw new Error("Invalid URL provided.");
        }

        // Directly calculate the PDF file path inside this function
        const pdfPath = path.join(__dirname, '..', 'uploads', 'agreements', `${templateId}.pdf`);

        // Ensure the directory for saving the file exists
        const dir = path.dirname(pdfPath);
        if (!fs.existsSync(dir)) {
            fs.mkdirSync(dir, { recursive: true });
            console.log(`Directory created: ${dir}`);
        }

        // Fetch PDF from Supabase with responseType 'arraybuffer'
        const response = await axios.get(url, { responseType: 'arraybuffer' });

        // Log the response size to ensure we received data
        console.log(`Received data size: ${response.data.length} bytes`);

        // Write the response data directly to the calculated local file path
        fs.writeFileSync(pdfPath, response.data);
        console.log(`Download complete, file saved at: ${pdfPath}`);

        // Verify if the file was created correctly
        const fileExists = fs.existsSync(pdfPath);
        console.log(`File exists at ${pdfPath}: ${fileExists}`);

        return pdfPath;  // Return the path for further processing
    } catch (error) {
        console.error("Error in downloadPdfFromSupabase:", error.message);
        throw error;  // Rethrow to ensure the calling function catches the error
    }
};
const getAllAgreements=async(req,res)=>{
    try {
        let result = await signAgreement.getAllAgreements()
        if(result){
            res.send({
                status:1,result
            })
        }else{
        res.send({
            status:0
        })
        }
    } catch (error) {
        console.log(error)
    }
}
const addAgreements = async (req, res) => {
    try {
        const { values, userId } = req.body;
        let template = {};
        template['name'] = values.name;
        template['content'] = values.description; // This should be HTML content from Quill
        template['timestamp'] = currentDate;
        template['updated_on'] = currentDate;
        template['added_by'] = userId;
        template['status'] = 1;
        template['document_type'] = 2;

        if (values.attachmentUrl != null && values.attachmentUrl !== '') {
            template['attachment'] = values.attachmentUrl;
            template['agreement_pdf_path'] = null;  // Nullify `agreement_pdf_path` if `attachmentUrl` is present
        } else {
            template['attachment'] = null; // Nullify `attachment` if no data
        }

        let templateId = await signAgreement.addAgreements(template);
        if (!empty(templateId)) {
            let pdfPath = null;
            let pdfRelative = null;

            if (values.attachmentUrl) {
                // If the document is from Supabase (attachmentUrl provided)
                pdfPath = getAgreementPdfPath(templateId); // Ensure this is a valid path

                // Log pdfPath to check if it's being generated correctly
                console.log('pdfPath (from getAgreementPdfPath):', pdfPath);

                if (!pdfPath || pdfPath === 'undefined') {
                    return res.status(400).send({ status: 0, message: 'PDF path is invalid.' });
                }

                // Download PDF from Supabase to the backend folder
                await downloadPdfFromSupabase(values.attachmentUrl, templateId);

                // Convert PDF to images (all pages)
                const imagePath = getAgreementImagePath(templateId);
                await convertPdfToImage(pdfPath, imagePath);

                // Collect the generated image paths
                const imagePaths = fs.readdirSync(path.dirname(imagePath))
                    .filter(file => file.startsWith(path.basename(imagePath)))
                    .map(file => path.join('uploads', 'agreements_images', file)); // Collect image paths in an array

                // Store the generated images in the database using bulk insert
                await signAgreement.storeAgreementImage(templateId, imagePaths);  // Store multiple images

                // Remove the downloaded PDF after conversion
                // fs.unlinkSync(pdfPath);  // Delete the PDF file after conversion
            } else {
                // If `agreement_pdf_path` is provided (local PDF file)
                // Fix: Use a proper file path instead of using values.description for file path
                pdfPath = path.join(__dirname, '..', 'uploads', 'agreements', `${templateId}.pdf`); // Correct the file path

                console.log('Corrected pdfPath:', pdfPath); // Log to ensure it's correct

                // **Step 1: Convert HTML content to PDF first**
                pdfRelative = await htmlToPdf(values.description, pdfPath); // Generate PDF from HTML content

                if (pdfRelative) {
                    // **Step 2: Store the generated PDF path in the database**
                    await signAgreement.updateAgreements(templateId, { agreement_pdf_path: pdfRelative });

                    // **Step 3: Convert the generated PDF to images (all pages)**
                    const imagePath = getAgreementImagePath(templateId);
                    await convertPdfToImage(pdfRelative, imagePath);

                    // Collect the generated image paths
                    const imagePaths = fs.readdirSync(path.dirname(imagePath))
                        .filter(file => file.startsWith(path.basename(imagePath)))
                        .map(file => path.join('uploads', 'agreements_images', file)); // Collect image paths in an array

                    // Store the generated images in the database using bulk insert
                    await signAgreement.storeAgreementImage(templateId, imagePaths);  // Store multiple images
                } else {
                    return res.status(500).send({ status: 0, message: 'Failed to generate PDF from HTML content.' });
                }
            }

            // Notification Logic
            let notificationMsg = `New sign agreement <strong>${template['name']}</strong> has been created.`
            let notificationURL = 'sign-agreements';
            if (userId != 1) {
                await Admin.incrementField(userId, 'noti_count', 1);
                let notidata = {
                    user_id: userId,
                    url: notificationURL,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId
                }
                await Admin.addNotification(notidata);
            }
            let adminIds = await Admin.getAllAdminIds();
            for (let eachIds of adminIds) {
                await Admin.incrementField(eachIds, 'noti_count', 1);
                let notifydata = {
                    user_id: eachIds,
                    url: notificationURL,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId
                }
                await Admin.addNotification(notifydata);
            }

            res.send({
                status: 1,
                message: 'Sign agreement has been successfully created!'
            });
        } else {
            res.send({
                status: 0,
                message: 'Failed to create sign agreement!'
            });
        }
    } catch (error) {
        console.log(error);
    }
}

const editAgreement = async (req, res) => {
    try {
        const { values, userId, templateId } = req.body;

        let template = {};
        template['name'] = values.name;
        template['content'] = values.description; // This should be HTML content from Quill
        template['updated_on'] = currentDate;

        // Update the attachment and handle PDF download if needed
        if (values.hasOwnProperty('attachmentUrl')) {
            if (values.attachmentUrl != null && values.attachmentUrl !== '') {
                template['attachment'] = values.attachmentUrl;
                template['agreement_pdf_path'] = null; // Nullify `agreement_pdf_path` if `attachmentUrl` is present
            } else {
                template['attachment'] = null; // Nullify `attachment` if no data
            }
        }

        let resultId = await signAgreement.updateAgreements(templateId, template);

        if (!empty(resultId)) {
            let imagePaths = []; // Initialize an array to store image paths

            // **Step 1: Delete the old image entries from the database**
            await signAgreement.deleteOldAgreementImage(templateId);  // Add this line to delete old image paths from DB

            // **Step 2: Delete the old PDF file if it exists**
            const oldPdfPath = getAgreementPdfPath(templateId); // Get the old PDF file path
            console.log('Deleting old PDF file at:', oldPdfPath);

            try {
                // Check if the old PDF exists and delete it
                await fs.promises.stat(oldPdfPath);
                await fs.promises.unlink(oldPdfPath); // Delete the old PDF
                console.log(`Old PDF file deleted: ${oldPdfPath}`);
            } catch (err) {
                if (err.code === 'ENOENT') {
                    console.log('Old PDF file not found, nothing to delete.');
                } else {
                    console.error(`Error deleting old PDF file: ${err.message}`);
                }
            }

            // **Step 3: Delete the old images from filesystem if they exist**
            const oldImagePath = getAgreementImagePath(templateId); // Get the old image file path
            console.log('Deleting old images at:', oldImagePath);

            try {
                const imageDir = path.dirname(oldImagePath);
                const files = fs.readdirSync(imageDir);
                files.forEach((file) => {
                    if (file.startsWith(path.basename(oldImagePath))) {
                        const imageFilePath = path.join(imageDir, file);
                        fs.unlinkSync(imageFilePath); // Delete old image files from filesystem
                        console.log(`Old image file deleted: ${imageFilePath}`);
                    }
                });
            } catch (err) {
                console.error(`Error deleting old images: ${err.message}`);
            }

            // **Step 4: Download the new PDF from Supabase and convert it to images**
            if (values.attachmentUrl) {
                const pdfPath = getAgreementPdfPath(templateId);  // Set the file path for PDF download

                console.log("Downloading new PDF from Supabase to path:", pdfPath);

                // **Step 4.1: Download the new PDF from Supabase**
                await downloadPdfFromSupabase(values.attachmentUrl, templateId);  // Download new PDF to server folder

                // **Step 4.2: Convert the downloaded PDF to images**
                const imagePath = getAgreementImagePath(templateId);
                console.log(`Converting new PDF to images at path: ${imagePath}`);
                await convertPdfToImage(pdfPath, imagePath);  // Convert new PDF to images

                // Collect the generated image paths
                imagePaths = fs.readdirSync(path.dirname(imagePath))
                    .filter(file => file.startsWith(path.basename(imagePath)))
                    .map(file => path.join('uploads', 'agreements_images', file)); // Collect image paths in an array

                // Store the generated images in the database using bulk insert
                await signAgreement.storeAgreementImage(templateId, imagePaths);  // Store multiple images

                // Remove the downloaded PDF after conversion
                // await fs.promises.unlink(pdfPath);  // Delete the new PDF file after conversion
            } else {
                // If `agreement_pdf_path` is provided (local PDF file)
                const pdfPath = path.join(__dirname, '..', 'uploads', 'agreements', `${templateId}.pdf`);

                console.log('pdfPath (from agreement_pdf_path):', pdfPath); // Log for debugging

                // Ensure `values.agreement_pdf_path` is valid
                if (!pdfPath || pdfPath === 'undefined') {
                    return res.status(400).send({ status: 0, message: 'PDF path is invalid.' });
                }

                // **Step 1: Convert HTML content to PDF first**
                const pdfRelative = await htmlToPdf(values.description, pdfPath); // Generate PDF from HTML content

                if (pdfRelative) {
                    // **Step 2: Store the generated PDF path in the database**
                    await signAgreement.updateAgreements(templateId, { agreement_pdf_path: pdfRelative });

                    // **Step 3: Convert the generated PDF to images (all pages)**
                    const imagePath = getAgreementImagePath(templateId);
                    await convertPdfToImage(pdfRelative, imagePath);

                    // Collect the generated image paths
                    imagePaths = fs.readdirSync(path.dirname(imagePath))
                        .filter(file => file.startsWith(path.basename(imagePath)))
                        .map(file => path.join('uploads', 'agreements_images', file)); // Collect image paths in an array

                    // Store the generated images in the database using bulk insert
                    await signAgreement.storeAgreementImage(templateId, imagePaths);  // Store multiple images
                } else {
                    return res.status(500).send({ status: 0, message: 'Failed to generate PDF from HTML content.' });
                }
            }

            // Notification Logic
            let notificationMsg = `The sign agreement <strong>${template['name']}</strong> has been updated.`
            let notificationURL = 'sign-agreements';
            if (userId != 1) {
                await Admin.incrementField(userId, 'noti_count', 1);
                let notidata = {
                    user_id: userId,
                    url: notificationURL,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId
                }
                await Admin.addNotification(notidata);
            }
            let adminIds = await Admin.getAllAdminIds();
            for (let eachIds of adminIds) {
                await Admin.incrementField(eachIds, 'noti_count', 1);
                let notifydata = {
                    user_id: eachIds,
                    url: notificationURL,
                    timestamp: currentDate,
                    message: notificationMsg,
                    status: 1,
                    from_id: userId
                }
                await Admin.addNotification(notifydata);
            }

            res.send({
                status: 1,
                message: 'Sign agreement has been updated'
            });
        } else {
            res.send({
                status: 0,
                message: 'Failed to update sign agreement!'
            });
        }
    } catch (error) {
        console.log(error);
    }
};
const deleteAgreement=async(req,res)=>{
    try {
        const {templateId,userId,status} = req.body;
        let template={}
        template['status'] = status

        if(!empty(templateId)){
           let data = await signAgreement.getTemplateFieldIdById(templateId) 

           let deleted = await signAgreement.updateAgreements(templateId,template)
           if(template['status'] ==2){
             if(deleted){
                //notification
                let notificationMsg = `The sign agreement <strong>${data['name']}</strong> has been deleted.`
                let notificationURL = 'sign-agreements'
                if(userId !=1){
                    await Admin.incrementField(userId,'noti_count',1)
                    let notidata={
                        user_id:userId,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notidata)
                }
                let adminIds= await Admin.getAllAdminIds()
                for(let eachIds of adminIds){
    
                    await Admin.incrementField(eachIds,'noti_count',1)
                    let notifydata={
                        user_id:eachIds,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notifydata)
                }
                res.send({
                    status:2,message:`The Sign agreement'${data['name']}' has been deleted successfully!`,
                })
             }
           }
           else if(template['status'] ==1){
            if(deleted){
                //notification
                let notificationMsg = `The sign agreement <strong>${data['name']}</strong> has been activated.`
                let notificationURL = 'sign-agreements'
                if(userId !=1){
                    await Admin.incrementField(userId,'noti_count',1)
                    let notidata={
                        user_id:userId,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notidata)
                }
                let adminIds= await Admin.getAllAdminIds()
                for(let eachIds of adminIds){
    
                    await Admin.incrementField(eachIds,'noti_count',1)
                    let notifydata={
                        user_id:eachIds,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notifydata)
                }
                res.send({
                    status:1,message:`The Sign agreement '${data['name']}' has been Activated successfully!`,
                })
             }
           }else if(template['status'] ==0){
            if(deleted){
                //notification
                let notificationMsg = `The sign agreement <strong>${data['name']}</strong> has been deactivated.`
                let notificationURL = 'sign-agreements'
                if(userId !=1){
                    await Admin.incrementField(userId,'noti_count',1)
                    let notidata={
                        user_id:userId,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notidata)
                }
                let adminIds= await Admin.getAllAdminIds()
                for(let eachIds of adminIds){
    
                    await Admin.incrementField(eachIds,'noti_count',1)
                    let notifydata={
                        user_id:eachIds,
                        url:notificationURL,
                        timestamp:currentDate,
                        message:notificationMsg,
                        status:1,
                        from_id:userId
                    }
                    await Admin.addNotification(notifydata)
                }
                res.send({
                    status:0,message:`The Sign agreement '${data['name']}' has been Deactivated successfully!`,
                })
             }
           }
        }
    } catch (error) {
        console.log(error)
    }
}
  
const getAgreementByid=async(req,res)=>{
    try {
        const {templateId,userId} = req.body
        let data = await signAgreement.getTemplateFieldIdById(templateId)
        if(!empty(data)){
            res.send({
                status:1,data
            })
        }else{
            res.send({
                status:0
            })         
        }
    } catch (error) {
        console.log(error)
    }
}
module.exports={
    getAllAgreements,
    addAgreements,
    editAgreement,
    deleteAgreement,
    getAgreementByid,
}