// /home/Autopartes/pos/static/js/customers.js
/**
 * Customers management frontend.
 * Communicates with /pos/api/customers (customers_bp).
 * Wired to the design-system HTML (customers.html).
 */
const Customers = (() => {
    let token = localStorage.getItem('pos_token') || '';
    let currentPage = 1;
    let totalPages = 1;
    let currentCustomer = null;
    let searchTimeout = null;

    const fmt = (n) => '$' + parseFloat(n || 0).toLocaleString('es-MX', {
        minimumFractionDigits: 2, maximumFractionDigits: 2
    });

    const fmtShort = (n) => {
        n = parseFloat(n || 0);
        if (n >= 1000000) return '$' + (n / 1000000).toFixed(1) + 'M';
        if (n >= 1000) return '$' + (n / 1000).toFixed(0) + 'K';
        return '$' + n.toFixed(0);
    };

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

    async function api(url, options = {}) {
        options.headers = headers();
        const res = await fetch(url, options);
        if (res.status === 401) {
            window.location.href = '/pos/login';
            return;
        }
        const data = await res.json();
        if (!res.ok) throw new Error(data.error || `HTTP ${res.status}`);
        return data;
    }

    // ─── Tier / Status helpers ───────────
    const tierMap = { 1: 'Mostrador', 2: 'Taller', 3: 'Mayoreo' };
    const tierClass = { 1: 'mostrador', 2: 'taller', 3: 'mayoreo' };

    function statusBadge(c) {
        if (c.is_active === false) {
            return '<span class="badge badge--inactive"><span class="badge-dot"></span>Inactivo</span>';
        }
        // Derive status: if credit_balance > credit_limit => Mora, else Activo
        if (c.credit_balance > 0 && c.credit_limit > 0 && c.credit_balance > c.credit_limit) {
            return '<span class="badge badge--warning"><span class="badge-dot"></span>Mora</span>';
        }
        return '<span class="badge badge--active"><span class="badge-dot"></span>Activo</span>';
    }

    function getInitials(name) {
        if (!name) return '--';
        const parts = name.trim().split(/\s+/);
        if (parts.length >= 2) return (parts[0][0] + parts[1][0]).toUpperCase();
        return name.substring(0, 2).toUpperCase();
    }

    function formatDate(d) {
        if (!d) return '-';
        try {
            return new Date(d).toLocaleDateString('es-MX', { day: '2-digit', month: 'short', year: 'numeric' });
        } catch (_) { return d; }
    }

    // ─── Summary Cards ──────────────────
    async function loadSummary() {
        try {
            // Load a small page just to get pagination totals
            const data = await api('/pos/api/customers?page=1&per_page=1');
            const totalClientes = data.pagination ? data.pagination.total : 0;

            const cards = document.querySelectorAll('.summary-card__value');
            if (cards.length >= 1) cards[0].textContent = totalClientes.toLocaleString('es-MX');
        } catch (_) { /* non-critical */ }
    }

    // ─── List ────────────────────────────
    async function loadCustomers(page, q) {
        page = page || currentPage;
        const searchEl = document.getElementById('searchInput');
        q = q !== undefined ? q : (searchEl ? searchEl.value || '' : '');

        const tipoEl = document.getElementById('tipoFilter');
        const estadoEl = document.getElementById('estadoFilter');
        const tipo = tipoEl ? tipoEl.value : '';
        // Map UI status labels to backend values
        const estadoMap = { 'Activo': 'active', 'Inactivo': 'inactive', 'Mora': 'overdue' };
        const estado = estadoEl ? (estadoMap[estadoEl.value] || 'all') : 'active';

        const tbody = document.getElementById('customersBody');
        if (tbody) tbody.innerHTML = '<tr><td colspan="11">' + renderLoadingState({ message: 'Cargando clientes...' }) + '</td></tr>';

        try {
            const params = new URLSearchParams({ page, per_page: 50 });
            if (q) params.append('q', q);
            if (tipo) params.append('price_tier', tipo);
            if (estado) params.append('status', estado);

            const data = await api(`/pos/api/customers?${params}`);
            renderTable(data.data || []);
            renderPagination(data.pagination || {});
        } catch (e) {
            if (tbody) tbody.innerHTML = '<tr><td colspan="11">' + renderEmptyState({ title: 'Error', subtitle: 'No se pudieron cargar los clientes.' }) + '</td></tr>';
            console.error('Load customers failed:', e);
        }
    }

    var selectedCustomers = new Set();

    function renderCustomerRow(c) {
        const tier = tierMap[c.price_tier] || 'Mostrador';
        const tClass = tierClass[c.price_tier] || 'mostrador';
        const limit = parseFloat(c.credit_limit || 0);
        const balance = parseFloat(c.credit_balance || 0);
        const available = Math.max(0, limit - balance);
        const usedPct = limit > 0 ? Math.round((balance / limit) * 100) : 0;
        const creditClass = usedPct >= 80 ? 'none' : usedPct >= 60 ? 'low' : '';
        const num = String(c.id).padStart(5, '0');
        const selClass = (currentCustomer && currentCustomer.id === c.id) ? 'selected' : '';
        const isChecked = selectedCustomers.has(c.id) ? 'checked' : '';
        return '<tr class="' + selClass + '" onclick="Customers.selectCustomer(' + c.id + ')">' +
            '<td onclick="event.stopPropagation();"><input type="checkbox" ' + isChecked + ' onchange="Customers.toggleCustomerSelection(' + c.id + ')"></td>' +
            '<td class="cell-num">' + num + '</td>' +
            '<td>' +
                '<div class="cell-name">' + (c.name || '') + '</div>' +
                '<div class="cell-name-sub hide-mobile">' + (c.razon_social || c.email || '') + '</div>' +
            '</td>' +
            '<td class="cell-rfc hide-mobile">' + (c.rfc || '-') + '</td>' +
            '<td class="hide-mobile">' + (c.phone || '-') + '</td>' +
            '<td class="hide-mobile" style="font-size:var(--text-caption);color:var(--color-text-secondary);">' + (c.email || '-') + '</td>' +
            '<td><span class="tipo-chip tipo-chip--' + tClass + '">' + tier + '</span></td>' +
            '<td class="cell-credit ' + creditClass + '">' + fmt(available) + '</td>' +
            '<td class="cell-date hide-mobile">' + formatDate(c.last_purchase || c.created_at) + '</td>' +
            '<td>' + statusBadge(c) + '</td>' +
            '<td onclick="event.stopPropagation();"><button class="btn btn-sm btn-ghost" title="Editar cliente" onclick="Customers.editCustomer(' + c.id + ')"><svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7"/><path d="M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z"/></svg></button></td>' +
            '</tr>';
    }

    var customersVS = null;

    function renderTable(customers) {
        const tbody = document.getElementById('customersBody');
        if (!tbody) return;

        if (!customers || customers.length === 0) {
            tbody.innerHTML = '<tr><td colspan="11">' + renderEmptyState({
                icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M23 21v-2a4 4 0 0 0-3-3.87M16 3.13a4 4 0 0 1 0 7.75"/></svg>',
                title: 'Sin clientes',
                subtitle: 'No se encontraron clientes registrados.',
                action: '<button class="btn btn--primary btn--sm" onclick="Customers.showCreateModal()">Nuevo cliente</button>'
            }) + '</td></tr>';
            return;
        }

        if (!customersVS) {
            customersVS = new VirtualScroll({
                container: tbody,
                rowHeight: 52,
                buffer: 3,
                renderRow: renderCustomerRow,
                emptyHtml: '<tr><td colspan="11">' + renderEmptyState({ title: 'Sin clientes', subtitle: 'No hay clientes registrados.' }) + '</td></tr>'
            });
        }
        customersVS.setData(customers);
    }

    function renderPagination(pag) {
        const container = document.querySelector('.pagination');
        const info = document.getElementById('tableInfo');

        if (!pag || !pag.total_pages) {
            if (container) container.innerHTML = '';
            if (info) info.textContent = '';
            return;
        }

        totalPages = pag.total_pages;
        currentPage = pag.page;
        const total = pag.total || 0;
        const perPage = pag.per_page || 50;
        const start = (pag.page - 1) * perPage + 1;
        const end = Math.min(pag.page * perPage, total);

        if (info) info.textContent = `Mostrando ${start}–${end} de ${total.toLocaleString('es-MX')} clientes`;

        if (!container) return;
        if (totalPages <= 1) { container.innerHTML = ''; return; }

        let html = '';
        html += `<button class="page-btn" ${pag.page <= 1 ? 'disabled' : ''} onclick="Customers.goToPage(${pag.page - 1})">&#8249;</button>`;

        const maxButtons = 7;
        let startP = Math.max(1, pag.page - 3);
        let endP = Math.min(totalPages, startP + maxButtons - 1);
        if (endP - startP < maxButtons - 1) startP = Math.max(1, endP - maxButtons + 1);

        for (let i = startP; i <= endP; i++) {
            html += `<button class="page-btn ${i === pag.page ? 'active' : ''}" onclick="Customers.goToPage(${i})">${i}</button>`;
        }

        if (endP < totalPages) {
            html += '<span style="color:var(--color-text-muted);font-size:var(--text-caption);padding:0 4px;">...</span>';
            html += `<button class="page-btn" onclick="Customers.goToPage(${totalPages})">${totalPages}</button>`;
        }

        html += `<button class="page-btn" ${pag.page >= totalPages ? 'disabled' : ''} onclick="Customers.goToPage(${pag.page + 1})">&#8250;</button>`;
        container.innerHTML = html;
    }

    function goToPage(page) {
        if (page < 1 || page > totalPages) return;
        currentPage = page;
        loadCustomers(page);
    }

    function search() {
        clearTimeout(searchTimeout);
        searchTimeout = setTimeout(() => {
            currentPage = 1;
            loadCustomers(1);
        }, 300);
    }

    // Alias for inline HTML oninput="filterCustomers()"
    window.filterCustomers = function() { search(); };

    // ─── Detail Panel (right side) ──────
    async function selectCustomer(id) {
        try {
            const c = await api(`/pos/api/customers/${id}`);
            currentCustomer = c;

            // Toggle empty/content
            const emptyEl = document.getElementById('detailEmpty');
            const contentEl = document.getElementById('detailContent');
            if (emptyEl) emptyEl.style.display = 'none';
            if (contentEl) contentEl.style.display = 'flex';

            // Avatar & Header
            const avatarEl = document.getElementById('detailAvatar');
            if (avatarEl) avatarEl.textContent = getInitials(c.name);

            const nameEl = document.getElementById('detailName');
            if (nameEl) nameEl.textContent = (c.name || '').toUpperCase();

            const rfcEl = document.getElementById('detailRFC');
            if (rfcEl) rfcEl.textContent = c.rfc || '-';

            // Tipo chip
            const tipoEl = document.getElementById('detailTipo');
            if (tipoEl) {
                const tier = tierMap[c.price_tier] || 'Mostrador';
                const tClass = tierClass[c.price_tier] || 'mostrador';
                tipoEl.textContent = tier;
                tipoEl.className = `tipo-chip tipo-chip--${tClass}`;
            }

            // Status badge
            const statEl = document.getElementById('detailStatus');
            if (statEl) statEl.innerHTML = statusBadge(c);

            // Contact
            const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val || '-'; };
            set('detailRazonSocial', c.razon_social);
            set('detailAddress', c.address);
            set('detailCp', c.cp);
            set('detailPhone', c.phone);
            set('detailEmail', c.email);
            set('detailSince', formatDate(c.created_at));
            set('detailLastPurchase', formatDate(c.last_purchase));

            // Credit
            const limit = parseFloat(c.credit_limit || 0);
            const balance = parseFloat(c.credit_balance || 0);
            const available = Math.max(0, limit - balance);
            const pct = limit > 0 ? Math.round((balance / limit) * 100) : 0;

            set('detailCreditLimit', fmt(limit));
            set('detailCreditAvail', fmt(available));
            set('detailCreditUsed', fmt(balance));
            set('detailCreditPct', pct + '%');

            const bar = document.getElementById('detailCreditBar');
            if (bar) {
                bar.style.width = pct + '%';
                bar.className = `progress-bar__fill ${pct < 40 ? 'low' : pct > 75 ? 'high' : ''}`;
            }

            // Discount
            const discountEl = document.getElementById('detailMaxDiscount');
            if (discountEl) discountEl.textContent = (c.max_discount_pct || 0) + '%';

            // Re-wire action buttons after detail panel is visible
            wireActionButtons();

            // Purchase History
            const hbody = document.getElementById('historyBody');
            if (hbody) {
                const purchases = c.recent_purchases || [];
                if (purchases.length === 0) {
                    hbody.innerHTML = '<tr><td colspan="4" style="text-align:center;color:var(--color-text-muted);padding:var(--space-4);">Sin compras recientes</td></tr>';
                } else {
                    hbody.innerHTML = '';
                    purchases.forEach(p => {
                        const statusClass = p.status === 'paid' ? 'mbadge--paid' : p.status === 'overdue' ? 'mbadge--overdue' : 'mbadge--pending';
                        const statusLabel = p.status === 'paid' ? 'Pagado' : p.status === 'overdue' ? 'Vencido' : 'Pendiente';
                        const tr = document.createElement('tr');
                        tr.innerHTML = `
                            <td class="date">${formatDate(p.created_at)}</td>
                            <td class="folio">NX-${String(p.id).padStart(5, '0')}</td>
                            <td class="total">${fmt(p.total)}</td>
                            <td><span class="mbadge ${statusClass}">${statusLabel}</span></td>
                        `;
                        hbody.appendChild(tr);
                    });
                }
            }

            // Also populate slide panel fields
            populateSlidePanel(c);

            // Re-render table to highlight selected row
            loadCustomers(currentPage);
        } catch (e) {
            console.error('Error loading customer:', e);
        }
    }

    // Populate the slide-panel (mobile/alt detail view)
    function populateSlidePanel(c) {
        const set = (id, val) => { const el = document.getElementById(id); if (el) el.textContent = val || '--'; };

        set('panelAvatar', getInitials(c.name));
        set('panelName', c.name);
        set('panelRfc', 'RFC: ' + (c.rfc || '-'));

        const limit = parseFloat(c.credit_limit || 0);
        const balance = parseFloat(c.credit_balance || 0);
        const available = Math.max(0, limit - balance);
        const pct = limit > 0 ? Math.round((balance / limit) * 100) : 0;

        set('panelCreditLimit', fmt(limit));
        set('panelCreditUsed', fmt(balance));
        set('panelCreditAvail', fmt(available));

        const panelBar = document.getElementById('panelCreditBar');
        if (panelBar) panelBar.style.width = pct + '%';

        // Vehicles
        const vehiclesEl = document.getElementById('panelVehicles');
        if (vehiclesEl) {
            const vehicles = c.vehicle_info || [];
            if (vehicles.length === 0) {
                vehiclesEl.innerHTML = '<span style="color:var(--color-text-muted);font-size:var(--text-body-sm);">Sin vehiculos registrados</span>';
            } else {
                vehiclesEl.innerHTML = vehicles.map(v =>
                    `<div style="padding:4px 0;border-bottom:1px solid var(--color-border);">
                        <strong>${v.make || ''} ${v.model || ''} ${v.year || ''}</strong>
                        ${v.plates ? ` <span style="color:var(--color-text-muted);">Placas: ${v.plates}</span>` : ''}
                    </div>`
                ).join('');
            }
        }

        // Purchases
        const purchasesEl = document.getElementById('panelPurchases');
        if (purchasesEl) {
            const purchases = c.recent_purchases || [];
            if (purchases.length === 0) {
                purchasesEl.innerHTML = '<span style="color:var(--color-text-muted);font-size:var(--text-body-sm);">Sin compras recientes</span>';
            } else {
                purchasesEl.innerHTML = purchases.slice(0, 5).map(p =>
                    `<div style="display:flex;justify-content:space-between;padding:4px 0;border-bottom:1px solid var(--color-border);font-size:var(--text-body-sm);">
                        <span>NX-${String(p.id).padStart(5, '0')} — ${formatDate(p.created_at)}</span>
                        <span>${fmt(p.total)}</span>
                    </div>`
                ).join('');
            }
        }
    }

    function closeDetail() {
        currentCustomer = null;
        const emptyEl = document.getElementById('detailEmpty');
        const contentEl = document.getElementById('detailContent');
        if (emptyEl) emptyEl.style.display = 'flex';
        if (contentEl) contentEl.style.display = 'none';
        loadCustomers(currentPage);
    }

    // Wire action buttons in detail panel
    function wireActionButtons() {
        const btns = document.querySelectorAll('.quick-actions .action-btn');
        // Order: Nueva Venta, Editar, Estado de Cuenta, Historial
        if (btns.length >= 1) btns[0].onclick = () => {
            if (currentCustomer) window.location.href = '/pos/sale?customer=' + currentCustomer.id;
        };
        if (btns.length >= 2) btns[1].onclick = () => editCurrent();
        if (btns.length >= 3) btns[2].onclick = () => showStatement();
        if (btns.length >= 4) btns[3].onclick = () => {
            if (currentCustomer) showCustomerHistory(currentCustomer.id);
        };
    }

    async function showCustomerHistory(customerId) {
        try {
            const res = await api(`/pos/api/customers/${customerId}/purchases`);
            const purchases = res.data || [];
            let modal = document.getElementById('customerHistoryModal');
            if (!modal) {
                modal = document.createElement('div');
                modal.id = 'customerHistoryModal';
                modal.className = 'modal-overlay';
                modal.style.display = 'none';
                modal.innerHTML = `
                    <div class="modal-content" style="max-width:700px;">
                        <div class="modal-header">
                            <h3>Historial de Compras — <span id="customerHistoryName"></span></h3>
                            <button class="modal-close" onclick="Customers.closeCustomerHistoryModal()">&times;</button>
                        </div>
                        <div class="modal-body">
                            <table class="history-table" style="width:100%;">
                                <thead>
                                    <tr>
                                        <th>Fecha</th>
                                        <th>Folio</th>
                                        <th>Total</th>
                                        <th>Pago</th>
                                        <th>Estado</th>
                                    </tr>
                                </thead>
                                <tbody id="customerHistoryBody"></tbody>
                            </table>
                        </div>
                    </div>
                `;
                document.body.appendChild(modal);
            }

            const tbody = document.getElementById('customerHistoryBody');
            const title = document.getElementById('customerHistoryName');
            if (title && currentCustomer) title.textContent = currentCustomer.name;

            if (purchases.length === 0) {
                tbody.innerHTML = '<tr><td colspan="5" style="text-align:center;color:var(--color-text-muted);padding:var(--space-4);">Sin compras registradas</td></tr>';
            } else {
                tbody.innerHTML = purchases.map(p => {
                    const statusClass = p.status === 'paid' ? 'mbadge--paid' : p.status === 'cancelled' ? 'mbadge--error' : p.status === 'overdue' ? 'mbadge--overdue' : 'mbadge--pending';
                    const statusLabel = p.status === 'paid' ? 'Pagado' : p.status === 'cancelled' ? 'Cancelado' : p.status === 'overdue' ? 'Vencido' : 'Pendiente';
                    return `<tr>
                        <td class="date">${formatDate(p.created_at)}</td>
                        <td class="folio">NX-${String(p.id).padStart(5, '0')}</td>
                        <td class="total">${fmt(p.total)}</td>
                        <td>${p.payment_method || '-'}</td>
                        <td><span class="mbadge ${statusClass}">${statusLabel}</span></td>
                    </tr>`;
                }).join('');
            }
            modal.style.display = 'flex';
            modal.classList.add('active');
        } catch (e) {
            console.error('Error loading customer history:', e);
            alert('Error al cargar historial: ' + e.message);
        }
    }

    function closeCustomerHistoryModal() {
        const modal = document.getElementById('customerHistoryModal');
        if (modal) {
            modal.style.display = 'none';
            modal.classList.remove('active');
        }
    }

    // ─── Create/Edit Modal ───────────────
    function showCreateModal() {
        const modal = document.getElementById('customerModal');
        if (!modal) return;
        document.getElementById('modalTitle').textContent = 'Nuevo Cliente';
        document.getElementById('editId').value = '';
        const safeSet = (id, v) => { const el = document.getElementById(id); if (el) el.value = v; };
        safeSet('fName', '');
        safeSet('fRfc', '');
        safeSet('fRazonSocial', '');
        safeSet('fRegimenFiscal', '');
        safeSet('fUsoCfdi', 'G03');
        safeSet('fCp', '');
        safeSet('fPhone', '');
        safeSet('fEmail', '');
        safeSet('fAddress', '');
        safeSet('fPriceTier', '1');
        safeSet('fCreditLimit', '0');
        safeSet('fMaxDiscountPct', '0');
        modal.classList.add('active');
        document.getElementById('fName').focus();
    }

    function editCurrent() {
        if (!currentCustomer) return;
        openEditModal(currentCustomer);
    }

    async function editCustomer(id) {
        try {
            const c = await api(`/pos/api/customers/${id}`);
            currentCustomer = c;
            openEditModal(c);
        } catch (e) {
            alert('Error: ' + e.message);
        }
    }

    function openEditModal(c) {
        const modal = document.getElementById('customerModal');
        if (!modal || !c) return;
        document.getElementById('modalTitle').textContent = 'Editar Cliente';
        document.getElementById('editId').value = c.id;
        const safeSet = (id, v) => { const el = document.getElementById(id); if (el) el.value = v; };
        safeSet('fName', c.name || '');
        safeSet('fRfc', c.rfc || '');
        safeSet('fRazonSocial', c.razon_social || '');
        safeSet('fRegimenFiscal', c.regimen_fiscal || '');
        safeSet('fUsoCfdi', c.uso_cfdi || 'G03');
        safeSet('fCp', c.cp || '');
        safeSet('fPhone', c.phone || '');
        safeSet('fEmail', c.email || '');
        safeSet('fAddress', c.address || '');
        safeSet('fPriceTier', c.price_tier || '1');
        safeSet('fCreditLimit', c.credit_limit || 0);
        safeSet('fMaxDiscountPct', c.max_discount_pct || 0);
        modal.classList.add('active');
    }

    function closeModal() {
        const modal = document.getElementById('customerModal');
        if (modal) modal.classList.remove('active');
    }

    async function save() {
        const nameEl = document.getElementById('fName');
        const name = nameEl ? nameEl.value.trim() : '';
        if (!name) { alert('Nombre es requerido'); return; }

        const val = (id) => { const el = document.getElementById(id); return el ? el.value.trim() : ''; };

        const body = {
            name: name,
            rfc: val('fRfc') || null,
            razon_social: val('fRazonSocial') || null,
            regimen_fiscal: val('fRegimenFiscal') || null,
            uso_cfdi: val('fUsoCfdi') || 'G03',
            cp: val('fCp') || null,
            phone: val('fPhone') || null,
            email: val('fEmail') || null,
            address: val('fAddress') || null,
            price_tier: parseInt(val('fPriceTier')) || 1,
            credit_limit: parseFloat(val('fCreditLimit')) || 0,
            max_discount_pct: parseFloat(val('fMaxDiscountPct')) || 0,
        };

        const editId = val('editId');

        try {
            if (editId) {
                await api(`/pos/api/customers/${editId}`, {
                    method: 'PUT',
                    body: JSON.stringify(body),
                });
            } else {
                await api('/pos/api/customers', {
                    method: 'POST',
                    body: JSON.stringify(body),
                });
            }

            closeModal();
            loadCustomers();
            if (editId && currentCustomer) {
                selectCustomer(editId);
            }
        } catch (e) {
            alert('Error: ' + e.message);
        }
    }

    // ─── Statement Modal ─────────────────
    async function showStatement() {
        if (!currentCustomer) return;
        const modal = document.getElementById('statementModal');
        if (!modal) return;
        const nameEl = document.getElementById('statementName');
        if (nameEl) nameEl.textContent = currentCustomer.name;

        const content = document.getElementById('statementContent');
        if (content) content.innerHTML = '<div style="padding:20px;"><div class="skeleton skeleton--text"></div><div class="skeleton skeleton--text-sm" style="width:70%;"></div><div class="skeleton skeleton--text" style="width:50%;"></div></div>';
        modal.classList.add('active');

        try {
            const data = await api(`/pos/api/customers/${currentCustomer.id}/statement`);

            let html = `<div style="margin-bottom:12px;font-size:14px;">
                <strong>Saldo actual: ${fmt(data.balance)}</strong> |
                Limite: ${fmt(data.customer ? data.customer.credit_limit : 0)}
            </div>`;

            if (!data.entries || data.entries.length === 0) {
                html += '<div style="color:var(--color-text-muted);padding:20px;text-align:center;">Sin movimientos</div>';
            } else {
                html += '<table style="width:100%;border-collapse:collapse;font-size:13px;">';
                html += '<tr style="background:var(--color-surface-2);"><th style="padding:8px;text-align:left;">Fecha</th><th style="text-align:left;">Concepto</th><th style="text-align:right;padding:8px;">Cargo</th><th style="text-align:right;padding:8px;">Abono</th><th style="text-align:right;padding:8px;">Saldo</th></tr>';

                data.entries.forEach(e => {
                    html += `<tr style="border-bottom:1px solid var(--color-border);">
                        <td style="padding:6px 8px;">${formatDate(e.date)}</td>
                        <td>${e.description || ''}</td>
                        <td style="text-align:right;padding:6px 8px;">${e.type === 'charge' ? fmt(e.amount) : ''}</td>
                        <td style="text-align:right;padding:6px 8px;">${e.type === 'payment' ? fmt(e.amount) : ''}</td>
                        <td style="text-align:right;padding:6px 8px;">${fmt(e.running_balance)}</td>
                    </tr>`;
                });
                html += '</table>';
            }

            if (content) content.innerHTML = html;
        } catch (e) {
            if (content) content.innerHTML = `<div style="color:var(--color-error);padding:20px;text-align:center;">Error: ${e.message}</div>`;
        }
    }

    function closeStatement() {
        const modal = document.getElementById('statementModal');
        if (modal) modal.classList.remove('active');
    }

    // ─── Payment Modal ───────────────────
    function showPaymentModal() {
        if (!currentCustomer) return;
        const modal = document.getElementById('paymentModal');
        if (!modal) return;
        document.getElementById('paymentCustomerName').textContent = currentCustomer.name;
        document.getElementById('paymentAmount').value = '';
        document.getElementById('paymentMethod').value = 'cash';
        document.getElementById('paymentRef').value = '';
        modal.classList.add('active');
        document.getElementById('paymentAmount').focus();
    }

    function closePayment() {
        const modal = document.getElementById('paymentModal');
        if (modal) modal.classList.remove('active');
    }

    async function recordPayment() {
        if (!currentCustomer) return;
        const amount = parseFloat(document.getElementById('paymentAmount').value);
        if (!amount || amount <= 0) { alert('Ingresa un monto valido'); return; }

        const method = document.getElementById('paymentMethod').value;
        const reference = document.getElementById('paymentRef').value.trim();

        try {
            await api(`/pos/api/customers/${currentCustomer.id}/payment`, {
                method: 'POST',
                body: JSON.stringify({ amount, payment_method: method, reference }),
            });
            closePayment();
            selectCustomer(currentCustomer.id);
        } catch (e) {
            alert('Error: ' + e.message);
        }
    }

    // ─── Slide Panel (from HTML) ─────────
    // The HTML already has openSlidePanel/closeSlidePanel. We hook showDetail into it.
    function showDetail(id) {
        selectCustomer(id);
        if (typeof openSlidePanel === 'function') openSlidePanel();
    }

    // ─── Init ────────────────────────────
    function init() {
        // Auth check
        if (!token) {
            window.location.href = '/pos/login';
            return;
        }

        // Wire the "Nuevo Cliente" button from the page header
        window.openNewCustomerModal = showCreateModal;

        // Wire action buttons in detail panel
        wireActionButtons();

        // Wire the inline HTML viewCustomer to our showDetail
        window.viewCustomer = showDetail;

        // Inject modals if not present
        injectModals();

        // Load data
        loadCustomers();
        loadSummary();
    }

    function injectModals() {
        // Customer Create/Edit Modal
        // Always remove and re-inject to ensure latest fields are present
        const existingModal = document.getElementById('customerModal');
        if (existingModal) existingModal.remove();
            const div = document.createElement('div');
            div.innerHTML = `
            <div id="customerModal" class="modal-overlay" style="display:none;">
                <div class="modal-box">
                    <div class="modal-header">
                        <h3 id="modalTitle">Nuevo Cliente</h3>
                        <button class="btn-close" onclick="Customers.closeModal()">&times;</button>
                    </div>
                    <div class="modal-body">
                        <input type="hidden" id="editId" />
                        <div class="form-row">
                            <div class="form-group"><label>Nombre *</label><input type="text" id="fName" class="form-input" placeholder="Nombre del cliente" /></div>
                            <div class="form-group"><label>RFC</label><input type="text" id="fRfc" class="form-input" placeholder="RFC" maxlength="13" /></div>
                        </div>
                        <div class="form-row">
                            <div class="form-group"><label>Razon Social</label><input type="text" id="fRazonSocial" class="form-input" placeholder="Razon Social" /></div>
                            <div class="form-group"><label>Regimen Fiscal</label>
                                <select id="fRegimenFiscal" class="form-input">
                                    <option value="">-- Seleccionar --</option>
                                    <option value="601">601 - General de Ley PM</option>
                                    <option value="603">603 - Personas Morales Fines No Lucrativos</option>
                                    <option value="605">605 - Sueldos y Salarios</option>
                                    <option value="606">606 - Arrendamiento</option>
                                    <option value="608">608 - Demas Ingresos</option>
                                    <option value="612">612 - Personas Fisicas Empresariales</option>
                                    <option value="616">616 - Sin Obligaciones Fiscales</option>
                                    <option value="621">621 - Incorporacion Fiscal</option>
                                    <option value="625">625 - RESICO</option>
                                    <option value="626">626 - RESICO PM</option>
                                </select>
                            </div>
                        </div>
                        <div class="form-row">
                            <div class="form-group"><label>Uso CFDI</label>
                                <select id="fUsoCfdi" class="form-input">
                                    <option value="G01">G01 - Adquisicion de mercancias</option>
                                    <option value="G03" selected>G03 - Gastos en general</option>
                                    <option value="I01">I01 - Construcciones</option>
                                    <option value="I08">I08 - Otra maquinaria</option>
                                    <option value="P01">P01 - Por definir</option>
                                    <option value="S01">S01 - Sin efectos fiscales</option>
                                </select>
                            </div>
                            <div class="form-group"><label>Codigo Postal</label><input type="text" id="fCp" class="form-input" placeholder="C.P." maxlength="5" /></div>
                        </div>
                        <div class="form-row">
                            <div class="form-group"><label>Telefono</label><input type="text" id="fPhone" class="form-input" placeholder="Telefono" /></div>
                            <div class="form-group"><label>Email</label><input type="email" id="fEmail" class="form-input" placeholder="correo@ejemplo.com" /></div>
                        </div>
                        <div class="form-group"><label>Direccion</label><input type="text" id="fAddress" class="form-input" placeholder="Direccion" /></div>
                        <div class="form-row">
                            <div class="form-group"><label>Tipo Precio</label>
                                <select id="fPriceTier" class="form-input">
                                    <option value="1">Mostrador</option>
                                    <option value="2">Taller</option>
                                    <option value="3">Mayoreo</option>
                                </select>
                            </div>
                            <div class="form-group"><label>Limite de Credito</label><input type="number" id="fCreditLimit" class="form-input" value="0" min="0" step="1000" /></div>
                            <div class="form-group"><label>Descuento Max (%)</label><input type="number" id="fMaxDiscountPct" class="form-input" value="0" min="0" max="100" step="0.5" /></div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-secondary" onclick="Customers.closeModal()">Cancelar</button>
                        <button class="btn btn-primary" onclick="Customers.save()">Guardar</button>
                    </div>
                </div>
            </div>`;
            document.body.appendChild(div);

        // Statement Modal
        const existingStatement = document.getElementById('statementModal');
        if (existingStatement) existingStatement.remove();
        if (!document.getElementById('statementModal')) {
            const div = document.createElement('div');
            div.innerHTML = `
            <div id="statementModal" class="modal-overlay" style="display:none;">
                <div class="modal-box modal-box--wide">
                    <div class="modal-header">
                        <h3>Estado de Cuenta — <span id="statementName"></span></h3>
                        <button class="btn-close" onclick="Customers.closeStatement()">&times;</button>
                    </div>
                    <div class="modal-body" id="statementContent" style="max-height:60vh;overflow-y:auto;">
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-primary" onclick="Customers.showPaymentModal()">Registrar Abono</button>
                        <button class="btn btn-secondary" onclick="Customers.closeStatement()">Cerrar</button>
                    </div>
                </div>
            </div>`;
            document.body.appendChild(div);
        }

        // Payment Modal
        if (!document.getElementById('paymentModal')) {
            const div = document.createElement('div');
            div.innerHTML = `
            <div id="paymentModal" class="modal-overlay" style="display:none;">
                <div class="modal-box">
                    <div class="modal-header">
                        <h3>Registrar Abono</h3>
                        <button class="btn-close" onclick="Customers.closePayment()">&times;</button>
                    </div>
                    <div class="modal-body">
                        <p style="margin-bottom:var(--space-4);color:var(--color-text-secondary);">Cliente: <strong id="paymentCustomerName"></strong></p>
                        <div class="form-row">
                            <div class="form-group"><label>Monto</label><input type="number" id="paymentAmount" class="form-input" placeholder="0.00" min="0" step="0.01" /></div>
                            <div class="form-group"><label>Metodo</label>
                                <select id="paymentMethod" class="form-input">
                                    <option value="cash">Efectivo</option>
                                    <option value="transfer">Transferencia</option>
                                    <option value="card">Tarjeta</option>
                                    <option value="check">Cheque</option>
                                </select>
                            </div>
                        </div>
                        <div class="form-group"><label>Referencia</label><input type="text" id="paymentRef" class="form-input" placeholder="Num. referencia (opcional)" /></div>
                    </div>
                    <div class="modal-footer">
                        <button class="btn btn-secondary" onclick="Customers.closePayment()">Cancelar</button>
                        <button class="btn btn-primary" onclick="Customers.recordPayment()">Registrar</button>
                    </div>
                </div>
            </div>`;
            document.body.appendChild(div);
        }

        // Inject modal styles
        if (!document.getElementById('modalStyles')) {
            const style = document.createElement('style');
            style.id = 'modalStyles';
            style.textContent = `
                .modal-overlay {
                    position: fixed; top: 0; left: 0; right: 0; bottom: 0;
                    background: rgba(0,0,0,0.5); z-index: 9000;
                    display: flex; align-items: center; justify-content: center;
                    backdrop-filter: blur(2px);
                }
                .modal-overlay.active { display: flex !important; }
                .modal-box {
                    background: var(--color-bg-elevated); border: 1px solid var(--color-border);
                    border-radius: var(--radius-lg); width: 90%; max-width: 600px;
                    max-height: 85vh; overflow-y: auto;
                    box-shadow: var(--shadow-xl);
                }
                .modal-box--wide { max-width: 800px; }
                .modal-header {
                    display: flex; align-items: center; justify-content: space-between;
                    padding: var(--space-4) var(--space-5);
                    border-bottom: 1px solid var(--color-border);
                }
                .modal-header h3 {
                    font-family: var(--font-heading); font-size: var(--text-h6);
                    font-weight: var(--heading-weight-primary); color: var(--color-text-primary);
                    letter-spacing: var(--tracking-wide); text-transform: uppercase;
                }
                .modal-body { padding: var(--space-5); }
                .modal-footer {
                    display: flex; justify-content: flex-end; gap: var(--space-3);
                    padding: var(--space-4) var(--space-5);
                    border-top: 1px solid var(--color-border);
                }
                .form-row { display: flex; gap: var(--space-4); margin-bottom: var(--space-4); }
                .form-row > .form-group { flex: 1; }
                .form-group { margin-bottom: var(--space-4); }
                .form-group label {
                    display: block; font-size: var(--text-caption); font-weight: var(--font-weight-semibold);
                    color: var(--color-text-muted); text-transform: uppercase; letter-spacing: var(--tracking-wider);
                    margin-bottom: var(--space-1);
                }
                .form-input {
                    width: 100%; height: 38px; padding: 0 var(--space-3);
                    background: var(--color-bg-overlay); border: 1.5px solid var(--color-border);
                    border-radius: var(--radius-md); font-family: var(--font-body);
                    font-size: var(--text-body-sm); color: var(--color-text-primary); outline: none;
                    transition: var(--transition-fast);
                }
                .form-input:focus { border-color: var(--color-border-focus); box-shadow: var(--shadow-focus); }
                select.form-input { cursor: pointer; }
            `;
            document.head.appendChild(style);
        }
    }

    // Run init
    init();

    const publicApi = {
        search, goToPage, loadCustomers,
        showDetail, selectCustomer, closeDetail,
        showCreateModal, editCurrent, editCustomer, closeModal, save,
        showStatement, closeStatement,
        showPaymentModal, closePayment, recordPayment,
        showCustomerHistory, closeCustomerHistoryModal,
    };

    // 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: "📊" });
    }

    // Bulk selection
    publicApi.toggleCustomerSelection = function(id) {
        if (selectedCustomers.has(id)) selectedCustomers.delete(id);
        else selectedCustomers.add(id);
        updateBulkToolbar();
    };
    publicApi.toggleSelectAll = function() {
        var cb = document.getElementById('selectAllCustomers');
        var allChecked = cb.checked;
        if (customersVS && customersVS.data) {
            customersVS.data.forEach(function(c) {
                if (allChecked) selectedCustomers.add(c.id);
                else selectedCustomers.delete(c.id);
            });
            customersVS.refresh();
        }
        updateBulkToolbar();
    };
    function updateBulkToolbar() {
        var container = document.getElementById('customersBulkToolbar');
        if (!container) return;
        var count = selectedCustomers.size;
        if (count === 0) { container.innerHTML = ''; return; }
        container.innerHTML = renderBulkToolbar(count,
            '<button class="btn btn--primary btn--sm" onclick="Customers.featureProximamente(\'Exportar seleccionados\')">📥 Exportar</button>' +
            '<button class="btn btn--ghost btn--sm" onclick="Customers.clearSelection()">Limpiar</button>'
        );
    }
    publicApi.clearSelection = function() {
        selectedCustomers.clear();
        document.getElementById('selectAllCustomers').checked = false;
        if (customersVS) customersVS.refresh();
        updateBulkToolbar();
    };

    publicApi.featureProximamente = function(name) {
        if (typeof window.featureProximamente === 'function') {
            window.featureProximamente(name);
        } else {
            alert(name + ' — próximamente');
        }
    };

    // Expose globally for inline HTML onclick handlers
    window.Customers = publicApi;
    return publicApi;
})();
