// JavaScript Document
// Replaces libPDFscripts.js
// NEW - Process Scripts
// 
//  ** OFFICIAL SCRIPT TO USE WHEN IN PRODUCTION
//
// Function to add Authenticator validation https://www.npmjs.com/package/speakeasy
// Utility to fetch PDF bytes


console.log("LIBRARY: libProcessScript.js")






const dd = createDebugLogger(true, "dd"); // code function at bottom of the page



// Wrapper function to fetch, update, and download PDF
async function processAndDownloadPdf(filePath, ...dataSources) {
    console.log(filePath)
    try {
        const pdfBytes = await fetchPdfBytes(filePath);
        const updatedPdfBytes = await updatePdfFields(pdfBytes, dataSources);
        const fileName = generateRandomFilename(8, "ERT_", ".pdf");
        //const saveFilePath = await savePdfToFile(pdfBytes);
        //dd("[PDF PATH]", saveFilePath);
        downloadPdf(updatedPdfBytes, fileName);
    } catch (err) {
        dd("Error Processing PDF", err)
        //console.error("Error processing the PDF:", err);
    }
}

async function fetchPdfBytes(filePath) {


    try {
        const response = await fetch(filePath);
        if (!response.ok) throw new Error(`Failed to fetch PDF from ${filePath}`);
        return await response.arrayBuffer();
    } catch (err) {
        console.error("Error fetching PDF bytes:", err);
        throw err;
    }
}

// Update form fields in the PDF



async function updatePdfFields(
    pdfBytes,
    dataSources,
    //skipMissingFields = false

) {
    console.log("Datasources Count:", dataSources.length)
    console.log(JSON.stringify(dataSources, null, 2));



    // try {
    const pdfDoc = await PDFLib.PDFDocument.load(pdfBytes);
    const form = pdfDoc.getForm();


    dataSources.forEach((dataSource, dsIndex) => {
        console.log(`Processing dataSource[${dsIndex}]:`, dataSource);

        if (!Array.isArray(dataSource)) {
            console.warn(`dataSource[${dsIndex}] is not an array. Skipping.`);
            return;
        }
        let ii = 0
        dataSource.forEach((record, recIndex) => {
            if (ii == 0) {
                console.log(JSON.stringify(record, null, 2))
            }
            console.log(`Processing record[${recIndex}]:`, record);

            if (!record || typeof record !== 'object') {
                console.warn(`record[${recIndex}] is undefined or not an object. Skipping.`);
                return;
            }

            // Extract numSection and pointValue dynamically or other 'key' components.
            /**  
             * Working area - to wrap assignment of numSection, pointValue or a Key-Value for other datasources.
             * so far this is working and success on downloading the PDF prefilled on the score.
             */
            const recordToKeyArray = Object.keys(record).includes("$id")

            if (recordToKeyArray) { console.log("$ID EXIST") }
            const { numSection, pointValue } = record;
            const rKey = numSection
            const rValue = pointValue
            //const pointValue = record.pointValue || record.Points;  // Fallback to Points if pointValue is missing
            console.log(`[numSection 2 key  ==>] ${rKey},${rValue}`)

            if (numSection && pointValue) {
                console.log(`Updating PDF field: ${numSection} with value: ${pointValue}`);

                try {
                    // Use numSection as the dynamic field name
                    //const formField = form.getTextField(numSection);
                    const formField = form.getFieldMaybe(String(numSection));  // if cannot find, then just returns 'undefined' rather than throw err.
                    if (formField) {
                        ii++
                        formField.setText(String(pointValue));
                        console.log(`Field "${numSection}" updated with value "${pointValue}".`);
                    } else {
                        console.warn(`Field "${numSection}" not found in PDF.`);
                    }
                } catch (err) {
                    console.error(`Error updating field "${numSection}":`, err);
                }
            } else {
                console.warn(`Missing numSection or pointValue in record[${recIndex}].`);
            }
        });
        console.log(`${ii} Form field updates complete.`);
        ii = 0;
    });


    return await pdfDoc.save(); /// MOVE TO the Main PROCESS and DOWNLOD PDF function or as last call. (need await??) Maybe make it an actual 'ready' to download button.



}




