/* =========================================================================
   venta.js - Versión final optimizada, modular y comentada
   - Modular: Utils, Ajax, Render, Grafico, Tablas
   - Maneja auto-selección de tienda desde sesión
   - Reutilizable para dashboard / anulados / top clientes
   ========================================================================= */

let grafico = null;
let pieChart;
let PAGINA = ""; // "dashboard", "anulados", "otro"

/* ============================
   AJAX PROMISE - wrapper de $.post que devuelve Promise con JSON parseado
   ============================ */
function postJSON(url, data = {}) {
    return new Promise((resolve, reject) => {
        $.post(url, data)
            .done(resp => {
                try {
                    // Si ya es objeto, devolverlo
                    if (typeof resp === "object") return resolve(resp);
                    resolve(JSON.parse(resp));
                } catch (err) {
                    reject({ type: "parse_error", message: "Respuesta JSON inválida", raw: resp });
                }
            })
            .fail(() => reject({ type: "network", message: "Error de conexión" }));
    });
}

/* ============================
   RENDER: generadores de fila para tablas
   ============================ */
const Render = {
    // Renderiza fila de comprobante (fecha, badge, número)
    rcomprobante(c) {
        let badgeLabel = "Otro";
        let badgeClass = "bg-secondary";
        switch (String(c.Tipo)) {
            case "01": badgeLabel = "Factura"; badgeClass = "badge-factura"; break;
            case "03": badgeLabel = "Boleta";   badgeClass = "badge-boleta";  break;
            case "07": badgeLabel = "N. Crédito"; badgeClass = "badge-nota";  break;
        }
        return `
            <tr>
                <td class="text-center">${c.Fecha ?? ""}</td>
                <td class="text-center"><span class="badge-doc ${badgeClass}">${badgeLabel}</span></td>
                <td class="text-center"><strong>${c.Numero ?? ""}</strong></td>
            </tr>
        `;
    },

    // Render fila para top clientes (id, nombre, importe)
    rtopCliente(c) {
        // Asegurarse de que el campo importe exista y sea numérico
        const importe = c.FCC_Total_Comprobante ?? c.FCC_Total_Comprobante?.replace?.(',', '') ?? c.FCC_Total ?? 0;
        return `
            <tr>
                <td class="text-start" style="font-size: 11px; width: 10%;">${c.FCC_IdCliente ?? ""}</td>
                <td class="text-start" style="font-size: 11px; width: 65%;">${c.FCC_NombreCliente ?? ""}</td>
                <td class="text-end" style="font-size: 11px; width: 25%;">S/ ${Utils.formatearNumero(importe)}</td>
            </tr>
        `;
    },

    // Render fila para top clientes (id, nombre, importe)
    rtopProducto(c) {
        // Asegurarse de que el campo importe exista y sea numérico
        const importe = c.Importe ?? c.Importe?.replace?.(',', '') ?? c.FCC_Total ?? 0;
        const cantidad = c.Cantidad ?? c.Cantidad?.replace?.(',', '') ?? c.FCC_Total ?? 0;
        return `
            <tr>
                <td class="text-center" style="font-size: 11px; width: 10%;">${c.FCD_IdArticulo ?? ""}</td>
                <td class="text-start" style="font-size: 11px; width: 50%;">${c.AR_Descripcion ?? ""}</td>
                <td class="text-end" style="font-size: 11px; width: 15%;">${Utils.formatearNumero(cantidad)}</td>
                <td class="text-end" style="font-size: 11px; width: 25%;">S/ ${Utils.formatearNumero(importe)}</td>
            </tr>
        `;
    },
    // Render fila para top clientes (id, nombre, importe)
    rCredito(c) {
        // Asegurarse de que el campo importe exista y sea numérico
        const importe = c.CXC_Saldo ?? c.CXC_Saldo?.replace?.(',', '') ?? c.FCC_Total ?? 0;
         
        return `
            <tr>
                <td class="text-center" style="font-size: 11px; width: 10%;">${c.CXC_FechaEmision ?? ""}</td>
                <td class="text-center" style="font-size: 11px; width: 15%;">${c.FCC_NroDocumento ?? ""}</td>
                <td class="text-start" style="font-size: 11px; width: 50%;">${c.FCC_NombreCliente ?? ""}</td>
                <td class="text-end" style="font-size: 11px; width: 35%;">S/ ${Utils.formatearNumero(importe)}</td>
            </tr>
        `;
    },

        // Render fila para top clientes (id, nombre, importe)
    rComprobanteActivos(c) {
        // Asegurarse de que el campo importe exista y sea numérico
        const importe = c.FCC_Total_Comprobante ?? c.FCC_Total_Comprobante?.replace?.(',', '') ?? c.FCC_Total ?? 0;
         
        return `
            <tr>
                <td class="text-center" style="font-size: 11px; width: 10%;">${c.Fecha ?? ""}</td>
                <td class="text-center" style="font-size: 11px; width: 15%;">${c.Numero ?? ""}</td>
                <td class="text-start" style="font-size: 11px; width: 50%;">${c.FCC_NombreCliente ?? ""}</td>
                <td class="text-end" style="font-size: 11px; width: 35%;">S/ ${Utils.formatearNumero(importe)}</td>
            </tr>
        `;
    }


};


