import * as Charts from "./globals.js";


document.addEventListener("DOMContentLoaded", () => {

    document
        .getElementById('chartSelectorBtn')
        ?.addEventListener('click', openChartSelector);
    const toggle = document.getElementById("exportToggle");
    const items = document.getElementById("exportItems");
    const close = document.getElementById("exportClose");


    if (!toggle || !items) return;

    toggle.addEventListener("click", () => {
        items.classList.toggle("show");

        toggle.innerText = items.classList.contains("show")
            ? "Export ▾"
            : "Export ▸";
    });

    if (close) {
        close.addEventListener("click", () => {
            items.classList.remove("show");
            toggle.innerText = "Export ▸";
        });
    }
    document
        .getElementById('btnCharts')
        ?.addEventListener('click', openChartSelector);

    document
        .getElementById('btnExport')
        ?.addEventListener('click', exportFullDashboard);


    document
        .querySelector('#chartCancel')
        ?.addEventListener('click', closeChartSelector);

    document
        .querySelector('#chartDownload')
        ?.addEventListener('click', exportSelectedCharts);

  

});


function openChartSelector() {

    if (typeof Charts.charts === "undefined" || Object.keys(Charts.charts).length === 0) {
        alert("Charts are still loading. Please try again.");
        return;
    }

    const modal = document.getElementById("chartModal");
    const list = document.getElementById("chartList");

    list.innerHTML = "";

    Object.keys(Charts.charts).forEach(id => {
        list.innerHTML += `
            <label style="display:block;margin-bottom:6px;">
                <input type="checkbox" value="${id}" checked>
                ${formatChartName(id)}
            </label>
        `;
    });
    list.innerHTML += `
        <label>
            <input type="checkbox" value="provinceMap" checked>
            Geographic Distribution
        </label>
    `;

    modal.style.display = "block";
}

function closeChartSelector() {
    document.getElementById("chartModal").style.display = "none";
}

function formatChartName(id) {
    const map = {
        trendChart: "Case Trend",
        pathogenChart: "Pathogen Distribution",
        provinceMap: "Geographic Distribution",
        ageChart: "Age Distribution",
        sexChart: "Sex Distribution",
        subtypeChart: "Influenza Subtypes",
        sentinelChart: "Sentinel Site Distribution",
        sequencingTotalChart: "Sequencing Total",
        covidLineageFrequency: "Covid Lineage Frequency",
        influenzaSubtypeDistribution: "Influenza Subtype Frequency",
        covidDistributedByAgeGroup: "Covid Cases by Age",
        influenzaSubtypeFrequency: "Influenza Cases by Age",

    };

    return map[id] || id;
}

