/**
 * Gestión y Control de Caja - Sistema Sufarma (Fase 2.2)
 * Autor: Premium Web Developer Specialist
 * State management, modal events, live differences, and ticket printing.
 */

class CajaManager {
    constructor() {
        this.activeSession = null;
        this.currentDrawerBalance = 0;
        this.expectedDrawerBalance = 0;
        this.init();
    }

    init() {
        document.addEventListener('DOMContentLoaded', () => {
            this.bindEvents();
            this.checkSessionState();
        });
    }

    bindEvents() {
        // Toggle Control de Caja button click
        const btnControlCaja = document.getElementById('btnControlCaja');
        if (btnControlCaja) {
            btnControlCaja.addEventListener('click', (e) => {
                e.preventDefault();
                if (this.activeSession) {
                    this.openControlModal();
                } else {
                    this.showToast("Debe abrir una sesión de caja para acceder al control.", "error");
                }
            });
        }

        // Close Control Modal button click
        const btnCloseControlCaja = document.getElementById('btnCloseControlCaja');
        if (btnCloseControlCaja) {
            btnCloseControlCaja.addEventListener('click', () => {
                document.getElementById('modalControlCaja').style.display = 'none';
            });
        }

        // Opening form submit
        const formAperturaCaja = document.getElementById('formAperturaCaja');
        if (formAperturaCaja) {
            formAperturaCaja.addEventListener('submit', (e) => {
                e.preventDefault();
                this.executeOpening();
            });
        }

        // Tabs bindings
        const tabMovimientosBtn = document.getElementById('tabMovimientosBtn');
        const tabCorteBtn = document.getElementById('tabCorteBtn');
        if (tabMovimientosBtn && tabCorteBtn) {
            tabMovimientosBtn.addEventListener('click', () => this.switchTab('movimientos'));
            tabCorteBtn.addEventListener('click', () => this.switchTab('corte'));
        }

        // Movement form submit
        const formCajaMovimiento = document.getElementById('formCajaMovimiento');
        if (formCajaMovimiento) {
            formCajaMovimiento.addEventListener('submit', (e) => {
                e.preventDefault();
                this.executeMovement();
            });
        }

        // Live Arqueo difference calculation
        const cierreRealInput = document.getElementById('cierreRealInput');
        if (cierreRealInput) {
            cierreRealInput.addEventListener('input', () => {
                this.calculateLiveDifference();
            });
        }

        // Listen to radio changes for Corte Type (Parcial vs Final)
        const inputsTipoCierre = document.querySelectorAll('input[name="tipoCierre"]');
        inputsTipoCierre.forEach(input => {
            input.addEventListener('change', () => {
                this.updateTipoCierreUI();
            });
        });

        // Closure submit button
        const btnEfectuarCierre = document.getElementById('btnEfectuarCierre');
        if (btnEfectuarCierre) {
            btnEfectuarCierre.addEventListener('click', () => {
                this.executeClosure();
            });
        }

        // Print ticket button
        const btnImprimirTicket = document.getElementById('btnImprimirTicket');
        if (btnImprimirTicket) {
            btnImprimirTicket.addEventListener('click', () => {
                window.print();
            });
        }

        // Close ticket modal & force opening block again
        const btnCerrarTicketModal = document.getElementById('btnCerrarTicketModal');
        if (btnCerrarTicketModal) {
            btnCerrarTicketModal.addEventListener('click', () => {
                document.getElementById('modalCorteTicket').style.display = 'none';
                this.checkSessionState(); // Habilitará el bloqueo del POS
            });
        }
    }

    async checkSessionState() {
        try {
            const response = await fetch('api/caja/estado_sesion.php');
            const data = await response.json();

            if (data.success && data.activa) {
                this.activeSession = data.sesion;
                this.updateStatusIndicator(true, data.sesion.nombre_usuario);
                document.getElementById('modalAperturaCaja').style.display = 'none';
            } else {
                this.activeSession = null;
                this.updateStatusIndicator(false);
                this.showOpeningModal();
            }
        } catch (error) {
            console.error("Error checking cash session state:", error);
            this.showToast("Error de conexión al verificar el estado de caja.", "error");
        }
    }