// Function to trigger download of the updated PDF
function downloadPdf(pdfBytes, fileName) {

    const blob = new Blob([pdfBytes], { type: "application/pdf" });
    const url = URL.createObjectURL(blob);

    const link = Object.assign(document.createElement("a"), {
        href: url,
        download: fileName,
    });
    console.log("DOWNLOAD Filled PDF")
    link.click();
    URL.revokeObjectURL(url); // Clean up the URL immediately
}

function generateRandomFilename(length = 8, prefix = "", suffix = "") {
    const characters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
    const array = Array.from({ length }, () =>
        characters.charAt(Math.floor(Math.random() * characters.length))
    );
    const filename = `${prefix}${array.join("")}${suffix}`;

    //dd("Random Filename:", filename);
    return filename;
}

// Example Usage:




async function savePdfToFile(pdfBytes) {
    const randomFilename = generateRandomFilename(12, "", ".pdf");
    File.path;
    const filePath = Filehandle.path.join(__dirname, "PDF", randomFilename);
    dd("[SAVE TO DISK]", randomFilename);
    // Save the file to disk
    await fs.writeFile(filePath, Buffer.from(pdfBytes));

    // Return a URL or file path based on your server setup
    return `/PDF/${randomFilename}`;
}

function createDebugLogger(debug, prefix = "DD") {


    return function (message, ...optionalParams) {

        switch (debug) {
            case true:
                console.log(
                    `[${prefix}]`.toUpperCase(), `${message}`, ...optionalParams);
                break
        }
    };
}


function saveSignature_OFF() { //Testing a new function under dummyfunctions section
    const canvas = document.getElementById('signatureCanvas');
    const imageData = canvas.toDataURL('image/png');
    dd(imageData.length)
    // Trigger the server action and handle the response
    dmx.parse('serverconnect_sign.load({imageData: "' + imageData + '"})');
    //dmx.parse('serverconnect_sign.load({ image: imageData })');
    /** 
    dmx.parse('serverconnect_sign.load', { image: imageData }).then((response) => {
        //dmx.parse('serverconnect_sign.load({image: "' + imageData + '"})').then((response) => {
        const uploadedSignature = document.getElementById('uploadedSignature');
        uploadedSignature.src = response.fileUrl; // Use the file path returned from the server
        dd(response.fileUrl)
    }).catch((error) => {
        console.error("Error uploading signature:", error);
    });
*/
}


// ************** DUMMY TEST FUNCTIONS BELOW ******************  //

function runMyFunction() {
    //  alert("function run")
    let result = generateRandomIdentifier(9);
    // Use Wappler dmx.set to bind result to a Wappler variable if needed
    //<p>{{myResult}}</p>
    console.log(result)
    dmx.global.set('myResult', result);

}

function generateRandomIdentifier(v) {
    return generateRandomFilename(v)
}


function saveSignature() {
    const canvas = document.getElementById('signatureCanvas');
    const imageData = canvas.toDataURL('image/png'); // Convert the canvas to a Base64 image string
    dd("Got Signature:", imageData)

    dmx.parse('serverconnect_sign.load({image: "' + imageData + '"})').then((response) => {
        const uploadedSignature = document.getElementById('uploadedSignature');
        dd(uploadedSignature)
        dd("Response:", response.fileUrl)
        uploadedSignature.src = response.fileUrl; // Set the uploaded file URL to the image element

    }).catch((error) => {
        console.error("Error uploading signature:", error);
    });
}

function saveSignatureAsBase64() {
    //const canvas = document.getElementById('signatureCanvas');

    return document.getElementById('signatureCanvas').toDataURL('image/png'); // Get the Base64 string

}

function getSignatureData() {
    dmx.global.set('signatureDataEncoded', saveSignatureAsBase64())
    dd('SignatureData:', saveSignatureAsBase64())
}

function saveSignatureNew() {
    const canvas = document.getElementById('signatureCanvas');
    const imageData = canvas.toDataURL('image/png'); // Convert the canvas to a Base64 image string
    dd("Got Signature:", imageData)
    dmx.app.data.content.serverconnect_sign.__load({ imageData: imageData }).then((response) => {
        dd("Success:", response);
        const uploadedSignature = document.getElementById('uploadedSignature');
        dd(uploadedSignature, "Response:", response.fileUrl)
        uploadedSignature.src = response.fileUrl; // Set the uploaded file URL to the image element
    }).catch((error) => {
        console.error("Error:", error);
    });
}

