// /home/Autopartes/pos/static/js/invoicing.js
// Invoicing module — wired to design-system HTML IDs
// Tabs: panel-facturas, panel-notas, panel-complementos, panel-cancelaciones, panel-config
// Modals: modalDetalleOverlay, modalCancelOverlay

const Invoicing = (() => {
    const API = '/pos/api/invoicing';

    function token() {
        return localStorage.getItem('pos_token') || '';
    }

    function headers() {
        return { 'Authorization': `Bearer ${token()}`, 'Content-Type': 'application/json' };
    }

    async function api(path, opts = {}) {
        const res = await fetch(`${API}${path}`, { headers: headers(), ...opts });
        if (!res.ok) {
            const err = await res.json().catch(() => ({ error: res.statusText }));
            throw new Error(err.error || 'Request failed');
        }
        return res.json();
    }

    function fmt(n) {
        return parseFloat(n || 0).toLocaleString('es-MX', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
    }

    // ---- Auth check ----
    function checkAuth() {
        if (!token()) {
            window.location.href = '/pos/login';
            return false;
        }
        return true;
    }

    // ---- Tab switching (matches design system onclick="switchTab('xxx')") ----
    function switchTab(name) {
        // Deactivate all tabs
        document.querySelectorAll('.tab-btn').forEach(btn => {
            btn.classList.remove('is-active');
            btn.setAttribute('aria-selected', 'false');
        });
        document.querySelectorAll('.tab-panel').forEach(p => p.classList.remove('is-active'));

        // Activate the clicked tab button
        const tabBtn = document.querySelector(`.tab-btn[onclick*="'${name}'"]`) ||
                       document.getElementById(`tab-${name}`);
        if (tabBtn) {
            tabBtn.classList.add('is-active');
            tabBtn.setAttribute('aria-selected', 'true');
        }

        // Activate the target panel
        const panel = document.getElementById(`panel-${name}`);
        if (panel) panel.classList.add('is-active');

        // Load data for the activated tab
        if (name === 'facturas') loadFacturas();
        if (name === 'notas') loadNotas();
        if (name === 'complementos') loadComplementos();
        if (name === 'cancelaciones') loadCancelaciones();
        if (name === 'config') loadFacturapiStatus();
    }

    // ---- Badge helpers ----
    function statusBadge(status) {
        const map = {
            pending: { css: 'badge--pendiente', label: 'Pendiente' },
            pendiente: { css: 'badge--pendiente', label: 'Pendiente' },
            sending: { css: 'badge--proceso', label: 'Enviando' },
            stamped: { css: 'badge--timbrada', label: 'Timbrada' },
            timbrada: { css: 'badge--timbrada', label: 'Timbrada' },
            failed: { css: 'badge--rechazada', label: 'Fallido' },
            cancelled: { css: 'badge--cancelada', label: 'Cancelada' },
            cancelada: { css: 'badge--cancelada', label: 'Cancelada' },
            ppd: { css: 'badge--ppd', label: 'PPD' },
            proceso: { css: 'badge--proceso', label: 'En proceso' },
            aceptada: { css: 'badge--aceptada', label: 'Aceptada SAT' },
            rechazada: { css: 'badge--rechazada', label: 'Rechazada SAT' },
        };
        const s = map[status] || { css: '', label: status || '' };
        return `<span class="badge ${s.css}">${s.label}</span>`;
    }

    // ---- Facturas (Tab 1) — loads from CFDI queue with type=Ingreso ----
    let facturasCache = [];

    async function loadFacturas() {
        const panel = document.getElementById('panel-facturas');
        if (!panel) return;
        const tbody = panel.querySelector('.data-table tbody');
        if (!tbody) return;

        const statusFilter = document.getElementById('facturas-status-filter');
        const status = statusFilter ? statusFilter.value : '';
        const url = status ? `/queue?per_page=50&type=ingreso&status=${status}` : '/queue?per_page=50&type=ingreso';

        tbody.innerHTML = '<tr><td colspan="10" style="padding:var(--space-6);">' + renderLoadingState({ message: 'Cargando facturas...' }) + '</td></tr>';

        try {
            const res = await api(url);
            facturasCache = res.data || [];
            renderFacturas(facturasCache, res.pagination?.total || facturasCache.length);
        } catch (e) {
            tbody.innerHTML = '<tr><td colspan="10" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Error', subtitle: e.message }) + '</td></tr>';
        }
    }

    function renderFacturas(items, total) {
        const panel = document.getElementById('panel-facturas');
        const tbody = panel.querySelector('.data-table tbody');
        if (!items.length) {
            tbody.innerHTML = '<tr><td colspan="10" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Sin facturas', subtitle: 'No hay facturas en este periodo.' }) + '</td></tr>';
            return;
        }
        tbody.innerHTML = items.map(item => `<tr>
            <td class="td--mono">${item.provisional_folio || item.id || '-'}</td>
            <td class="td--primary">${item.serie || '-'}</td>
            <td class="td--primary">${item.customer_name || '-'}</td>
            <td class="td--mono">${item.rfc || '-'}</td>
            <td class="td--amount">$${fmt(item.subtotal)}</td>
            <td class="td--amount">$${fmt(item.tax_total)}</td>
            <td class="td--amount">$${fmt(item.total)}</td>
            <td style="font-size:var(--text-caption);">${item.payment_method || '-'}</td>
            <td>${statusBadge(item.status)}</td>
            <td>
                <div style="display:flex;gap:4px;">
                    <button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">Ver</button>
                    ${item.sale_id ? `<a href="${API}/${item.sale_id}/pdf" target="_blank" class="btn btn--ghost btn--sm">PDF</a>` : ''}
                    ${item.status === 'stamped' ? `<button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">XML</button>` : ''}
                </div>
            </td>
        </tr>`).join('');

        const footer = panel.querySelector('.table-footer span');
        if (footer) footer.textContent = `Mostrando 1\u2013${items.length} de ${total} facturas`;
    }

    function filterFacturas() {
        const q = (document.getElementById('facturas-search')?.value || '').toLowerCase();
        const filtered = facturasCache.filter(item =>
            (item.provisional_folio || '').toLowerCase().includes(q) ||
            (item.customer_name || '').toLowerCase().includes(q) ||
            (item.rfc || '').toLowerCase().includes(q)
        );
        renderFacturas(filtered, facturasCache.length);
    }

    function exportFacturasCSV() {
        if (typeof window.exportVisibleTableCSV === 'function') {
            window.exportVisibleTableCSV('facturas');
        } else {
            alert('Exportador no disponible');
        }
    }

    function exportNotasCSV() {
        if (typeof window.exportVisibleTableCSV === 'function') {
            window.exportVisibleTableCSV('notas_de_credito');
        } else {
            alert('Exportador no disponible');
        }
    }

    function newCreditNote() {
        alert('Nueva nota de crédito — próximamente');
    }

    function newPaymentComplement() {
        alert('Nuevo complemento de pago — próximamente');
    }

    // ---- Notas de Credito (Tab 2) — loads from CFDI queue with type=Egreso ----
    async function loadNotas() {
        const panel = document.getElementById('panel-notas');
        if (!panel) return;
        const tbody = panel.querySelector('.data-table tbody');
        if (!tbody) return;

        tbody.innerHTML = '<tr><td colspan="7" style="padding:var(--space-6);">' + renderLoadingState({ message: 'Cargando notas de credito...' }) + '</td></tr>';

        try {
            const res = await api('/queue?per_page=50&type=egreso');
            const items = res.data || [];
            if (!items.length) {
                tbody.innerHTML = '<tr><td colspan="7" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Sin notas de credito', subtitle: 'No hay notas de credito registradas.' }) + '</td></tr>';
                return;
            }
            tbody.innerHTML = items.map(item => `<tr>
                <td class="td--mono">${item.provisional_folio || '-'}</td>
                <td class="td--mono" style="color:var(--color-text-accent);">${item.related_folio || '-'}</td>
                <td class="td--primary">${item.customer_name || '-'}</td>
                <td>${item.cancel_motive || '-'}</td>
                <td class="td--amount">$${fmt(item.total)}</td>
                <td>${statusBadge(item.status)}</td>
                <td>
                    <div style="display:flex;gap:4px;">
                        <button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">Ver</button>
                        ${item.sale_id ? `<a href="${API}/${item.sale_id}/pdf" target="_blank" class="btn btn--ghost btn--sm">PDF</a>` : ''}
                    </div>
                </td>
            </tr>`).join('');
        } catch (e) {
            tbody.innerHTML = '<tr><td colspan="7" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Error', subtitle: e.message }) + '</td></tr>';
        }
    }

    // ---- Complementos de Pago (Tab 3) — loads from CFDI queue with type=Pago ----
    async function loadComplementos() {
        const panel = document.getElementById('panel-complementos');
        if (!panel) return;
        const tbody = panel.querySelector('.data-table tbody');
        if (!tbody) return;

        tbody.innerHTML = '<tr><td colspan="8" style="padding:var(--space-6);">' + renderLoadingState({ message: 'Cargando complementos...' }) + '</td></tr>';

        try {
            const res = await api('/queue?per_page=50&type=pago');
            complementosCache = res.data || [];
            renderComplementos(complementosCache);
        } catch (e) {
            tbody.innerHTML = '<tr><td colspan="8" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Error', subtitle: e.message }) + '</td></tr>';
        }
    }

    let complementosCache = [];

    function renderComplementos(items) {
        const panel = document.getElementById('panel-complementos');
        const tbody = panel.querySelector('.data-table tbody');
        const methodFilter = document.getElementById('complementos-method-filter');
        const method = methodFilter ? methodFilter.value : '';
        const filtered = method ? items.filter(item => (item.payment_method || '').startsWith(method)) : items;

        if (!filtered.length) {
            tbody.innerHTML = '<tr><td colspan="8" style="padding:var(--space-6);">' + renderEmptyState({ title: 'Sin complementos', subtitle: 'No hay complementos de pago registrados.' }) + '</td></tr>';
            return;
        }
        tbody.innerHTML = filtered.map(item => `<tr>
            <td class="td--mono">${item.provisional_folio || '-'}</td>
            <td class="td--mono" style="color:var(--color-text-accent);">${item.related_folio || '-'}</td>
            <td class="td--primary">${item.customer_name || '-'}</td>
            <td class="td--amount">$${fmt(item.total)}</td>
            <td style="font-size:var(--text-caption);">${item.payment_method || '-'}</td>
            <td>${item.created_at ? new Date(item.created_at).toLocaleDateString('es-MX') : '-'}</td>
            <td>${statusBadge(item.status)}</td>
            <td>
                <div style="display:flex;gap:4px;">
                    <button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">Ver</button>
                    ${item.status === 'stamped' ? `<button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">XML</button>` : ''}
                </div>
            </td>
        </tr>`).join('');
    }

    // ---- Cancelaciones (Tab 4) — loads cancelled/cancelling CFDIs ----
    async function loadCancelaciones() {
        const panel = document.getElementById('panel-cancelaciones');
        if (!panel) return;
        const grid = panel.querySelector('.cancel-grid');
        if (!grid) return;

        try {
            const res = await api('/queue?per_page=50&status=cancelled');
            const items = res.data || [];

            // Also try to get in-process cancellations
            let processingItems = [];
            try {
                const res2 = await api('/queue?per_page=50&status=cancelling');
                processingItems = res2.data || [];
            } catch (_) { /* ignore */ }

            const allItems = [...processingItems, ...items];
            if (!allItems.length) {
                grid.innerHTML = '<p style="padding:var(--space-6);color:var(--color-text-muted);text-align:center;">No hay solicitudes de cancelacion.</p>';
                return;
            }

            grid.innerHTML = allItems.map(item => {
                const cardClass = item.status === 'cancelled' ? 'cancel-card--aceptada' :
                                  item.status === 'cancelling' ? 'cancel-card--proceso' :
                                  item.cancel_accepted === false ? 'cancel-card--rechazada' :
                                  'cancel-card--proceso';
                const badgeText = item.status === 'cancelled' ? statusBadge('aceptada') :
                                  item.cancel_accepted === false ? statusBadge('rechazada') :
                                  statusBadge('proceso');

                return `<div class="cancel-card ${cardClass}">
                    <div class="cancel-card__header">
                        <span class="cancel-card__folio">${item.provisional_folio || `CFDI-${item.id}`}</span>
                        ${badgeText}
                    </div>
                    <div class="cancel-card__body">
                        <div class="cancel-card__row">
                            <span class="cancel-card__row-label">Cliente</span>
                            <span class="cancel-card__row-value">${item.customer_name || '-'}</span>
                        </div>
                        <div class="cancel-card__row">
                            <span class="cancel-card__row-label">RFC</span>
                            <span class="cancel-card__row-value" style="font-family:var(--font-mono);font-size:0.8rem;">${item.rfc || '-'}</span>
                        </div>
                        <div class="cancel-card__row">
                            <span class="cancel-card__row-label">Motivo</span>
                            <span class="cancel-card__row-value">${item.cancel_motive || '-'}</span>
                        </div>
                        <div class="cancel-card__row">
                            <span class="cancel-card__row-label">Monto</span>
                            <span class="cancel-card__row-value" style="font-family:var(--font-mono);font-weight:600;color:var(--color-text-primary);">$${fmt(item.total)} MXN</span>
                        </div>
                    </div>
                    <div class="cancel-card__footer">
                        <span style="font-size:var(--text-caption);color:var(--color-text-muted);">${item.cancelled_at ? 'Cancelada: ' + new Date(item.cancelled_at).toLocaleDateString('es-MX') : item.created_at ? 'Solicitada: ' + new Date(item.created_at).toLocaleDateString('es-MX') : ''}</span>
                        <button class="btn btn--ghost btn--sm" onclick="Invoicing.showDetail(${item.id})">Ver detalle</button>
                    </div>
                </div>`;
            }).join('');
        } catch (e) {
            grid.innerHTML = `<p style="color:var(--color-error);padding:var(--space-4);">Error: ${e.message}</p>`;
        }
    }

    // ---- Facturapi status (config tab) ----
    async function loadFacturapiStatus() {
        const container = document.getElementById('facturapi-status');
        if (!container) return;
        container.innerHTML = 'Cargando...';
        try {
            const status = await api('/facturapi/status');

            if (!status.has_key) {
                container.innerHTML = `<p style="color:var(--color-error);">Falta la llave API de Facturapi. Configura <code>cfdi_facturapi_key</code> o la variable <code>FACTURAPI_USER_KEY</code>.</p>`;
                return;
            }

            if (!status.has_org_id) {
                container.innerHTML = `
                    <p style="color:var(--color-warning);margin-bottom:var(--space-3);">No hay organización Facturapi vinculada.</p>
                    <button class="btn btn--primary" onclick="Invoicing.setupFacturapi(this)">Crear / Vincular Organización</button>
                `;
                return;
            }

            let csdHtml = status.has_csd
                ? '<span style="color:var(--color-success);">Activo</span>'
                : '<span style="color:var(--color-error);">Pendiente</span>';

            let pendingHtml = '';
            if (status.pending_steps && status.pending_steps.length) {
                pendingHtml = '<ul style="margin:var(--space-2) 0 0 0;padding-left:var(--space-5);color:var(--color-warning);">' +
                    status.pending_steps.map(s => `<li>${s.description || s.type}</li>`).join('') +
                    '</ul>';
            }

            container.innerHTML = `
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:var(--space-4);">
                    <div>
                        <div style="font-size:var(--text-caption);color:var(--color-text-muted);">Organización</div>
                        <div style="font-weight:var(--font-weight-semibold);">${escapeHtml(status.legal_name) || '-'}</div>
                        <div style="font-family:var(--font-mono);font-size:var(--text-body-sm);">${status.tax_id || ''}</div>
                        <div style="font-family:var(--font-mono);font-size:var(--text-caption);color:var(--color-text-muted);">${status.org_id || ''}</div>
                    </div>
                    <div>
                        <div style="font-size:var(--text-caption);color:var(--color-text-muted);">CSD</div>
                        <div style="font-weight:var(--font-weight-semibold);">${csdHtml}</div>
                        <div style="font-size:var(--text-caption);color:var(--color-text-muted);margin-top:var(--space-2);">Pasos pendientes</div>
                        ${pendingHtml || '<span style="color:var(--color-success);">Ninguno</span>'}
                    </div>
                </div>
                ${status.error ? `<p style="color:var(--color-error);margin-top:var(--space-3);">Error: ${escapeHtml(status.error)}</p>` : ''}
            `;
        } catch (e) {
            container.innerHTML = `<p style="color:var(--color-error);">Error: ${e.message}</p>`;
        }
    }

    async function setupFacturapi(btn) {
        if (!btn) return;
        btn.disabled = true;
        btn.textContent = 'Configurando...';
        try {
            const res = await api('/facturapi/setup', { method: 'POST' });
            alert('Organización vinculada: ' + res.org_id);
            loadFacturapiStatus();
        } catch (e) {
            alert('Error: ' + e.message);
            btn.disabled = false;
            btn.textContent = 'Crear / Vincular Organización';
        }
    }

    function resetCsdForm() {
        document.getElementById('csd-form').reset();
        document.getElementById('csd-cer-label').textContent = 'Subir certificado .cer';
        document.getElementById('csd-key-label').textContent = 'Subir llave privada .key';
    }

    function updateFileLabels() {
        const cer = document.getElementById('csd-cer');
        const key = document.getElementById('csd-key');
        if (cer && cer.files.length) {
            document.getElementById('csd-cer-label').textContent = cer.files[0].name;
        }
        if (key && key.files.length) {
            document.getElementById('csd-key-label').textContent = key.files[0].name;
        }
    }

    async function uploadCsd(btn) {
        if (!btn) return;
        const cer = document.getElementById('csd-cer');
        const key = document.getElementById('csd-key');
        const password = document.getElementById('contrasena-csd').value.trim();

        if (!cer || !cer.files.length || !key || !key.files.length) {
            alert('Selecciona el archivo .cer y .key');
            return;
        }
        if (!password) {
            alert('Escribe la contraseña del CSD');
            return;
        }

        const formData = new FormData();
        formData.append('certificate', cer.files[0]);
        formData.append('private_key', key.files[0]);
        formData.append('password', password);

        btn.disabled = true;
        const originalText = btn.innerHTML;
        btn.textContent = 'Subiendo...';
        try {
            const res = await fetch(`${API}/facturapi/csd`, {
                method: 'POST',
                headers: { 'Authorization': `Bearer ${token()}` },
                body: formData,
            });
            const data = await res.json().catch(() => ({ error: res.statusText }));
            if (!res.ok) throw new Error(data.error || 'Upload failed');
            alert('CSD actualizado correctamente');
            resetCsdForm();
            loadFacturapiStatus();
        } catch (e) {
            alert('Error al subir CSD: ' + e.message);
        } finally {
            btn.disabled = false;
            btn.innerHTML = originalText;
        }
    }

    // Wire file input change listeners
    setTimeout(() => {
        const cer = document.getElementById('csd-cer');
        const key = document.getElementById('csd-key');
        if (cer) cer.addEventListener('change', updateFileLabels);
        if (key) key.addEventListener('change', updateFileLabels);
    }, 0);

    // ---- Detail modal (uses modalDetalleOverlay) ----
    async function showDetail(cfdiId) {
        const overlay = document.getElementById('modalDetalleOverlay');
        if (!overlay) return;

        try {
            const item = await api(`/queue/${cfdiId}`);
            const modalCard = overlay.querySelector('.modal-card');
            if (!modalCard) return;

            // Update header
            const headerTitle = modalCard.querySelector('div > div:first-child > div:first-child');
            const headerSub = modalCard.querySelector('div > div:first-child > div:nth-child(2)');
            if (headerTitle) headerTitle.textContent = 'Detalle de Factura';
            if (headerSub) headerSub.textContent = `${item.provisional_folio || 'CFDI-' + item.id} \u2014 ${item.status === 'stamped' ? 'Timbrada' : item.status === 'cancelled' ? 'Cancelada' : item.status === 'pending' ? 'Pendiente' : item.status || ''}`;

            // Update detail grid
            const detailGrid = modalCard.querySelector('div:nth-child(2)');
            if (detailGrid) {
                detailGrid.innerHTML = `
                    <div style="display:grid; grid-template-columns:1fr 1fr; gap:var(--space-4); margin-bottom:var(--space-6);">
                        <div>
                            <div style="font-size:var(--text-caption); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:var(--tracking-widest); margin-bottom:var(--space-1);">Emisor</div>
                            <div style="font-weight:var(--font-weight-semibold);">${item.emisor_name || 'Nexus Autoparts SA de CV'}</div>
                            <div style="font-family:var(--font-mono); font-size:var(--text-body-sm); color:var(--color-text-secondary);">${item.emisor_rfc || ''}</div>
                        </div>
                        <div>
                            <div style="font-size:var(--text-caption); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:var(--tracking-widest); margin-bottom:var(--space-1);">Receptor</div>
                            <div style="font-weight:var(--font-weight-semibold);">${item.customer_name || '-'}</div>
                            <div style="font-family:var(--font-mono); font-size:var(--text-body-sm); color:var(--color-text-secondary);">${item.rfc || ''}</div>
                        </div>
                        <div>
                            <div style="font-size:var(--text-caption); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:var(--tracking-widest); margin-bottom:var(--space-1);">UUID</div>
                            <div style="font-family:var(--font-mono); font-size:var(--text-caption); color:var(--color-text-accent); word-break:break-all;">${item.uuid_fiscal || 'Sin timbrar'}</div>
                        </div>
                        <div>
                            <div style="font-size:var(--text-caption); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:var(--tracking-widest); margin-bottom:var(--space-1);">Total</div>
                            <div style="font-family:var(--font-mono); font-size:var(--text-h4); font-weight:var(--font-weight-bold); color:var(--color-text-primary);">$${fmt(item.total)}</div>
                        </div>
                    </div>
                    ${item.error_message ? `<p style="color:var(--color-error);margin-bottom:var(--space-3);"><strong>Error:</strong> ${escapeHtml(item.error_message)}</p>` : ''}
                    ${(item.xml_signed || item.payload_unsigned) ? `
                        <div style="font-size:var(--text-caption); color:var(--color-text-muted); text-transform:uppercase; letter-spacing:var(--tracking-widest); margin-bottom:var(--space-2);">${item.xml_signed ? 'Vista previa XML' : 'Payload Facturapi'}</div>
                        <pre style="background:var(--color-surface-3); border:1px solid var(--color-border); border-radius:var(--radius-md); padding:var(--space-4); font-family:var(--font-mono); font-size:11px; color:var(--color-text-secondary); overflow-x:auto; max-height:200px; line-height:1.6;">${escapeHtml(item.xml_signed || item.payload_unsigned)}</pre>
                    ` : ''}
                    ${item.status === 'stamped' && item.external_id ? `
                        <div style="display:flex;gap:var(--space-3);margin-top:var(--space-4);">
                            <a class="btn btn--ghost btn--sm" href="${API}/facturapi/download/${item.id}/xml" target="_blank">Descargar XML</a>
                            <a class="btn btn--ghost btn--sm" href="${API}/facturapi/download/${item.id}/pdf" target="_blank">Descargar PDF</a>
                        </div>
                    ` : ''}
                `;
            }

            // Wire the cancel button inside modal footer
            const cancelBtn = modalCard.querySelector('div:last-child button:last-child');
            if (cancelBtn && item.status === 'stamped') {
                cancelBtn.style.display = '';
                cancelBtn.onclick = () => {
                    overlay.style.display = 'none';
                    showCancelModal(cfdiId);
                };
            } else if (cancelBtn) {
                cancelBtn.style.display = 'none';
            }

            // Store current CFDI id for use by footer buttons
            overlay.dataset.cfdiId = cfdiId;
            overlay.dataset.saleId = item.sale_id || '';

            overlay.style.display = 'flex';
        } catch (e) {
            alert('Error al cargar detalle: ' + e.message);
        }
    }

    function escapeHtml(text) {
        const div = document.createElement('div');
        div.textContent = text;
        return div.innerHTML;
    }

    // ---- Cancel modal (uses modalCancelOverlay) ----
    let cancelTargetId = null;

    function showCancelModal(cfdiId) {
        cancelTargetId = cfdiId;
        const overlay = document.getElementById('modalCancelOverlay');
        if (overlay) overlay.style.display = 'flex';
    }

    async function confirmCancel() {
        if (!cancelTargetId) return;
        const overlay = document.getElementById('modalCancelOverlay');
        if (!overlay) return;

        const selectedRadio = overlay.querySelector('input[name="motivo-sat"]:checked');
        if (!selectedRadio) { alert('Selecciona un motivo de cancelacion.'); return; }
        const motive = selectedRadio.value;

        const uuidInput = overlay.querySelector('input[type="text"]');
        const replacementUuid = uuidInput ? uuidInput.value.trim() : '';

        if (motive === '01' && !replacementUuid) {
            alert('UUID sustituto requerido para motivo 01.');
            return;
        }

        if (!confirm('Confirmar cancelacion ante el SAT?')) return;

        try {
            const body = { motive };
            if (replacementUuid) body.replacement_uuid = replacementUuid;

            await api(`/cancel/${cancelTargetId}`, { method: 'POST', body: JSON.stringify(body) });
            overlay.style.display = 'none';
            cancelTargetId = null;
            loadFacturas();
            alert('CFDI cancelado exitosamente.');
        } catch (e) {
            alert('Error: ' + e.message);
        }
    }

    // ---- Process entire queue ----
    async function processQueue() {
        if (!confirm('Procesar todos los CFDIs pendientes?')) return;
        try {
            const result = await api('/queue/process', { method: 'POST' });
            alert(`Procesados: ${result.processed}, Timbrados: ${result.stamped}, Fallidos: ${result.failed}`);
            loadFacturas();
        } catch (e) {
            alert('Error: ' + e.message);
        }
    }

    // ---- Clock ----
    function startClock() {
        const el = document.getElementById('live-clock');
        if (!el) return;
        const tick = () => {
            const now = new Date();
            el.textContent = now.toLocaleTimeString('es-MX', { hour: '2-digit', minute: '2-digit', second: '2-digit' });
        };
        tick();
        setInterval(tick, 1000);
    }

    // ---- Wire cancel modal "Solicitar Cancelacion SAT" button ----
    function wireCancelModal() {
        const overlay = document.getElementById('modalCancelOverlay');
        if (!overlay) return;
        const footerBtns = overlay.querySelectorAll('div:last-child button');
        if (footerBtns.length >= 2) {
            // Last button = confirm cancel
            footerBtns[footerBtns.length - 1].onclick = () => confirmCancel();
            // Second to last = close
            footerBtns[footerBtns.length - 2].onclick = () => {
                overlay.style.display = 'none';
                cancelTargetId = null;
            };
        }
    }

    // ---- Wire detail modal close button ----
    function wireDetailModal() {
        const overlay = document.getElementById('modalDetalleOverlay');
        if (!overlay) return;
        const closeBtn = overlay.querySelector('button[onclick*="modalDetalleOverlay"]');
        if (closeBtn) {
            closeBtn.onclick = () => { overlay.style.display = 'none'; };
        }
    }

    // ---- Init ----
    function init() {
        if (!checkAuth()) return;
        startClock();
        wireDetailModal();
        wireCancelModal();
        // Load initial tab data (facturas is active by default)
        loadFacturas();
    }

    document.addEventListener('DOMContentLoaded', init);

    // ---- Nueva Factura modal ----
    function showNewInvoiceModal() {
        const overlay = document.getElementById('newInvoiceModalOverlay');
        if (!overlay) return;
        const input = overlay.querySelector('#invoiceSaleId');
        if (input) input.value = '';
        document.getElementById('invoiceResult').innerHTML = '';
        overlay.style.display = 'flex';
    }

    function closeNewInvoiceModal() {
        const overlay = document.getElementById('newInvoiceModalOverlay');
        if (overlay) overlay.style.display = 'none';
    }

    async function submitNewInvoice() {
        const saleId = parseInt(document.getElementById('invoiceSaleId').value);
        const resultEl = document.getElementById('invoiceResult');
        if (!saleId) {
            resultEl.innerHTML = '<span style="color:var(--color-error);">Ingrese un ID de venta valido.</span>';
            return;
        }
        try {
            const result = await api('/invoice', {
                method: 'POST',
                body: JSON.stringify({ sale_id: saleId }),
            });
            resultEl.innerHTML = '<span style="color:var(--color-success);">Factura generada: ' + (result.provisional_folio || 'CFDI-' + (result.id || '')) + '</span>';
            loadFacturas();
            setTimeout(() => closeNewInvoiceModal(), 1500);
        } catch (e) {
            resultEl.innerHTML = '<span style="color:var(--color-error);">Error: ' + e.message + '</span>';
        }
    }

    // ---- Nota de Credito placeholder ----
    function notaCreditoPlaceholder() {
        alert('Nota de credito: proximamente');
    }

    // ---- Global Invoice ----
    function openGlobalInvoiceModal() {
        const now = new Date();
        document.getElementById('global-year').value = now.getFullYear();
        document.getElementById('global-month').value = now.getMonth() + 1;
        document.getElementById('global-preview').innerHTML = 'Presiona "Vista previa" para ver ventas elegibles.';
        document.getElementById('modalGlobalInvoice').style.display = 'flex';
    }

    async function previewGlobalInvoice() {
        const year = document.getElementById('global-year').value;
        const month = document.getElementById('global-month').value;
        const preview = document.getElementById('global-preview');
        preview.innerHTML = 'Cargando...';
        try {
            const res = await api(`/global-invoice/eligible-sales?year=${year}&month=${month}`);
            preview.innerHTML = `<strong>${res.count} ventas elegibles</strong> — Total: $${fmt(res.total)}<br><small>${res.sales.map(s => '#' + s.id).join(', ')}</small>`;
        } catch (e) {
            preview.innerHTML = '<span style="color:var(--color-error);">Error: ' + e.message + '</span>';
        }
    }

    async function generateGlobalInvoice() {
        const year = parseInt(document.getElementById('global-year').value, 10);
        const month = parseInt(document.getElementById('global-month').value, 10);
        const btn = document.querySelector('#modalGlobalInvoice .btn--primary');
        const originalText = btn.textContent;
        btn.disabled = true;
        btn.textContent = 'Generando...';
        try {
            const res = await api('/global-invoice', {
                method: 'POST',
                body: JSON.stringify({ year, month })
            });
            alert(`Factura global generada: ${res.provisional_folio} (${res.sales_count} ventas, $${fmt(res.total)})`);
            document.getElementById('modalGlobalInvoice').style.display = 'none';
            loadFacturas();
        } catch (e) {
            alert('Error: ' + e.message);
        } finally {
            btn.disabled = false;
            btn.textContent = originalText;
        }
    }

    // Expose switchTab globally for onclick handlers in HTML
    window.switchTab = switchTab;
    window.showNewInvoiceModal = showNewInvoiceModal;
    window.closeNewInvoiceModal = closeNewInvoiceModal;
    window.submitNewInvoice = submitNewInvoice;
    window.notaCreditoPlaceholder = notaCreditoPlaceholder;

    // Register Cmd+K items
    if (typeof registerCmdKItem === "function") {
        registerCmdKItem({ group: "Principal", label: "POS Ventas", href: "/pos/sale", icon: "🛒" });
        registerCmdKItem({ group: "Principal", label: "Catálogo", href: "/pos/catalog", icon: "📁" });
        registerCmdKItem({ group: "Principal", label: "Clientes", href: "/pos/customers", icon: "👤" });
        registerCmdKItem({ group: "Principal", label: "Dashboard", href: "/pos/dashboard", icon: "📊" });
    }

    return {
        switchTab, loadFacturas, loadNotas, loadComplementos, loadCancelaciones, loadFacturapiStatus,
        showDetail, showCancelModal, confirmCancel, processQueue,
        showNewInvoiceModal, closeNewInvoiceModal, submitNewInvoice, notaCreditoPlaceholder,
        openGlobalInvoiceModal, previewGlobalInvoice, generateGlobalInvoice, setupFacturapi,
        uploadCsd, resetCsdForm,
        filterFacturas, exportFacturasCSV, exportNotasCSV,
        newCreditNote, newPaymentComplement,
    };

})();