/* ============================
   ORDENADOR DE TABLAS GENÉRICO
   ============================ */
const OrdenarTabla = {

    /**
     * Ordena una tabla HTML por columna
     * @param {string} tablaId  (ej: "tablatopClientes")
     * @param {number} colIndex (ej: 0, 1, 2)
     * @param {string} tipo     "num" o "text"
     * @param {string} modo     "asc" o "desc"
     */
    ordenar(tablaId, colIndex, tipo = "text", modo = "asc") {
        const tabla = document.getElementById(tablaId);
        if (!tabla) return;

        let filas = Array.from(tabla.querySelectorAll("tr"));
        if (filas.length === 0) return;

        filas.sort((a, b) => {
            let A = a.children[colIndex]?.innerText.trim() ?? "";
            let B = b.children[colIndex]?.innerText.trim() ?? "";

            // Procesar según tipo
            if (tipo === "num") {
                A = parseFloat(A.replace(/[S\/]|,/g, "")) || 0;
                B = parseFloat(B.replace(/[S\/]|,/g, "")) || 0;
            } else {
                A = A.toLowerCase();
                B = B.toLowerCase();
            }

            if (modo === "asc") return A > B ? 1 : -1;
            return A < B ? 1 : -1;
        });

        tabla.innerHTML = "";
        filas.forEach(f => tabla.appendChild(f));
    },

    /**
     * Facilita aplicar ordenadores al hacer clic en encabezados
     */
    aplicar(tablaId, definiciones) {
        // definiciones: [{col:0, tipo:"num"}, {col:2, tipo:"text"}]
        const thead = document.querySelector(`#${tablaId}`).closest("table").querySelector("thead");
        if (!thead) return;

        definiciones.forEach(def => {
            const th = thead.querySelectorAll("th")[def.col];
            if (!th) return;

            let modo = "desc"; // por defecto ordenar descendente al primer clic

            th.style.cursor = "pointer";
            th.innerHTML += ` <span style="font-size:9px;">⇅</span>`;

            th.addEventListener("click", () => {
                OrdenarTabla.ordenar(tablaId, def.col, def.tipo, modo);
                modo = modo === "asc" ? "desc" : "asc";
            });
        });
    }
};

/* ============================
   GRAFICO: encapsula Chart.js
   ============================ */
