(function () {
    const root = document.getElementById("invoicePrintRoot");
    if (!root) return;

    const invoiceNo = root.getAttribute("data-invoice-no");
    const tbody = document.querySelector("#printLineTable tbody");
    const copyBtn = document.getElementById("copyInvoiceLinkBtn");
    const shareBtn = document.getElementById("shareInvoiceBtn");
    const pdfBtn = document.getElementById("downloadInvoicePdfBtn");
    const printBtn = document.getElementById("printInvoiceBtn");
    const loader = document.getElementById("invoiceLoader");
    const documentRoot = document.getElementById("invoiceDocument");

    if (!invoiceNo || !tbody || !documentRoot) return;

    showLoader(true);
    fetch("/api/sales/invoice-print/" + encodeURIComponent(invoiceNo))
        .then(handleJson)
        .then(function (data) {
            bindHeader(data);
            bindParty(data);
            bindSummary(data);
            bindLines(data.lines || []);
        })
        .catch(function () {
            if (window.Swal) {
                window.Swal.fire({
                    icon: "error",
                    title: "Unable to load invoice",
                    text: "The invoice data could not be loaded from the server."
                });
            }
        })
        .finally(function () {
            showLoader(false);
        });

    copyBtn?.addEventListener("click", async function () {
        if (!navigator.clipboard) return;
        await navigator.clipboard.writeText(window.location.href);
    });

    pdfBtn?.addEventListener("click", function () {
        generatePdf();
    });

    printBtn?.addEventListener("click", function () {
        printInvoicePdf();
    });

    shareBtn?.addEventListener("click", async function () {
        try {
            const file = await generatePdfBlob();
            if (navigator.canShare && navigator.canShare({ files: [file] })) {
                await navigator.share({ files: [file], title: "Invoice " + invoiceNo });
                return;
            }

            if (navigator.clipboard) {
                await navigator.clipboard.writeText(window.location.href);
            }
        } catch {
            if (window.Swal) {
                window.Swal.fire({
                    icon: "info",
                    title: "Share unavailable",
                    text: "PDF sharing is not supported in this browser."
                });
            }
        }
    });

    function bindHeader(data) {
        setText("printCompanyName", data.company.companyName);
        setHtml("printCompanyAddress", [data.company.address1, data.company.address2].filter(Boolean).join("<br>"));
        setText("printCompanyMeta", ["Phone: " + (data.company.phone || ""), "GST: " + (data.company.gstNo || "")].filter(Boolean).join(" | "));
        setText("printInvoiceNo", data.header.invoiceNo);
        setText("printInvoiceDate", formatDate(data.header.invoiceDate));
        setText("printTransport", data.header.transport || "-");
    }

    function bindParty(data) {
        setText("printPartyName", data.header.partyName);
        setHtml("printPartyAddress", [data.header.address1, data.header.address2].filter(Boolean).join("<br>"));
        setText("printPartyPhone", data.header.phone ? "Mobile: " + data.header.phone : "");
        setText("printPartyGst", data.header.gstNo ? "GSTIN: " + data.header.gstNo : "");
    }

    function bindSummary(data) {
        const lines = data.lines || [];
        const totalTax = lines.reduce(function (sum, line) { return sum + Number(line.taxAmount || 0); }, 0);
        const subtotal = lines.reduce(function (sum, line) { return sum + Number(line.netAmount || 0); }, 0);
        setText("printSubtotal", money(data.header.netAmount));
        setText("printTax", money(totalTax));
        setText("printGross", money(data.header.grossAmount));
        setText("printAmountWords", numberToWords(Math.round(Number(data.header.grossAmount || 0))) + " Rupees Only");
        setText("printFooterNote", "Subtotal " + money(subtotal) + " | Tax " + money(totalTax) + " | Payable " + money(data.header.grossAmount));
    }

    function bindLines(lines) {
        tbody.innerHTML = lines.map(function (line, index) {
            return "<tr>" +
                "<td>" + (index + 1) + "</td>" +
                "<td>" + esc(line.productName) + "</td>" +
                "<td>" + esc(line.batchNo) + "</td>" +
                '<td class="text-end">' + qty(line.quantity) + "</td>" +
                '<td class="text-end">' + qty(line.freeQuantity) + "</td>" +
                '<td class="text-end">' + money(line.rate) + "</td>" +
                '<td class="text-end">' + money(line.taxAmount) + "</td>" +
                '<td class="text-end">' + qty(line.discountPercent) + "</td>" +
                '<td class="text-end">' + money(line.discountAmount) + "</td>" +
                '<td class="text-end">' + money(line.netAmount) + "</td>" +
                "</tr>";
        }).join("");
    }

    function generatePdf() {
        if (!window.html2pdf) return;
        window.html2pdf().set(pdfOptions()).from(documentRoot).save();
    }

    async function generatePdfBlob() {
        if (!window.html2pdf) throw new Error("PDF not available");
        const blob = await window.html2pdf().set(pdfOptions()).from(documentRoot).outputPdf("blob");
        return new File([blob], "Invoice-" + invoiceNo + ".pdf", { type: "application/pdf" });
    }

    async function printInvoicePdf() {
        try {
            showLoader(true);
            const file = await generatePdfBlob();
            const url = URL.createObjectURL(file);
            const printWindow = window.open(url, "_blank");

            if (!printWindow) {
                URL.revokeObjectURL(url);
                if (window.Swal) {
                    window.Swal.fire({
                        icon: "info",
                        title: "Popup blocked",
                        text: "Allow popups for this site to open the PDF print view."
                    });
                }
                return;
            }

            window.setTimeout(function () {
                URL.revokeObjectURL(url);
            }, 60000);
        } catch {
            if (window.Swal) {
                window.Swal.fire({
                    icon: "error",
                    title: "Print failed",
                    text: "The invoice PDF could not be generated for printing."
                });
            }
        } finally {
            showLoader(false);
        }
    }

    function pdfOptions() {
        return {
            margin: [10, 10, 10, 10],
            filename: "Invoice-" + invoiceNo + ".pdf",
            image: { type: "jpeg", quality: 0.98 },
            html2canvas: { scale: 2, useCORS: true },
            jsPDF: { unit: "mm", format: "a4", orientation: "portrait" }
        };
    }

    function numberToWords(num) {
        const a = ["", "One ", "Two ", "Three ", "Four ", "Five ", "Six ", "Seven ", "Eight ", "Nine ", "Ten ", "Eleven ", "Twelve ", "Thirteen ", "Fourteen ", "Fifteen ", "Sixteen ", "Seventeen ", "Eighteen ", "Nineteen "];
        const b = ["", "", "Twenty ", "Thirty ", "Forty ", "Fifty ", "Sixty ", "Seventy ", "Eighty ", "Ninety "];

        function words(n) {
            if (n < 20) return a[n];
            if (n < 100) return b[Math.floor(n / 10)] + a[n % 10];
            if (n < 1000) return a[Math.floor(n / 100)] + "Hundred " + (n % 100 ? words(n % 100) : "");
            if (n < 100000) return words(Math.floor(n / 1000)) + "Thousand " + (n % 1000 ? words(n % 1000) : "");
            if (n < 10000000) return words(Math.floor(n / 100000)) + "Lakh " + (n % 100000 ? words(n % 100000) : "");
            return "";
        }

        return words(num).trim();
    }

    function showLoader(show) {
        if (!loader) return;
        loader.hidden = !show;
    }

    function setText(id, value) {
        const el = document.getElementById(id);
        if (el) el.textContent = value || "";
    }

    function setHtml(id, value) {
        const el = document.getElementById(id);
        if (el) el.innerHTML = value || "";
    }

    function handleJson(response) {
        if (!response.ok) throw new Error("Request failed");
        return response.json();
    }

    function money(value) {
        return Number(value || 0).toLocaleString("en-IN", { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }

    function qty(value) {
        return Number(value || 0).toLocaleString(undefined, { minimumFractionDigits: 0, maximumFractionDigits: 2 });
    }

    function formatDate(value) {
        return value ? new Date(value).toLocaleDateString("en-GB") : "";
    }

    function esc(value) {
        return String(value || "")
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#39;");
    }
}());
