(function () {
    const fromInput = document.getElementById("invoiceFromDate");
    const toInput = document.getElementById("invoiceToDate");
    const searchInput = document.getElementById("invoiceSearch");
    const loadBtn = document.getElementById("loadInvoicesBtn");
    const resetBtn = document.getElementById("resetInvoicesBtn");
    const exportBtn = document.getElementById("exportInvoicesBtn");
    const tbody = document.querySelector("#invoiceTable tbody");
    const metricCards = document.getElementById("invoiceMetricCards");
    const rangeLabel = document.getElementById("invoiceRangeLabel");
    const rowCountLabel = document.getElementById("invoiceRowCountLabel");
    const searchStateLabel = document.getElementById("invoiceSearchStateLabel");
    const totalValueLabel = document.getElementById("invoiceTotalValueLabel");
    let latestRows = [];

    if (!fromInput || !toInput || !searchInput || !loadBtn || !tbody || !metricCards) {
        return;
    }

    resetDates();
    bindEvents();
    load();

    function bindEvents() {
        loadBtn.addEventListener("click", load);
        resetBtn?.addEventListener("click", function () {
            resetDates();
            searchInput.value = "";
            load();
        });
        exportBtn?.addEventListener("click", exportCsv);
        searchInput.addEventListener("keydown", function (event) {
            if (event.key === "Enter") {
                event.preventDefault();
                load();
            }
        });
    }

    function load() {
        loadBtn.disabled = true;
        fetch("/api/sales/invoices?fromDate=" + encodeURIComponent(fromInput.value) + "&toDate=" + encodeURIComponent(toInput.value) + "&limit=200&search=" + encodeURIComponent(searchInput.value || ""))
            .then(handleJson)
            .then(function (rows) {
                latestRows = rows || [];
                render();
            })
            .finally(function () {
                loadBtn.disabled = false;
            });
    }

    function render() {
        renderTable();
        renderMetrics();
        renderToolbar();
    }

    function renderTable() {
        tbody.innerHTML = latestRows.map(function (row) {
            const printUrl = "/Sales/InvoicePrint/" + encodeURIComponent(row.invoiceNo || "");
            const shareText = window.location.origin + printUrl;

            return "<tr>" +
                "<td><div class=\"invoice-row-primary\">" + esc(row.invoiceNo) + "</div></td>" +
                "<td>" + date(row.invoiceDate) + "</td>" +
                "<td><div class=\"invoice-row-party\">" + esc(row.partyName || "-") + "</div></td>" +
                '<td class="text-end">' + number(row.itemCount) + "</td>" +
                '<td class="text-end invoice-row-amount">' + money(row.totalAmount) + "</td>" +
                '<td class="text-center"><div class="invoice-row-actions">' +
                '<a class="btn btn-sm btn-outline-primary" href="' + printUrl + '">Print</a>' +
                '<a class="btn btn-sm btn-light" href="' + printUrl + '" target="_blank">Open</a>' +
                '<button class="btn btn-sm btn-light js-copy-link" type="button" data-link="' + esc(shareText) + '">Copy</button>' +
                "</div></td>" +
                "</tr>";
        }).join("");

        if (!latestRows.length) {
            tbody.innerHTML = '<tr><td colspan="6" class="text-center text-muted py-4">No invoices found for the selected filters.</td></tr>';
        }

        tbody.querySelectorAll(".js-copy-link").forEach(function (button) {
            button.addEventListener("click", function () {
                const link = button.getAttribute("data-link") || "";
                if (!navigator.clipboard) {
                    return;
                }
                navigator.clipboard.writeText(link).then(function () {
                    button.textContent = "Copied";
                    window.setTimeout(function () { button.textContent = "Copy"; }, 1200);
                });
            });
        });
    }

    function renderMetrics() {
        const totalValue = sum(latestRows, function (row) { return row.totalAmount; });
        const totalItems = sum(latestRows, function (row) { return row.itemCount; });
        const averageInvoice = latestRows.length ? totalValue / latestRows.length : 0;
        const uniqueParties = new Set(latestRows.map(function (row) { return (row.partyName || "").trim(); }).filter(Boolean)).size;

        metricCards.innerHTML = [
            metric("Invoices loaded", number(latestRows.length), "info", "Current rows"),
            metric("Invoice value", money(totalValue), "success", "Visible invoice total"),
            metric("Items billed", number(totalItems), "warning", "Sum of item count"),
            metric("Average invoice", money(averageInvoice), "indigo", number(uniqueParties) + " parties")
        ].join("");
    }

    function renderToolbar() {
        const totalValue = sum(latestRows, function (row) { return row.totalAmount; });

        if (rangeLabel) {
            rangeLabel.textContent = date(fromInput.value) + " to " + date(toInput.value);
        }
        if (rowCountLabel) {
            rowCountLabel.textContent = number(latestRows.length) + " invoices";
        }
        if (searchStateLabel) {
            searchStateLabel.textContent = searchInput.value ? ('"' + searchInput.value + '"') : "Today list";
        }
        if (totalValueLabel) {
            totalValueLabel.textContent = money(totalValue);
        }
    }

    function exportCsv() {
        const lines = ["Invoice,Date,Party,Items,Amount"].concat(latestRows.map(function (row) {
            return [row.invoiceNo, date(row.invoiceDate), clean(row.partyName), row.itemCount, row.totalAmount].join(",");
        }));
        download("sales-invoices.csv", lines.join("\n"));
    }

    function resetDates() {
        const today = new Date();
        const value = toDateInput(today);
        fromInput.value = value;
        toInput.value = value;
    }

    function sum(rows, selector) {
        return rows.reduce(function (total, row) {
            return total + Number(selector(row) || 0);
        }, 0);
    }

    function metric(title, value, tone, note) {
        return '<article class="metric-card">' +
            '<span class="tone ' + esc(tone) + '">' + esc(note) + "</span>" +
            "<h3>" + esc(value) + "</h3>" +
            "<p>" + esc(title) + "</p>" +
            "</article>";
    }

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

    function money(value) {
        return "Rs. " + Number(value || 0).toLocaleString(undefined, { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }

    function number(value) {
        return Number(value || 0).toLocaleString();
    }

    function date(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;");
    }

    function clean(value) {
        return String(value || "").replace(/,/g, " ");
    }

    function toDateInput(value) {
        const year = value.getFullYear();
        const month = String(value.getMonth() + 1).padStart(2, "0");
        const day = String(value.getDate()).padStart(2, "0");
        return year + "-" + month + "-" + day;
    }

    function download(name, text) {
        const blob = new Blob([text], { type: "text/csv;charset=utf-8;" });
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = name;
        a.click();
        URL.revokeObjectURL(url);
    }
}());