const Grafico = {
    crear(canvasId, labels, valores, opcionesExtra = {}) {
        const canvas = document.getElementById(canvasId);
        if (!canvas) return null;

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

        if (grafico) grafico.destroy();

        // 🎨 Gradiente moderno
        const grad = ctx.createLinearGradient(0, 0, 0, 300);
        grad.addColorStop(0, "rgba(10, 158, 244, 0.9)");
        grad.addColorStop(1, "rgba(37,99,235,0.2)");

        grafico = new Chart(ctx, {
            type: "bar",
            data: {
                labels,
                datasets: [{
                    label: "Total S/ por día",
                    data: valores,
                    backgroundColor: grad,
                    borderRadius: 10,
                    borderSkipped: false,
                    barThickness: 28
                }]
            },
            options: {
                responsive: true,
                maintainAspectRatio: false,
                animation: {
                    duration: 900,
                    easing: "easeOutQuart"
                },
                plugins: {
                    legend: {
                        display: false
                    },
                    tooltip: {
                        backgroundColor: "#111827",
                        titleColor: "#fff",
                        bodyColor: "#e5e7eb",
                        padding: 12,
                        cornerRadius: 8,
                        callbacks: {
                            label: ctx => ` S/ ${Utils.formatearNumero(ctx.raw)}`
                        }
                    }
                },
                scales: {
                    x: {
                        grid: { display: false },
                        ticks: {
                            font: { size: 11 }
                        }
                    },
                    y: {
                        grid: {
                            borderDash: [6, 4],
                            color: "rgba(0,0,0,0.05)"
                        },
                        ticks: {
                            callback: v => "S/ " + Utils.formatearNumero(v),
                            font: { size: 11 }
                        }
                    }
                }
            }
        });

        return grafico;
    }
};

/* ============================
   TABLAS: función genérica para cargar tablas
   - recibe renderFila que convierte cada item a <tr>...</tr>
   ============================ */
function cargarTabla({ tablaId, postData = {}, renderFila, mensajeCargando = "Cargando...", mensajeVacio = "No hay datos", mensajeError = "Error al cargar datos", colspan = 3 }) {
    const $tabla = $(`#${tablaId}`);
    if (!$tabla.length) return;

    $tabla.html(Utils.htmlMensaje(colspan, mensajeCargando));

    const ipEnc = Utils.obtenerIpTienda();
    if (!ipEnc) {
        $tabla.html(Utils.htmlMensaje(colspan, "Seleccione una tienda", "text-center text-danger"));
        return;
    }

    postData.ipEnc = ipEnc;

    postJSON("../controllers/VentaController.php", postData)
        .then(datos => {
            if (!datos) {
                $tabla.html(Utils.htmlMensaje(colspan, mensajeVacio));
                return;
            }
            if (datos.error) {
                $tabla.html(Utils.htmlMensaje(colspan, datos.error, "text-center text-danger"));
                return;
            }

            if (!Array.isArray(datos) || datos.length === 0) {
                $tabla.html(Utils.htmlMensaje(colspan, mensajeVacio));
                return;
            }

            // map + join usando el render pasado
            const html = datos.map(item => renderFila(item)).join("");
            $tabla.html(html || Utils.htmlMensaje(colspan, mensajeVacio));
        })
        .catch(err => {
            console.error("Error cargarTabla:", err);
            const msg = err?.message || mensajeError;
            $tabla.html(Utils.htmlMensaje(colspan, msg, "text-center text-danger"));
        });
}

/* ============================
   FUNCIONES PRINCIPALES (dashboard / anulados)
   ============================ */