    updateStatusIndicator(isOpen, cashierName = '') {
        const badge = document.getElementById('cajaStatusBadge');
        if (badge) {
            if (isOpen) {
                badge.textContent = "Abierta";
                badge.style.background = "#10b981"; // Green
                badge.style.boxShadow = "0 0 10px rgba(16, 185, 129, 0.4)";
            } else {
                badge.textContent = "Cerrada";
                badge.style.background = "#ef4444"; // Red
                badge.style.boxShadow = "none";
            }
        }
    }

    async showOpeningModal() {
        document.getElementById('modalAperturaCaja').style.display = 'flex';
        await this.loadCashiers();
    }

    async loadCashiers(selectId = 'aperturaUsuarioSelect') {
        const select = document.getElementById(selectId);
        if (!select) return;
        select.innerHTML = '<option value="">-- Cargando cajeros... --</option>';

        try {
            const response = await fetch('api/pedidos/obtener_usuarios.php');
            const data = await response.json();

            if (data.success && data.usuarios) {
                let html = '<option value="">-- Seleccione el Cajero --</option>';
                data.usuarios.forEach(user => {
                    html += `<option value="${user.id}">${user.nombre} (${user.codigo_usuario})</option>`;
                });
                select.innerHTML = html;
            } else {
                select.innerHTML = '<option value="">Error cargando cajeros</option>';
            }
        } catch (error) {
            select.innerHTML = '<option value="">Error de conexión</option>';
        }
    }