async function exportSelectedCharts() {

    const { jsPDF } = window.jspdf;
    const pdf = new jsPDF("l", "mm", "a4");

    const margin = 15;
    const pageWidth = 297;
    const pageHeight = 210;

    const contentTop = 35;
    const contentHeight = pageHeight - contentTop - 10;
    const contentWidth = pageWidth - margin * 2;

    const selected = document.querySelectorAll("#chartList input:checked");

    const loadingDiv = document.createElement("div");
    Object.assign(loadingDiv.style, {
        position: "fixed",
        top: "50%",
        left: "50%",
        transform: "translate(-50%, -50%)",
        background: "rgb(255, 255, 255)",
        color: "#000000",
        padding: "20px",
        borderRadius: "10px",
        zIndex: "10000"
    });
    loadingDiv.innerHTML = "Generating PDF...";
    document.body.appendChild(loadingDiv);

    function drawHeader() {
        pdf.setFillColor(255, 255, 255);
        pdf.rect(0, 0, pageWidth, 30, "F");

        pdf.setFontSize(18);
        pdf.setFont(undefined, "bold");
        pdf.setTextColor(0);
        pdf.text(getReportTitle(), margin, 14);

        pdf.setFontSize(9);
        pdf.setTextColor(100);
        pdf.text(`Generated: ${new Date().toLocaleString()}`, margin, 22);

        pdf.setDrawColor(220);
        pdf.line(margin, 28, pageWidth - margin, 28);
    }

    drawHeader();

    const items = [];

    for (const cb of selected) {
        if (cb.value === "provinceMap") {
            loadingDiv.innerHTML = "Processing map...";
            const img = await getMapImage();

            if (img) {
                items.push({
                    id: "provinceMap",
                    type: "map",
                    img
                });
            }
        } else {
            const chart = Charts.charts[cb.value];
            if (!chart) continue;

            items.push({
                id: cb.value,
                type: "chart",
                chart
            });
        }
    }

    for (let i = 0; i < items.length; i++) {
        const item = items[i];

        loadingDiv.innerHTML = `Rendering ${formatChartName(item.id)} (${i + 1}/${items.length})`;

        if (i !== 0) {
            pdf.addPage();
            drawHeader();
        }

        const cardX = margin;
        const cardY = contentTop - 5;
        const cardWidth = contentWidth;
        const cardHeight = contentHeight;

        pdf.setFillColor(255, 255, 255);
        pdf.roundedRect(cardX, cardY, cardWidth, cardHeight, 3, 3, "F");

        pdf.setDrawColor(230);
        pdf.roundedRect(cardX, cardY, cardWidth, cardHeight, 3, 3);

        pdf.setFontSize(13);
        pdf.setFont(undefined, "bold");
        pdf.setTextColor(0);
        pdf.text(formatChartName(item.id), cardX + 5, cardY + 8);

        let img;
        let width;
        let height;

        if (item.type === "map") {
            img = item.img;

            width = cardWidth - 60;
            height = width * 0.65;

        } else {
            const canvas = item.chart.canvas;

            const scale = 4;

            const tempCanvas = document.createElement("canvas");

            tempCanvas.width = canvas.width * scale;
            tempCanvas.height = canvas.height * scale;

            const ctx = tempCanvas.getContext("2d");

            ctx.scale(scale, scale);

            ctx.fillStyle = "#ffffff";
            ctx.fillRect(0, 0, canvas.width, canvas.height);

            ctx.drawImage(canvas, 0, 0);

            img = tempCanvas.toDataURL("image/jpeg", 0.95);

            const ratio = canvas.height / canvas.width;

            width = cardWidth - 10;
            height = width * ratio;

            if (height > cardHeight - 20) {
                height = cardHeight - 20;
                width = height / ratio;
            }
        }

        const x = cardX + (cardWidth - width) / 2;
        const contentTopOffset = 14;
        const availableHeight = cardHeight - contentTopOffset;

        const y = cardY + contentTopOffset + (availableHeight - height) / 2;

        pdf.addImage(img, "PNG", x, y, width, height);
    }

    document.body.removeChild(loadingDiv);

    pdf.save("dashboard_report.pdf");
    closeChartSelector();
}
function prepareMapForExport() {
    if (!window.map) return;

    const bounds = L.latLngBounds([
        [10.3, 102.3],
        [14.7, 107.6]
    ]);

    window.map.fitBounds(bounds);

}
async function exportFullDashboard() {
    const el = document.querySelector(".content-area");

    const mapEl = document.getElementById("provinceMap");
    let originalMapHTML = null;

    if (mapEl) {
        originalMapHTML = mapEl.innerHTML;

        const mapImg = await getMapImage();

        if (mapImg) {
            mapEl.innerHTML = `<img src="${mapImg}" style="width:100%;height:100%;object-fit:cover;" />`;
        }
    }
    prepareMapForExport();

    await new Promise(resolve => setTimeout(resolve, 800));

    const canvas = await html2canvas(el, {
        scale: 4,
        useCORS: true,
        scrollY: -window.scrollY,
        backgroundColor: "#ffffff"
    });

    if (mapEl && originalMapHTML !== null) {
        mapEl.innerHTML = originalMapHTML;
        window.map.invalidateSize();
    }

    const img = canvas.toDataURL("image/jpeg", 0.95);

    const { jsPDF } = window.jspdf;
    const pdf = new jsPDF({
        orientation: "landscape",
        unit: "mm",
        format: "a4",
        compress: true
    });

    const pageWidth = 297;
    const pageHeight = 210;

    const ratio = Math.min(
        pageWidth / canvas.width,
        pageHeight / canvas.height
    );

    const imgWidth = canvas.width * ratio;
    const imgHeight = canvas.height * ratio;

    const x = (pageWidth - imgWidth) / 2;
    const y = (pageHeight - imgHeight) / 2;

    pdf.addImage(img, "JPEG", x, y, imgWidth, imgHeight);
    pdf.save("full_dashboard.pdf");

    closeChartSelector();
}
function getColor(value) {
    if (value > 50) return "#b91c1c";
    if (value >= 10) return "#ef4444";
    if (value > 0) return "#fecaca";
    return "#f3f4f600";
}
async function getMapImage() {
    const original = document.getElementById("provinceMap");
    if (!original) return null;

    const width = original.offsetWidth;
    const height = original.offsetHeight;

    const canvas = document.createElement("canvas");
    canvas.width = width * 3;
    canvas.height = height * 3;

    const ctx = canvas.getContext("2d");
    ctx.scale(3, 3);


    ctx.fillStyle = "#ffffff";
    ctx.fillRect(0, 0, width, height);

    const zoom = window.map.getZoom();
    const projection = window.map.options.crs;

    const projectedRings = [];

    let minX = Infinity, minY = Infinity;
    let maxX = -Infinity, maxY = -Infinity;

    const totals = {};
    const rows = window.latestProvinceData || [];

    rows.forEach(r => {
        const province = window.normalizeProvince(r.patient_province, window.validProvinces);
        if (!province) return;

        if (!totals[province]) {
            totals[province] = { total: 0, positive: 0 };
        }

        totals[province].total += Number(r.total);
        totals[province].positive += Number(r.positive);
    });



    window.map.eachLayer(layer => {
        if (!layer.toGeoJSON) return;
        if (layer instanceof L.CircleMarker) {

            const latlng = layer.getLatLng();

            const point = projection.latLngToPoint(latlng, zoom);

            minX = Math.min(minX, point.x);
            maxX = Math.max(maxX, point.x);
            minY = Math.min(minY, point.y);
            maxY = Math.max(maxY, point.y);

            projectedRings.push({
                type: "circle",
                x: point.x,
                y: point.y,
                radius: layer.getRadius(),
                fillColor: layer.options.fillColor || "#000",
                strokeColor: layer.options.color || "#000"
            });

            return;
        }

        const geo = layer.toGeoJSON();

        const features = geo.type === "FeatureCollection"
            ? geo.features
            : [geo];

        features.forEach(f => {
            if (
                !f.geometry ||
                !f.geometry.coordinates
            ) return;

            const coords = f.geometry.coordinates;

            const polygons = f.geometry.type === "MultiPolygon"
                ? coords
                : [coords];

            polygons.forEach(poly => {

                if (!Array.isArray(poly)) return;

                poly.forEach(ring => {

                    if (
                        !Array.isArray(ring) ||
                        !Array.isArray(ring[0])
                    ) {
                        return;
                    }

                    const projected = ring.map(coord => {

                        if (!Array.isArray(coord) || coord.length < 2) {
                            return null;
                        }

                        const [lng, lat] = coord;

                        const latlng = L.latLng(lat, lng);
                        const point = projection.latLngToPoint(latlng, zoom);

                        minX = Math.min(minX, point.x);
                        maxX = Math.max(maxX, point.x);
                        minY = Math.min(minY, point.y);
                        maxY = Math.max(maxY, point.y);

                        return [point.x, point.y];
                    }).filter(Boolean);

                    if (!projected.length) return;

                    projectedRings.push({
                        points: projected,
                        properties: f.properties || {}
                    });

                });
            });
        });
    });

    const padding = 10;

    const scaleX = (width - padding * 2) / (maxX - minX);
    const scaleY = (height - padding * 2) / (maxY - minY);
    const scale = Math.min(scaleX, scaleY);

    const offsetX = (width - (maxX - minX) * scale) / 2;
    const offsetY = (height - (maxY - minY) * scale) / 2;

    projectedRings.forEach(item => {

        // -------------------------
        // Draw circle markers
        // -------------------------
        if (item.type === "circle") {

            const drawX = (item.x - minX) * scale + offsetX;
            const drawY = (item.y - minY) * scale + offsetY;

            ctx.beginPath();

            ctx.arc(
                drawX,
                drawY,
                item.radius,
                0,
                Math.PI * 2
            );

            ctx.fillStyle = item.fillColor;
            ctx.fill();



            return;
        }

        // -------------------------
        // Draw polygons
        // -------------------------
        const { points, properties } = item;

        ctx.beginPath();

        points.forEach(([x, y], i) => {

            const drawX = (x - minX) * scale + offsetX;
            const drawY = (y - minY) * scale + offsetY;

            if (i === 0) ctx.moveTo(drawX, drawY);
            else ctx.lineTo(drawX, drawY);

        });

        ctx.closePath();

        const province = properties.ADM1_EN;
        const value = totals[province]?.total || 0;

        ctx.fillStyle = getColor(value);
        ctx.fill();

        ctx.strokeStyle = "#444";
        ctx.lineWidth = 1;
        ctx.stroke();
    });

    const legend = document.querySelector(".map-legend");

    if (legend) {
        const legendCanvas = await html2canvas(legend, {
            scale: 3,
            backgroundColor: null
        });

        const lw = legend.offsetWidth;
        const lh = legend.offsetHeight;

        ctx.drawImage(
            legendCanvas,
            width - lw - 10,
            height - lh - 10,
            lw,
            lh
        );
    }

    return canvas.toDataURL("image/png");
}
function getReportTitle() {
    const program = window.PROGRAM_CODE || "Overview";

    const rangeType = document.getElementById("trend_range")?.value;

    if (rangeType === "custom") {
        const sy = document.getElementById("start_year")?.value;
        const sw = document.getElementById("start_week")?.value;
        const ey = document.getElementById("end_year")?.value;
        const ew = document.getElementById("end_week")?.value;

        return `${program} Report (W${sw}/${sy} – W${ew}/${ey})`;
    }

    return `${program} Report (Last ${rangeType} weeks)`;
}