// Ejecuta consulta de dashboard (tarjetas + gráfico)
function ejecutarConsulta() {
    const inicioISO = $("#fechaInicio").val();
    const finISO = $("#fechaFin").val();

    if (!inicioISO || !finISO) { alert("Seleccione ambas fechas."); return; }
    const ipEnc = Utils.obtenerIpTienda();
    if (!ipEnc) { alert("Seleccione una tienda."); return; }

    Utils.mostrarLoader();

    const inicio = Utils.convertirFecha(inicioISO);
    const fin = Utils.convertirFecha(finISO);

    cargarGraficoFormaPago(inicio,fin,ipEnc);
    cargarCobranzas(inicio,fin,ipEnc);

    postJSON("../controllers/VentaController.php", { 
            obtenerReporteFacturas: true,
            inicio, 
            fin, 
            ipEnc 
        })
        .then(datos => {

            if (datos.error) { 
                alert(datos.error); 
                return; 
            }

            // Validar array
            if (!Array.isArray(datos)) return;

            // ============================
            // TARJETAS
            // ============================
            const total = datos.reduce((s, e) => s + parseFloat(e.total || 0), 0);
            const comprob = datos.reduce((s, e) => s + parseInt(e.comprobantes || 0), 0);

            if ($("#cardTotal").length) {
                $("#cardTotal").text("S/ " + Utils.formatearNumero(total));
            }

            if ($("#cardComprobantes").length) {
                $("#cardComprobantes").text(Utils.formatearNumero(comprob));
            }

            // ============================
            // GRÁFICO
            // ============================
            if (document.getElementById("graficoFacturas")) {

                const labels = datos.map(e => e.FECHA || e.tienda || "");
                const totales = datos.map(e => Number(e.total || 0));

                Grafico.crear("graficoFacturas", labels, totales);
            }

            // ============================
            // TABLAS
            // ============================
            if ($("#tablaComprobantes").length) {
                Tablas.comprobantes(inicio, fin);
            }

            if ($("#tablatopClientes").length) {
                Tablas.topClientes(inicio, fin);
            }

            if ($("#tablatopProductos").length) {
                Tablas.topProductos(inicio, fin);
            }

            if ($("#tablaCreditos").length) {
                Tablas.Creditos(inicio, fin);
            }

            if ($("#tablaVentaActivos").length) {
                Tablas.ComprobantesActivos(inicio, fin);
            }

        })
        .catch(err => {
            console.error("Error ejecutarConsulta:", err);
            alert("Error procesando datos del servidor.");
        })
        .finally(() => Utils.ocultarLoader());
}

/* ============================
   TABLAS específicas agrupadas
   ============================ */
const Tablas = {
    comprobantes(inicio, fin) {
        cargarTabla({
            tablaId: "tablaComprobantes",
            postData: { listarComprobantes: true, inicio, fin },
            renderFila: Render.rcomprobante,
            mensajeCargando: "Cargando comprobantes...",
            mensajeVacio: "No hay comprobantes",
            mensajeError: "Error al cargar comprobantes",
            colspan: 3
        });
    },

    topClientes(inicio, fin, top = 5) {
        // Si quieres permitir top dinámico, añade param top al postData
        cargarTabla({
            tablaId: "tablatopClientes",
            postData: { listarTopVentasClientes: true, inicio, fin, top },
            renderFila: Render.rtopCliente,
            mensajeCargando: "Cargando top clientes...",
            mensajeVacio: "No se registró ventas",
            mensajeError: "Error al cargar top clientes",
            colspan: 3
        });
    },

    topProductos(inicio, fin, top = 5) {
        // Si quieres permitir top dinámico, añade param top al postData
        cargarTabla({
            tablaId: "tablatopProductos",
            postData: { listarTopVentasProducto: true, inicio, fin, top },
            renderFila: Render.rtopProducto,
            mensajeCargando: "Cargando top productos...",
            mensajeVacio: "No se registró ventas",
            mensajeError: "Error al cargar top productos",
            colspan: 3
        });
    },
    Creditos(inicio, fin) {
        // Si quieres permitir top dinámico, añade param top al postData
        cargarTabla({
            tablaId: "tablaCreditos",
            postData: { listarCreditos: true, inicio, fin  },
            renderFila: Render.rCredito,
            mensajeCargando: "Cargando creditos...",
            mensajeVacio: "No se registró creditos",
            mensajeError: "Error al cargar creditos",
            colspan: 3
        });
    },
    ComprobantesActivos(inicio, fin) {
        // Si quieres permitir top dinámico, añade param top al postData
        cargarTabla({
            tablaId: "tablaVentaActivos",
            postData: { listarComprobantesActivos: true, inicio, fin  },
            renderFila: Render.rComprobanteActivos,
            mensajeCargando: "Cargando ventas...",
            mensajeVacio: "No se registró ventas",
            mensajeError: "Error al cargar ventas",
            colspan: 3
        });
    }


};

 

/* ============================
   DETECCIÓN E INICIALIZACIÓN
   ============================ */