    async executeOpening() {
        const userSelect = document.getElementById('aperturaUsuarioSelect');
        const montoInput = document.getElementById('aperturaMontoInput');

        const usuario_id = parseInt(userSelect.value);
        const monto_apertura = parseFloat(montoInput.value);

        if (!usuario_id || isNaN(monto_apertura)) {
            this.showToast("Ingrese todos los campos correspondientes.", "error");
            return;
        }

        try {
            const response = await fetch('api/caja/abrir.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ usuario_id, monto_apertura })
            });

            const data = await response.json();

            if (data.success) {
                this.showToast("Caja abierta correctamente. Sistema POS listo.", "success");
                montoInput.value = '';
                userSelect.value = '';
                this.checkSessionState();
            } else {
                this.showToast(data.error || "No se pudo abrir la caja.", "error");
            }
        } catch (error) {
            this.showToast("Error de servidor al abrir la caja.", "error");
        }
    }

    switchTab(tab) {
        const tabMovimientosBtn = document.getElementById('tabMovimientosBtn');
        const tabCorteBtn = document.getElementById('tabCorteBtn');
        const tabMovimientos = document.getElementById('tabMovimientos');
        const tabCorte = document.getElementById('tabCorte');

        if (tab === 'movimientos') {
            tabMovimientosBtn.classList.add('active-tab');
            tabCorteBtn.classList.remove('active-tab');
            tabMovimientos.style.display = 'block';
            tabCorte.style.display = 'none';
        } else {
            tabCorteBtn.classList.add('active-tab');
            tabMovimientosBtn.classList.remove('active-tab');
            tabMovimientos.style.display = 'none';
            tabCorte.style.display = 'block';
            this.loadClosureDetails();
        }
    }

    async openControlModal() {
        document.getElementById('modalControlCaja').style.display = 'flex';
        this.switchTab('movimientos');

        const headerText = document.getElementById('cajaSesionUsuarioText');
        if (headerText && this.activeSession) {
            headerText.innerHTML = `Cajero activo: <strong>${this.activeSession.nombre_usuario}</strong> | Turno iniciado: <strong>${this.activeSession.fecha_apertura}</strong>`;
        }
    }

    async executeMovement() {
        const tipoRadio = document.querySelector('input[name="movimientoTipo"]:checked');
        const montoInput = document.getElementById('movimientoMonto');
        const motivoText = document.getElementById('movimientoMotivo');

        if (!this.activeSession) return;

        const tipo = tipoRadio.value;
        const monto = parseFloat(montoInput.value);
        const motivo = motivoText.value.trim();

        if (isNaN(monto) || monto <= 0 || !motivo) {
            this.showToast("Ingrese un monto válido y justificación.", "error");
            return;
        }

        try {
            const response = await fetch('api/caja/registrar_movimiento.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    sesion_id: this.activeSession.id,
                    tipo: tipo,
                    monto: monto,
                    motivo: motivo,
                    usuario_id: this.activeSession.usuario_id
                })
            });

            const data = await response.json();

            if (data.success) {
                this.showToast(`Ajuste (${tipo.toUpperCase()}) registrado exitosamente.`, "success");
                montoInput.value = '';
                motivoText.value = '';
            } else {
                this.showToast(data.error || "No se pudo registrar el ajuste.", "error");
            }
        } catch (error) {
            this.showToast("Error de conexión al registrar el movimiento.", "error");
        }
    }

    async loadClosureDetails() {
        if (!this.activeSession) return;

        try {
            const response = await fetch(`api/caja/obtener_detalle_cierre.php?sesion_id=${this.activeSession.id}`);
            const data = await response.json();

            if (data.success && data.sesion) {
                const s = data.sesion;
                this.expectedDrawerBalance = s.saldo_esperado;

                document.getElementById('cierreAperturaText').textContent = `Q ${s.monto_apertura.toFixed(2)}`;
                document.getElementById('cierreVentasEfectivoText').textContent = `Q ${s.ventas_efectivo.toFixed(2)}`;
                document.getElementById('cierreIngresosText').textContent = `Q ${s.ingresos_extras.toFixed(2)}`;
                document.getElementById('cierreEgresosText').textContent = `Q ${s.egresos.toFixed(2)}`;
                document.getElementById('cierreEsperadoText').textContent = `Q ${s.saldo_esperado.toFixed(2)}`;

                // Reset physical declared input and differential evaluation
                document.getElementById('cierreRealInput').value = '';
                this.calculateLiveDifference();

                // Reset to Corte Parcial (safe informative state) by default
                const radioParcial = document.querySelector('input[name="tipoCierre"][value="parcial"]');
                if (radioParcial) {
                    radioParcial.checked = true;
                }
                this.updateTipoCierreUI();

                // Cargar cajeros para el cierre y preseleccionar el cajero activo
                await this.loadCashiers('cierreUsuarioSelect');
                if (this.activeSession && this.activeSession.usuario_id) {
                    const selectCierre = document.getElementById('cierreUsuarioSelect');
                    if (selectCierre) {
                        selectCierre.value = this.activeSession.usuario_id;
                    }
                }
            } else {
                this.showToast("No se pudieron cargar las estadísticas del cierre.", "error");
            }
        } catch (error) {
            this.showToast("Error de conexión al obtener estadísticas de caja.", "error");
        }
    }

    calculateLiveDifference() {
        const cierreRealInput = document.getElementById('cierreRealInput');
        const physicalValue = parseFloat(cierreRealInput.value);
        
        const diffMonto = document.getElementById('cierreDiferenciaMonto');
        const diffEstado = document.getElementById('cierreDiferenciaEstado');
        const container = document.getElementById('cierreDiferenciaContainer');

        if (isNaN(physicalValue)) {
            diffMonto.textContent = 'Q 0.00';
            diffMonto.style.color = '#475569';
            diffEstado.textContent = 'SIN CUADRAR';
            diffEstado.style.color = '#64748b';
            container.style.background = '#f1f5f9';
            container.style.borderColor = '#e2e8f0';
            return;
        }

        const diferencia = physicalValue - this.expectedDrawerBalance;
        diffMonto.textContent = `Q ${Math.abs(diferencia).toFixed(2)}`;

        // Exact match
        if (Math.abs(diferencia) < 0.01) {
            diffMonto.textContent = 'Q 0.00';
            diffMonto.style.color = '#10b981';
            diffEstado.textContent = 'Caja Cuadrada Perfecta';
            diffEstado.style.color = '#065f46';
            container.style.background = '#d1fae5';
            container.style.borderColor = '#a7f3d0';
        } else if (diferencia > 0) {
            diffMonto.style.color = '#0284c7';
            diffEstado.textContent = `Sobrante (+Q ${diferencia.toFixed(2)})`;
            diffEstado.style.color = '#075985';
            container.style.background = '#e0f2fe';
            container.style.borderColor = '#bae6fd';
        } else {
            diffMonto.style.color = '#ef4444';
            diffEstado.textContent = `Faltante (-Q ${Math.abs(diferencia).toFixed(2)})`;
            diffEstado.style.color = '#991b1b';
            container.style.background = '#fee2e2';
            container.style.borderColor = '#fca5a5';
        }
    }

    updateTipoCierreUI() {
        const lblParcial = document.getElementById('lblCorteParcial');
        const lblFinal = document.getElementById('lblCorteFinal');
        const radioParcial = document.querySelector('input[name="tipoCierre"][value="parcial"]');
        const btnCierre = document.getElementById('btnEfectuarCierre');

        if (!lblParcial || !lblFinal || !radioParcial || !btnCierre) return;

        if (radioParcial.checked) {
            // Active styling for Parcial
            lblParcial.style.background = 'white';
            lblParcial.style.color = '#0284c7';
            lblParcial.style.boxShadow = '0 4px 6px -1px rgba(0,0,0,0.05)';
            
            // Passive styling for Final
            lblFinal.style.background = 'transparent';
            lblFinal.style.color = '#64748b';
            lblFinal.style.boxShadow = 'none';

            // Button styling for Parcial
            btnCierre.style.background = 'linear-gradient(135deg, #0284c7, #0369a1)';
            btnCierre.style.boxShadow = '0 4px 10px rgba(3, 105, 161, 0.2)';
            btnCierre.textContent = 'Imprimir Corte Parcial (X)';
        } else {
            // Passive styling for Parcial
            lblParcial.style.background = 'transparent';
            lblParcial.style.color = '#64748b';
            lblParcial.style.boxShadow = 'none';
            
            // Active styling for Final
            lblFinal.style.background = 'white';
            lblFinal.style.color = '#dc2626';
            lblFinal.style.boxShadow = '0 4px 6px -1px rgba(0,0,0,0.05)';

            // Button styling for Final
            btnCierre.style.background = 'linear-gradient(135deg, #dc2626, #b91c1c)';
            btnCierre.style.boxShadow = '0 4px 10px rgba(220, 38, 38, 0.2)';
            btnCierre.textContent = 'Efectuar Cierre Final (Z) & Imprimir';
        }
    }

    async executeClosure() {
        const cierreUserSelect = document.getElementById('cierreUsuarioSelect');
        const usuario_id_cierre = parseInt(cierreUserSelect ? cierreUserSelect.value : 0);

        if (!usuario_id_cierre) {
            this.showToast("Por favor, seleccione el cajero que realiza el cierre.", "error");
            return;
        }

        const cierreRealInput = document.getElementById('cierreRealInput');
        const physicalValue = parseFloat(cierreRealInput.value);

        if (isNaN(physicalValue) || physicalValue < 0) {
            this.showToast("Por favor, ingrese el monto físico real de efectivo.", "error");
            return;
        }

        // Obtener el tipo de cierre seleccionado (parcial o final)
        const radioTipoCierre = document.querySelector('input[name="tipoCierre"]:checked');
        const tipo_cierre = radioTipoCierre ? radioTipoCierre.value : 'final';

        const diferencia = physicalValue - this.expectedDrawerBalance;
        const labelTipo = tipo_cierre === 'parcial' ? 'corte parcial' : 'cierre final';
        let warningText = `¿Está seguro de que desea realizar el ${labelTipo} de caja?`;
        
        if (Math.abs(diferencia) >= 0.01) {
            const labelDiff = diferencia > 0 ? "sobrante" : "faltante";
            warningText += `\n\n⚠️ ¡ATENCIÓN!: Se detectó un ${labelDiff} de Q ${Math.abs(diferencia).toFixed(2)}.`;
        }

        if (!confirm(warningText)) {
            return;
        }

        try {
            const response = await fetch('api/caja/cerrar.php', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({
                    sesion_id: this.activeSession.id,
                    monto_cierre_real: physicalValue,
                    usuario_id_cierre: usuario_id_cierre,
                    tipo_cierre: tipo_cierre
                })
            });

            const data = await response.json();

            if (data.success && data.resumen) {
                const r = data.resumen;
                if (r.tipo_cierre === 'parcial') {
                    this.showToast("Corte parcial generado exitosamente.", "success");
                } else {
                    this.showToast("Caja cerrada de forma segura.", "success");
                }
                
                document.getElementById('modalControlCaja').style.display = 'none';
                
                // Cargar detalles en el Ticket Imprimible
                document.getElementById('ticketIdText').textContent = r.id;
                document.getElementById('ticketCajeroText').textContent = r.cajero;
                
                const ticketCajeroCierre = document.getElementById('ticketCajeroCierreText');
                if (ticketCajeroCierre) {
                    ticketCajeroCierre.textContent = r.cajero_cierre;
                }

                document.getElementById('ticketFechaAperturaText').textContent = r.fecha_apertura;
                document.getElementById('ticketFechaCierreText').textContent = r.fecha_cierre;
                
                // Actualizar el título del reporte en el ticket dinámicamente
                const ticketTitulo = document.getElementById('ticketReporteTitulo');
                if (ticketTitulo) {
                    ticketTitulo.textContent = r.tipo_cierre === 'parcial' 
                        ? 'REPORTE DE CORTE PARCIAL (X)' 
                        : 'REPORTE DE CORTE FINAL (Z)';
                }

                document.getElementById('ticketAperturaMonto').textContent = `Q ${r.monto_apertura.toFixed(2)}`;
                document.getElementById('ticketVentasEfectivo').textContent = `Q ${r.ventas_efectivo.toFixed(2)}`;
                document.getElementById('ticketIngresosMonto').textContent = `Q ${r.ingresos_extras.toFixed(2)}`;
                document.getElementById('ticketEgresosMonto').textContent = `Q ${r.egresos.toFixed(2)}`;
                document.getElementById('ticketEsperadoMonto').textContent = `Q ${r.saldo_esperado.toFixed(2)}`;
                document.getElementById('ticketRealMonto').textContent = `Q ${r.monto_cierre_real.toFixed(2)}`;
                
                const absDiff = Math.abs(r.diferencia);
                const prefixDiff = r.diferencia >= 0 ? '+' : '-';
                document.getElementById('ticketDiferenciaMonto').textContent = `${prefixDiff}Q ${absDiff.toFixed(2)}`;

                const evaluation = document.getElementById('ticketDiferenciaEvaluacion');
                if (absDiff < 0.01) {
                    evaluation.textContent = "CAJA CUADRADA CORRECTAMENTE";
                    evaluation.style.color = '#047857';
                } else if (r.diferencia > 0) {
                    evaluation.textContent = `SOBRANTE DE EFECTIVO (+Q ${absDiff.toFixed(2)})`;
                    evaluation.style.color = '#0369a1';
                } else {
                    evaluation.textContent = `FALTANTE DE EFECTIVO (-Q ${absDiff.toFixed(2)})`;
                    evaluation.style.color = '#b91c1c';
                }

                // Poblar historial de cortes parciales en el ticket (solo visible en Cierre Final Z)
                const seccionParciales = document.getElementById('ticketCortesParciales');
                const listaParciales = document.getElementById('ticketCortesParcialesLista');
                if (seccionParciales && listaParciales) {
                    if (r.tipo_cierre === 'final' && r.cortes_parciales && r.cortes_parciales.length > 0) {
                        let htmlParciales = '';
                        r.cortes_parciales.forEach((cp, idx) => {
                            const horaCorte = cp.hora ? cp.hora.substring(11, 16) : '--:--';
                            const diffPrefix = cp.diferencia >= 0 ? '+' : '-';
                            htmlParciales += `
                                <div style="border: 1px dashed #999; border-radius: 4px; padding: 6px 8px; margin-bottom: 6px;">
                                    <strong>Corte X #${idx + 1}</strong> — ${horaCorte} hrs<br>
                                    Cajero: ${cp.cajero}<br>
                                    Declarado: Q ${cp.declarado.toFixed(2)} | Esperado: Q ${cp.esperado.toFixed(2)}<br>
                                    Diferencia: ${diffPrefix}Q ${Math.abs(cp.diferencia).toFixed(2)}
                                </div>`;
                        });
                        listaParciales.innerHTML = htmlParciales;
                        seccionParciales.style.display = 'block';
                    } else {
                        seccionParciales.style.display = 'none';
                        listaParciales.innerHTML = '';
                    }
                }

                // Mostrar el modal del ticket para impresión
                document.getElementById('modalCorteTicket').style.display = 'flex';
                
                // Si es un corte parcial, NO invalidamos la sesión ni bloqueamos el POS
                if (r.tipo_cierre === 'final') {
                    this.activeSession = null;
                    this.updateStatusIndicator(false);
                }
            } else {
                this.showToast(data.error || "Ocurrió un error al efectuar el cierre.", "error");
            }
        } catch (error) {
            this.showToast("Error de servidor al efectuar el cierre de caja.", "error");
        }
    }

    showToast(msg, type = 'info') {
        // Usa la función showToast de POS si está disponible globalmente
        if (window.pos && typeof window.pos.showToast === 'function') {
            window.pos.showToast(msg, type);
            return;
        }

        // Fallback si no está cargado pos.js
        const toast = document.createElement('div');
        let icon = type === 'error' ? '❌' : (type === 'success' ? '✅' : 'ℹ️');
        toast.innerHTML = `<span style="font-size: 1.1rem; margin-right: 8px;">${icon}</span> <span>${msg}</span>`;

        Object.assign(toast.style, {
            position: 'fixed', bottom: '30px', left: '50%', transform: 'translateX(-50%) translateY(20px)',
            background: type === 'error' ? '#ef4444' : (type === 'success' ? '#10b981' : '#3b82f6'),
            color: 'white', padding: '12px 24px', borderRadius: '100px',
            boxShadow: '0 10px 25px rgba(0,0,0,0.1)', zIndex: '100002', fontSize: '14px', fontWeight: '600',
            opacity: '0', transition: 'all 0.4s cubic-bezier(0.16, 1, 0.3, 1)', fontFamily: 'sans-serif',
            display: 'flex', alignItems: 'center'
        });

        document.body.appendChild(toast);
        requestAnimationFrame(() => {
            toast.style.opacity = '1';
            toast.style.transform = 'translateX(-50%) translateY(0)';
        });

        setTimeout(() => {
            toast.style.opacity = '0';
            toast.style.transform = 'translateX(-50%) translateY(20px)';
            setTimeout(() => { toast.remove(); }, 400);
        }, 3000);
    }
}

// Inicializar el Manager Global de Caja
window.cajaManager = new CajaManager();