function detectarPagina() {
    if (document.getElementById("graficoFacturas")) return "dashboard";
    if (document.getElementById("tablaComprobantes")) return "venta_anulado";
    if (document.getElementById("tablaVentaActivos")) return "venta_activo";
    if (document.getElementById("tablaCreditos")) return "creditos";
    return "otro";
}

document.addEventListener("DOMContentLoaded", function () {
    PAGINA = detectarPagina();

    const selectTienda = document.querySelector("select[name='tienda_ip']");
    const btnBuscar = document.getElementById("btnConsultar");

    // Evento change: guarda sesión y busca si aplica
    if (selectTienda) {
        selectTienda.addEventListener("change", function () {
            setNombreTienda(this);
            // En dashboard y anulados, disparar búsqueda automática
            if (btnBuscar) btnBuscar.click();
        });
    }

    // Inicializa fechas a hoy si existen
    //const hoy = fechaBogota();//new Date().toISOString().slice(0, 10);
    const hoy = new Date().toISOString().slice(0, 10);
    if ($("#fechaInicio").length) $("#fechaInicio").val(hoy);
    if ($("#fechaFin").length) $("#fechaFin").val(hoy);
 
    // Intentar recuperar tienda guardada en sesión y auto-seleccionar
    postJSON("../controllers/TiendaController.php", { obtenerSesion: true })
        .then(ses => {
            if (!ses || !ses.ip_enc) return;
            const select = document.querySelector("select[name='tienda_ip']");
            if (!select) return;
            const opcion = [...select.options].find(opt => opt.value === ses.ip_enc);
            if (opcion) {
                // establecer valor y sincronizar UI
                select.value = ses.ip_enc;
                setNombreTienda(opcion);
                // Ejecutar búsqueda inicial dependiendo de la página
                if (btnBuscar) {
                    // si dashboard -> ejecutarConsulta (usa fechas inicializadas)
                    // si anulados -> cargar tablas
                    if (PAGINA === "dashboard") btnBuscar.click();
                    else if (PAGINA === "venta_activo") btnBuscar.click();
                    else if (PAGINA === "venta_anulado") btnBuscar.click();
                    else if (PAGINA === "creditos") btnBuscar.click();
                }
            }
        })
        .catch(err => {
            // No crítico; sólo logueamos
            console.warn("No se pudo recuperar sesión de tienda:", err);
        });


 

        // Activar ordenamiento en tabla Top Clientes
        if (document.getElementById("tablatopClientes")) {
            OrdenarTabla.aplicar("tablatopClientes", [
                { col: 0, tipo: "text" },
                { col: 1, tipo: "text" },
                { col: 2, tipo: "num" } // importe
            ]);


            OrdenarTabla.aplicar("tablatopProductos", [
                { col: 0, tipo: "text" },
                { col: 1, tipo: "text" },
                { col: 2, tipo: "num" },
                { col: 3, tipo: "num" }
            ]);

        }


        if (document.getElementById("tablaCreditos")) {
            OrdenarTabla.aplicar("tablaCreditos", [
                { col: 0, tipo: "text" },
                { col: 1, tipo: "text" },
                { col: 2, tipo: "text" },
                { col: 3, tipo: "num" }
            ]);

        }

        if (document.getElementById("tablaComprobantes")) {
            OrdenarTabla.aplicar("tablaComprobantes", [
                { col: 0, tipo: "text" },
                { col: 1, tipo: "text" },
                { col: 2, tipo: "text" }
            ]);

        }

        if (document.getElementById("tablaVentaActivos")) {
            OrdenarTabla.aplicar("tablaVentaActivos", [
                { col: 0, tipo: "text" },
                { col: 1, tipo: "text" },
                { col: 2, tipo: "text" },
                { col: 3, tipo: "num" }
            ]);

        }




        /* AUTOCARGA DE TIENDA DESDE SESIÓN */
        try {
            const tiendaSesion = window.TIENDA_SESION || "";

            if (tiendaSesion !== "") {
                const select = document.getElementById("sel_tienda");
                if (select) {
                    select.value = tiendaSesion;
                    console.log("Tienda cargada automáticamente desde sesión:", tiendaSesion);
                }
            }
        } catch (e) {
            console.error("Error al cargar tienda desde sesión:", e);
        }


});

/* ============================
   BIND BOTÓN CONSULTAR (único control)
   ============================ */
$(document).ready(function () {

    if (!$("#btnConsultar").length) return;
    $("#btnConsultar").on("click", function (e) {
        e.preventDefault();
        const datos = initform();
        if (!datos) return;
        const inicio = datos.inicio;
        const fin = datos.fin;
        // Ejecutar la acción correspondiente según la página
        if (PAGINA === "dashboard") {
            ejecutarConsulta();
            return;
        }
 
        if (PAGINA === "venta_anulado") {

            Tablas.comprobantes(inicio, fin);
            return;
        }


        if (PAGINA === "creditos") {
            Tablas.Creditos(inicio, fin);
            return;
        }

        // "otro" o fallback
        ejecutarConsulta();
        
    });
});

 
function dibujarGrafico(credito, contado) {
    const canvas = document.getElementById('pieVentas');
    if (!canvas) return;

    const ctx = canvas.getContext('2d');

    if (pieChart) pieChart.destroy();

    pieChart = new Chart(ctx, {
        type: 'doughnut', // Donut
        data: {
            labels: [
                `Crédito: S/ ${Utils.formatearNumero(credito)}`,
                `Contado: S/ ${Utils.formatearNumero(contado)}`
            ],
            datasets: [{
                data: [credito, contado],
                backgroundColor: ['#f59e0b', '#10b981'],
                hoverOffset: 8,
                borderWidth: 2,
                borderColor: '#ffffff'
            }]
        },
        options: {
            cutout: '65%', // hueco central
            responsive: true,
            plugins: {
                legend: {
                    position: 'bottom',
                    labels: {
                        usePointStyle: true,
                        font: { size: 13 }
                    }
                },
                tooltip: {
                    callbacks: {
                        label: ctx => {
                            const val = ctx.raw || 0;
                            return `${ctx.label}`;
                        }
                    }
                }
            }
        }
    });
}


function ajaxVentas(data, procesarRespuesta) {

    $.ajax({
        url: "../controllers/VentaController.php",
        type: "POST",
        dataType: "json",
        data: data,

        beforeSend: () => $('#loader-overlay').fadeIn(),

        success: function(response){
            procesarRespuesta(response);
        },

        complete: () => $('#loader-overlay').fadeOut(),

        error: function(err){
            console.error("Error en petición AJAX", err);
        }

    });
}


function cargarGraficoFormaPago(inicio, fin, ipEnc) {

    ajaxVentas({
        listarFormaPago_fecha: true,
        inicio: inicio,
        fin: fin,
        ipEnc: ipEnc
    }, function(response){

        let credito = 0;
        let contado = 0;

        response.forEach(item => {

            if (item.FCC_IdCondicion === 'CREDITO') {
                credito = parseFloat(item.Total);
            }

            if (item.FCC_IdCondicion === 'CONTADO') {
                contado = parseFloat(item.Total);
            }

        });

        if ($("#cardCreditos").length) {
            $("#cardCreditos").text("S/ " + Utils.formatearNumero(credito));
        }

        dibujarGrafico(credito, contado);

    });

}

function cargarCobranzas(inicio, fin, ipEnc) {

    ajaxVentas({
        listarCobranzas_fecha: true,
        inicio: inicio,
        fin: fin,
        ipEnc: ipEnc
    }, function(response){

        let total = 0;

        if (Array.isArray(response)) {

            response.forEach(item => {

                if (item?.Tipo === 'Cobranzas') {

                    const valor = parseFloat(item.Total);

                    if (!isNaN(valor)) {
                        total += valor;
                    }

                }

            });

        }

        if ($("#cardCobranzas").length) {
            $("#cardCobranzas").text("S/ " + Utils.formatearNumero(total));
        }

    });

}


 