// /home/Autopartes/pos/static/js/dashboard.js
// Dashboard module: fetches real data from POS APIs

const Dashboard = (() => {
    function token() {
        return localStorage.getItem('pos_token') || '';
    }

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

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

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

    function fmtInt(n) {
        return parseInt(n || 0).toLocaleString('es-MX');
    }

    /** Today as YYYY-MM-DD */
    function todayStr() {
        return new Date().toISOString().slice(0, 10);
    }

    /** Return a date N days ago as YYYY-MM-DD */
    function daysAgo(n) {
        const d = new Date();
        d.setDate(d.getDate() - n);
        return d.toISOString().slice(0, 10);
    }

    const DAY_NAMES_SHORT = ['Dom', 'Lun', 'Mar', 'Mie', 'Jue', 'Vie', 'Sab'];
    const MONTH_NAMES = ['enero', 'febrero', 'marzo', 'abril', 'mayo', 'junio',
        'julio', 'agosto', 'septiembre', 'octubre', 'noviembre', 'diciembre'];
    const DAY_NAMES_LONG = ['Domingo', 'Lunes', 'Martes', 'Miercoles', 'Jueves', 'Viernes', 'Sabado'];

    // -------------------------------------------------------------------------
    // Theme switcher
    // -------------------------------------------------------------------------
    function setTheme(theme) {
        document.documentElement.setAttribute('data-theme', theme);
        try { localStorage.setItem('pos_theme', theme); } catch(e) {}
        const btnInd = document.getElementById('btn-industrial');
        const btnMod = document.getElementById('btn-modern');
        if (btnInd) btnInd.classList.toggle('active', theme === 'industrial');
        if (btnMod) btnMod.classList.toggle('active', theme === 'modern');
    }
    window.setTheme = setTheme;

    // -------------------------------------------------------------------------
    // Sidebar toggle (mobile)
    // -------------------------------------------------------------------------
    function toggleSidebar() {
        const sidebar = document.getElementById('sidebar');
        const overlay = document.getElementById('sidebar-overlay');
        if (!sidebar) return;
        const isOpen = sidebar.classList.contains('open');
        sidebar.classList.toggle('open', !isOpen);
        if (overlay) overlay.classList.toggle('open', !isOpen);
        document.body.style.overflow = isOpen ? '' : 'hidden';
    }
    window.toggleSidebar = toggleSidebar;

    function closeSidebar() {
        const sidebar = document.getElementById('sidebar');
        const overlay = document.getElementById('sidebar-overlay');
        if (sidebar) sidebar.classList.remove('open');
        if (overlay) overlay.classList.remove('open');
        document.body.style.overflow = '';
    }
    window.closeSidebar = closeSidebar;

    window.addEventListener('resize', function() {
        if (window.innerWidth >= 768) closeSidebar();
    });

    // -------------------------------------------------------------------------
    // Period selector
    // -------------------------------------------------------------------------
    function setPeriod(btn) {
        btn.closest('.period-selector').querySelectorAll('.period-btn').forEach(function(b) {
            b.classList.remove('active');
        });
        btn.classList.add('active');
        const period = btn.textContent.trim().toLowerCase();
        loadChart(period);
    }
    window.setPeriod = setPeriod;

    // -------------------------------------------------------------------------
    // Generic fetch helper
    // -------------------------------------------------------------------------
    async function apiFetch(url) {
        try {
            const resp = await fetch(url, { headers: headers() });
            if (resp.status === 401) {
                window.location.href = '/pos/login';
                return null;
            }
            if (!resp.ok) return null;
            return await resp.json();
        } catch (err) {
            console.error('Dashboard fetch error:', url, err);
            return null;
        }
    }

    // -------------------------------------------------------------------------
    // Set header greeting with real date and user info
    // -------------------------------------------------------------------------
    function setGreeting() {
        const now = new Date();
        const h = now.getHours();
        let saludo = 'Buenos dias';
        if (h >= 12 && h < 19) saludo = 'Buenas tardes';
        else if (h >= 19) saludo = 'Buenas noches';

        // Try to get user name from JWT payload
        let userName = '';
        try {
            const payload = JSON.parse(atob(token().split('.')[1]));
            userName = payload.name || payload.sub || '';
        } catch(e) {}

        const greetEl = document.getElementById('header-greeting');
        if (greetEl) greetEl.textContent = userName ? `${saludo}, ${userName}` : saludo;

        const subEl = document.getElementById('header-subtitle');
        if (subEl) {
            const dayName = DAY_NAMES_LONG[now.getDay()];
            const day = now.getDate();
            const month = MONTH_NAMES[now.getMonth()];
            const year = now.getFullYear();
            subEl.textContent = `${dayName}, ${day} de ${month} de ${year}`;
        }
    }

    // -------------------------------------------------------------------------
    // 1. Ventas de hoy KPIs (daily summary)
    // -------------------------------------------------------------------------
    async function loadDailySummary() {
        const today = todayStr();
        const data = await apiFetch(`/pos/api/register/daily-summary?date=${today}`);
        if (!data) {
            setKpiError('kpi-ventas-total', 'kpi-ventas-meta');
            setKpiError('kpi-tickets-count', 'kpi-tickets-meta');
            setKpiError('kpi-promedio-value', 'kpi-promedio-meta');
            return null;
        }

        // Ventas Hoy
        const totalEl = document.getElementById('kpi-ventas-total');
        const metaEl = document.getElementById('kpi-ventas-meta');
        if (totalEl) totalEl.textContent = fmt(data.total_sales);
        if (metaEl) {
            const methods = Object.entries(data.sales_by_method || {})
                .map(([m, v]) => `${capitalize(m)}: ${fmt(v.amount)}`)
                .join(' | ');
            metaEl.innerHTML = methods
                ? `<span class="kpi-meta-text">${methods}</span>`
                : '<span class="kpi-meta-text">Sin ventas aun</span>';
        }

        // Tickets Hoy
        const ticketsEl = document.getElementById('kpi-tickets-count');
        const ticketsMetaEl = document.getElementById('kpi-tickets-meta');
        if (ticketsEl) ticketsEl.textContent = fmtInt(data.total_sales_count);
        if (ticketsMetaEl) {
            const cancelled = data.cancelled_count || 0;
            ticketsMetaEl.innerHTML = cancelled > 0
                ? `<span class="kpi-tag kpi-tag--neutral">${cancelled} cancelada${cancelled > 1 ? 's' : ''}</span><span class="kpi-meta-text">de ${data.total_sales_count + cancelled} totales</span>`
                : `<span class="kpi-meta-text">${data.total_sales_count} completada${data.total_sales_count !== 1 ? 's' : ''}</span>`;
        }

        // Ticket Promedio
        const promedioEl = document.getElementById('kpi-promedio-value');
        const promedioMetaEl = document.getElementById('kpi-promedio-meta');
        const avg = data.total_sales_count > 0 ? data.total_sales / data.total_sales_count : 0;
        if (promedioEl) promedioEl.textContent = fmt(avg);
        if (promedioMetaEl) {
            promedioMetaEl.innerHTML = `<span class="kpi-meta-text">sobre ${fmtInt(data.total_sales_count)} ventas</span>`;
        }

        // Cajas del Día KPI
        const cajasCountEl = document.getElementById('kpi-cajas-count');
        const cajasMetaEl = document.getElementById('kpi-cajas-meta');
        const regs = data.registers || [];
        const activeRegs = regs.filter(r => r.status === 'open');
        const closedRegs = regs.filter(r => r.status === 'closed');
        if (cajasCountEl) cajasCountEl.textContent = regs.length;
        if (cajasMetaEl) {
            cajasMetaEl.innerHTML = `<span class="kpi-tag kpi-tag--up">${activeRegs.length} abierta${activeRegs.length !== 1 ? 's' : ''}</span><span class="kpi-meta-text">${closedRegs.length} cerrada${closedRegs.length !== 1 ? 's' : ''}</span>`;
        }

        // Also populate registers list
        renderRegisters(regs);

        return data;
    }

    // -------------------------------------------------------------------------
    // 1b. Historical sales KPIs (imported data)
    // -------------------------------------------------------------------------
    async function loadHistoricalSummary() {
        try {
            const now = new Date();
            const firstDay = new Date(now.getFullYear(), now.getMonth(), 1).toISOString().slice(0, 10);
            const lastDay = new Date(now.getFullYear(), now.getMonth() + 1, 0).toISOString().slice(0, 10);

            // All historical sales
            const all = await apiFetch('/pos/api/historical-sales?per_page=1');
            const totalRecords = all.pagination ? all.pagination.total : 0;

            // Current month historical sales
            const month = await apiFetch(`/pos/api/historical-sales?date_from=${firstDay}&date_to=${lastDay}&per_page=200`);
            const monthRows = month.data || [];
            const monthTotal = monthRows.reduce((a, r) => a + (r.total || 0), 0);

            const totalEl = document.getElementById('kpi-historico-total-value');
            const totalMetaEl = document.getElementById('kpi-historico-total-meta');
            if (totalEl) totalEl.textContent = fmt(monthTotal);
            if (totalMetaEl) totalMetaEl.innerHTML = `<span class="kpi-meta-text">${fmtInt(totalRecords)} tickets importados</span>`;

            const mesEl = document.getElementById('kpi-historico-mes-value');
            const mesMetaEl = document.getElementById('kpi-historico-mes-meta');
            if (mesEl) mesEl.textContent = fmt(monthTotal);
            if (mesMetaEl) mesMetaEl.innerHTML = `<span class="kpi-meta-text">${monthRows.length} tickets este mes</span>`;

            const countEl = document.getElementById('kpi-historico-count-value');
            const countMetaEl = document.getElementById('kpi-historico-count-meta');
            if (countEl) countEl.textContent = fmtInt(totalRecords);
            if (countMetaEl) countMetaEl.innerHTML = `<span class="kpi-meta-text">Registros históricos</span>`;

        } catch (err) {
            console.error('Error loading historical summary:', err);
            const ids = [
                ['kpi-historico-total-value', 'kpi-historico-total-meta'],
                ['kpi-historico-mes-value', 'kpi-historico-mes-meta'],
                ['kpi-historico-count-value', 'kpi-historico-count-meta'],
            ];
            ids.forEach(([v, m]) => setKpiError(v, m));
        }
    }

    function setKpiError(valueId, metaId) {
        const v = document.getElementById(valueId);
        const m = document.getElementById(metaId);
        if (v) v.innerHTML = '<span style="color:var(--color-error)">--</span>';
        if (m) m.innerHTML = '<span class="kpi-meta-text" style="color:var(--color-error)">Error al cargar</span>';
    }

    function capitalize(s) {
        if (!s) return '';
        return s.charAt(0).toUpperCase() + s.slice(1);
    }

    // -------------------------------------------------------------------------
    // 2. Registers list
    // -------------------------------------------------------------------------
    function renderRegisters(registers) {
        const container = document.getElementById('registers-list');
        if (!container) return;

        if (!registers || registers.length === 0) {
            container.innerHTML = renderEmptyState({
                icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
                title: 'Sin cajas hoy',
                subtitle: 'Ninguna caja ha sido abierta el día de hoy.',
                action: '<a href="/pos/sale" class="btn btn--primary btn--sm">Abrir POS</a>'
            });
            return;
        }

        const maxSale = Math.max(...registers.map(r => r.sale_total || 0), 1);
        container.innerHTML = registers.map((r, i) => {
            const statusClass = r.status === 'open' ? 'kpi-tag--up' : 'kpi-tag--neutral';
            const statusLabel = r.status === 'open' ? 'Abierta' : 'Cerrada';
            const pct = maxSale > 0 ? Math.round((r.sale_total / maxSale) * 100) : 0;
            return `
                <div class="rank-item">
                    <div class="rank-num ${i === 0 ? 'rank-num--1' : i === 1 ? 'rank-num--2' : ''}">${i + 1}</div>
                    <div class="rank-item__info">
                        <div class="rank-item__name">Caja ${r.register_number || r.id}</div>
                        <div class="rank-item__sub">${r.employee_name || 'Sin cajero'} &nbsp;&middot;&nbsp; ${r.sale_count || 0} ventas &nbsp;<span class="kpi-tag ${statusClass}" style="font-size:9px;padding:1px 6px;">${statusLabel}</span></div>
                        <div class="rank-item__bar-bg">
                            <div class="rank-item__bar-fill" style="width:${pct}%"></div>
                        </div>
                    </div>
                    <div class="rank-item__value">${fmt(r.sale_total)}</div>
                </div>`;
        }).join('');
    }

    // -------------------------------------------------------------------------
    // 3. Inventory alerts
    // -------------------------------------------------------------------------
    async function loadAlerts() {
        const data = await apiFetch('/pos/api/inventory/alerts');
        const container = document.getElementById('alerts-grid');
        if (!container) return;

        if (!data || !data.data || data.data.length === 0) {
            container.innerHTML = `
                <div class="alert-item" style="border-left:4px solid var(--color-success);justify-content:center;">
                    <div class="alert-icon-wrap" style="background-color:rgba(34,197,94,0.1);color:var(--color-success);">
                        <svg width="18" height="18" viewBox="0 0 18 18" fill="none"><circle cx="9" cy="9" r="7" stroke="currentColor" stroke-width="1.5"/><path d="M6 9l2 2 4-4" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"/></svg>
                    </div>
                    <div class="alert-content">
                        <span class="alert-title">Sin alertas</span>
                        <div class="alert-desc">Todo el inventario dentro de parametros normales.</div>
                    </div>
                </div>`;
            return;
        }

        const alerts = data.data;
        // Group by type
        const zero = alerts.filter(a => a.type === 'zero');
        const low = alerts.filter(a => a.type === 'low');
        const over = alerts.filter(a => a.type === 'over');

        let html = '';

        if (zero.length > 0) {
            const items = zero.slice(0, 5).map(a => `${a.name}: <strong>${a.stock} uds</strong>`).join(' &middot; ');
            html += buildAlertCard('error', 'Stock Agotado', `${zero.length} items`, items,
                '<svg width="18" height="18" viewBox="0 0 18 18" fill="none"><path d="M9 3L16.5 15H1.5L9 3z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M9 8v3M9 12.5v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>');
        }

        if (low.length > 0) {
            const items = low.slice(0, 5).map(a => `${a.name}: <strong>${a.stock} uds</strong> (min ${a.min_stock})`).join(' &middot; ');
            html += buildAlertCard('warning', 'Stock Bajo', `${low.length} items`, items,
                '<svg width="18" height="18" viewBox="0 0 18 18" fill="none"><path d="M9 3L16.5 15H1.5L9 3z" stroke="currentColor" stroke-width="1.5" stroke-linejoin="round"/><path d="M9 8v3M9 12.5v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>');
        }

        if (over.length > 0) {
            const items = over.slice(0, 5).map(a => `${a.name}: <strong>${a.stock} uds</strong> (max ${a.max_stock})`).join(' &middot; ');
            html += buildAlertCard('orange', 'Sobrestock', `${over.length} items`, items,
                '<svg width="18" height="18" viewBox="0 0 18 18" fill="none"><rect x="2" y="2" width="14" height="14" rx="2" stroke="currentColor" stroke-width="1.5"/><path d="M9 6v3M9 11v.5" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/></svg>');
        }

        container.innerHTML = html || '<div class="alert-item" style="border-left:none;justify-content:center;color:var(--color-text-muted);">Sin alertas</div>';
    }

    function buildAlertCard(severity, title, badge, desc, iconSvg) {
        return `
            <div class="alert-item alert-item--${severity}">
                <div class="alert-icon-wrap alert-icon-wrap--${severity}">${iconSvg}</div>
                <div class="alert-content">
                    <div style="display:flex;align-items:center;gap:var(--space-2);margin-bottom:3px;">
                        <span class="alert-title">${title}</span>
                        <span class="alert-badge alert-badge--${severity}">${badge}</span>
                    </div>
                    <div class="alert-desc">${desc}</div>
                </div>
                <a href="/pos/inventory#alertas" class="alert-action" style="text-decoration:none;">Ver</a>
            </div>`;
    }

    // -------------------------------------------------------------------------
    // 4. Credit alerts
    // -------------------------------------------------------------------------
    async function loadCreditAlerts() {
        const data = await apiFetch('/pos/api/dashboard/credit-alerts');
        const tbody = document.getElementById('credit-alerts-tbody');
        const meta = document.getElementById('credit-alerts-meta');
        if (!tbody) return;

        if (!data || !data.data || data.data.length === 0) {
            tbody.innerHTML = '<tr><td colspan="6" style="text-align:center;padding:var(--space-4);color:var(--color-text-muted);">No hay créditos por vencer.</td></tr>';
            if (meta) meta.textContent = 'Vencidos: 0 / Por vencer: 0';
            return;
        }

        if (meta) {
            meta.innerHTML = `<span style="color:var(--color-error);font-weight:600;">Vencidos: ${data.overdue_count || 0}</span> &nbsp;|&nbsp; <span style="color:var(--color-warning);font-weight:600;">Por vencer: ${data.due_soon_count || 0}</span>`;
        }

        tbody.innerHTML = data.data.map(function(r) {
            const dueDate = r.due_date ? new Date(r.due_date).toLocaleDateString('es-MX') : '-';
            const daysText = r.days_until_due < 0 ? `${Math.abs(r.days_until_due)} días vencido` : `${r.days_until_due} días restantes`;
            const statusClass = r.status === 'overdue' ? 'error' : (r.status === 'due_soon' ? 'warning' : 'success');
            return `<tr>
                <td><span class="td-client">${escHtml(r.customer_name)}</span></td>
                <td><span class="td-mono">${escHtml(r.folio)}</span></td>
                <td>${dueDate}</td>
                <td>${daysText}</td>
                <td class="align-right"><span class="td-mono">${fmt(r.balance)}</span></td>
                <td><span class="badge badge--${statusClass}">${r.status_label}</span></td>
            </tr>`;
        }).join('');
    }

    // -------------------------------------------------------------------------
    // 5. Top Products (from today's sales detail)
    // -------------------------------------------------------------------------
    async function loadTopProducts() {
        // Single optimized endpoint: returns today's top products already aggregated
        const data = await apiFetch('/pos/api/dashboard/stats');
        const container = document.getElementById('top-products-list');
        if (!container) return;

        const top = data && data.top_products ? data.top_products : [];

        if (!top.length) {
            container.innerHTML = renderEmptyState({
                icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
                title: 'Sin ventas hoy',
                subtitle: 'Aún no hay transacciones registradas el día de hoy.',
                action: '<a href="/pos/sale" class="btn btn--primary btn--sm">Nueva venta</a>'
            });
            return;
        }

        const sorted = top.slice(0, 5);
        const maxRev = sorted[0].revenue || 1;
        container.innerHTML = sorted.map((p, i) => {
            const pct = Math.round((p.revenue / maxRev) * 100);
            return `
                <div class="rank-item">
                    <div class="rank-num ${i === 0 ? 'rank-num--1' : i === 1 ? 'rank-num--2' : ''}">${i + 1}</div>
                    <div class="rank-item__info">
                        <div class="rank-item__name">${escHtml(p.name)}</div>
                        <div class="rank-item__sub">${p.quantity} pzas vendidas</div>
                        <div class="rank-item__bar-bg">
                            <div class="rank-item__bar-fill" style="width:${pct}%"></div>
                        </div>
                    </div>
                    <div class="rank-item__value">${fmt(p.revenue)}</div>
                </div>`;
        }).join('');
    }

    function escHtml(s) {
        const div = document.createElement('div');
        div.textContent = s || '';
        return div.innerHTML;
    }

    // -------------------------------------------------------------------------
    // Helpers for chart grouping
    // -------------------------------------------------------------------------
    function isoWeek(date) {
        const tmp = new Date(date.valueOf());
        const dayNum = (date.getDay() + 6) % 7;
        tmp.setDate(tmp.getDate() - dayNum + 3);
        const firstThursday = tmp.valueOf();
        tmp.setMonth(0, 1);
        if (tmp.getDay() !== 4) {
            tmp.setMonth(0, 1 + ((4 - tmp.getDay()) + 7) % 7);
        }
        return 1 + Math.ceil((firstThursday - tmp) / 604800000);
    }

    function weekLabel(date) {
        return `Sem ${isoWeek(date)}`;
    }

    function monthLabel(date) {
        return MONTH_NAMES[date.getMonth()].slice(0, 3);
    }

    // -------------------------------------------------------------------------
    // 5. Sales chart (today / week / month / year)
    // -------------------------------------------------------------------------
    async function loadChart(period) {
        const chartEl = document.getElementById('bar-chart');
        const totalEl = document.getElementById('chart-week-total');
        const legendEl = document.getElementById('chart-legend');
        const titleEl = document.querySelector('.chart-header .section-title');
        if (!chartEl) return;

        period = period || 'semana';

        let dateFrom, dateTo, labels = [], buckets = {}, labelOrder = [];
        const now = new Date();

        if (period === 'hoy') {
            dateFrom = dateTo = todayStr();
            labelOrder = ['Hoy'];
            buckets['Hoy'] = 0;
        } else if (period === 'semana') {
            const days = [];
            for (let i = 6; i >= 0; i--) { days.push(daysAgo(i)); }
            dateFrom = days[0];
            dateTo = days[6];
            days.forEach(d => {
                const date = new Date(d + 'T12:00:00');
                const label = DAY_NAMES_SHORT[date.getDay()];
                labelOrder.push(label);
                buckets[label] = { total: 0, date: d };
            });
        } else if (period === 'mes') {
            const year = now.getFullYear();
            const month = now.getMonth();
            const lastDay = new Date(year, month + 1, 0).getDate();
            dateFrom = new Date(year, month, 1).toISOString().slice(0, 10);
            dateTo = new Date(year, month, lastDay).toISOString().slice(0, 10);
            for (let i = 1; i <= 4; i++) {
                const label = `Sem ${i}`;
                labelOrder.push(label);
                buckets[label] = { total: 0, week: i };
            }
        } else if (period === 'año') {
            for (let i = 11; i >= 0; i--) {
                const d = new Date(now.getFullYear(), now.getMonth() - i, 1);
                const label = monthLabel(d);
                labelOrder.push(label);
                buckets[label] = 0;
            }
            dateFrom = new Date(now.getFullYear(), now.getMonth() - 11, 1).toISOString().slice(0, 10);
            dateTo = todayStr();
        }

        // Fetch normal sales for short periods
        let normalByKey = {};
        if (period === 'hoy' || period === 'semana') {
            const days = period === 'hoy' ? [todayStr()] : (function() {
                const arr = [];
                for (let i = 6; i >= 0; i--) arr.push(daysAgo(i));
                return arr;
            })();
            const summaries = await Promise.all(
                days.map(d => apiFetch(`/pos/api/register/daily-summary?date=${d}`))
            );
            days.forEach((d, i) => {
                const date = new Date(d + 'T12:00:00');
                const key = period === 'hoy' ? 'Hoy' : DAY_NAMES_SHORT[date.getDay()];
                normalByKey[key] = summaries[i] ? (summaries[i].total_sales || 0) : 0;
            });
        }

        // Fetch historical sales for the range
        let histRows = [];
        try {
            const perPage = period === 'año' ? 2000 : 1000;
            const histData = await apiFetch(`/pos/api/historical-sales?date_from=${dateFrom}&date_to=${dateTo}&per_page=${perPage}`);
            histRows = histData.data || [];
            const totalPages = histData.pagination ? histData.pagination.total_pages : 1;
            for (let p = 2; p <= totalPages && p <= 20; p++) {
                const more = await apiFetch(`/pos/api/historical-sales?date_from=${dateFrom}&date_to=${dateTo}&per_page=${perPage}&page=${p}`);
                histRows = histRows.concat(more.data || []);
            }
        } catch (e) {
            histRows = [];
        }

        // Group historical sales
        histRows.forEach(r => {
            if (!r.sale_date) return;
            const date = new Date(r.sale_date + 'T12:00:00');
            let key;
            if (period === 'hoy') key = 'Hoy';
            else if (period === 'semana') key = DAY_NAMES_SHORT[date.getDay()];
            else if (period === 'mes') {
                const day = date.getDate();
                const weekNum = day <= 7 ? 1 : day <= 14 ? 2 : day <= 21 ? 3 : 4;
                key = `Sem ${weekNum}`;
            } else {
                key = monthLabel(date);
            }
            if (key) {
                if (typeof buckets[key] === 'object') buckets[key].total += (r.total || 0);
                else buckets[key] = (buckets[key] || 0) + (r.total || 0);
            }
        });

        // Build chart data
        let chartTotal = 0;
        const dayData = labelOrder.map(label => {
            let normalTotal = normalByKey[label] || 0;
            let histTotal = 0;
            if (typeof buckets[label] === 'object') {
                histTotal = buckets[label].total;
            } else {
                histTotal = buckets[label] || 0;
            }
            const total = normalTotal + histTotal;
            chartTotal += total;
            const isToday = period === 'hoy' || (typeof buckets[label] === 'object' && buckets[label].date === todayStr());
            return { label, total, isToday };
        });

        // Update labels
        const titles = { hoy: 'Ventas de Hoy', semana: 'Ventas Semanales', mes: 'Ventas del Mes', año: 'Ventas del Año' };
        const legends = { hoy: 'Total del día', semana: 'Ventas brutas (7 días)', mes: 'Ventas brutas (4 semanas)', año: 'Ventas brutas (12 meses)' };
        if (titleEl) titleEl.textContent = titles[period] || 'Ventas';
        if (totalEl) {
            const periodLabel = period === 'hoy' ? 'Total día' : period === 'semana' ? 'Total semana' : period === 'mes' ? 'Total mes' : 'Total año';
            totalEl.innerHTML = `${periodLabel}: <strong style="color:var(--color-primary);font-family:var(--font-mono);">${fmt(chartTotal)}</strong>`;
        }
        if (legendEl) {
            legendEl.innerHTML = `<div class="legend-item"><div class="legend-dot"></div>${legends[period]}</div>`;
        }

        const maxVal = Math.max(...dayData.map(d => d.total), 1);

        chartEl.innerHTML = dayData.map(d => {
            const heightPct = Math.max(Math.round((d.total / maxVal) * 100), 2);
            const todayClass = d.isToday ? ' today' : '';
            const todayLabelStyle = d.isToday ? ' style="color:var(--color-primary);font-weight:700;"' : '';
            const tooltip = d.isToday ? `${fmt(d.total)} ← Hoy` : fmt(d.total);
            return `
                <div class="bar-chart__col">
                    <div class="bar-chart__bar-wrap">
                        <div class="bar-chart__bar${todayClass}" style="height:${heightPct}%" data-value="${tooltip}"></div>
                    </div>
                    <span class="bar-chart__label"${todayLabelStyle}>${d.label}</span>
                </div>`;
        }).join('');
    }

    // -------------------------------------------------------------------------
    // 6. Recent sales table
    // -------------------------------------------------------------------------
    async function loadRecentSales() {
        const today = todayStr();
        const data = await apiFetch(`/pos/api/sales/recent?date_from=${today}&date_to=${today}&limit=10`);
        const tbody = document.getElementById('recent-sales-tbody');
        if (!tbody) return;

        const sales = data && data.data ? data.data : [];
        if (!sales.length) {
            tbody.innerHTML = '<tr><td colspan="5">' + renderEmptyState({
                icon: '<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><rect x="2" y="3" width="20" height="14" rx="2" ry="2"/><path d="M8 21h8M12 17v4"/></svg>',
                title: 'Sin ventas hoy',
                subtitle: 'Aún no hay transacciones registradas.',
                action: '<a href="/pos/sale" class="btn btn--primary btn--sm">Nueva venta</a>'
            }) + '</td></tr>';
            return;
        }

        const salesToShow = sales.slice(0, 5);

        tbody.innerHTML = salesToShow.map((sale) => {
            const time = sale.created_at ? sale.created_at.slice(11, 16) : '--:--';
            const client = sale.customer_name || 'Publico General';
            const total = sale.total || 0;
            const method = sale.payment_method || 'efectivo';

            // Build products summary from items already included in the response
            let productsSummary = '';
            const items = sale.items || [];
            if (items.length > 0) {
                productsSummary = items.slice(0, 3).map(it =>
                    `${escHtml(it.name)}${it.quantity > 1 ? ' (x' + it.quantity + ')' : ''}`
                ).join(', ');
                if (items.length > 3) productsSummary += '...';
            }

            const methodClass = getPaymentBadgeClass(method);
            const methodLabel = capitalize(method);

            const statusTag = sale.status === 'cancelled'
                ? ' <span style="color:var(--color-error);font-size:10px;font-weight:700;">[CANCELADA]</span>' : '';

            return `
                <tr>
                    <td><span class="td-time">${time}</span></td>
                    <td><span class="td-client">${escHtml(client)}</span>${statusTag}</td>
                    <td class="td-products">${productsSummary}</td>
                    <td><span class="td-mono">${fmt(total)}</span></td>
                    <td><span class="pago-badge pago-badge--${methodClass}">${methodLabel}</span></td>
                </tr>`;
        }).join('');
    }

    function getPaymentBadgeClass(method) {
        const m = (method || '').toLowerCase();
        if (m.includes('efectivo') || m === 'cash') return 'efectivo';
        if (m.includes('tarjeta') || m === 'card') return 'tarjeta';
        if (m.includes('transferencia') || m === 'transfer') return 'transferencia';
        if (m.includes('credito') || m === 'credit') return 'credito';
        return 'efectivo';
    }

    // -------------------------------------------------------------------------
    // Init
    // -------------------------------------------------------------------------
    function init() {
        if (!checkAuth()) return;

        // Restore theme
        try {
            const saved = localStorage.getItem('pos_theme');
            if (saved === 'industrial' || saved === 'modern') {
                setTheme(saved);
            }
        } catch(e) {}

        setGreeting();

        // Load all data in parallel
        loadDailySummary();
        loadHistoricalSummary();
        loadAlerts();
        loadCreditAlerts();
        loadTopProducts();
        loadChart('semana');
        loadRecentSales();

        // Auto-refresh every 2 minutes
        setInterval(() => {
            loadDailySummary();
            loadRecentSales();
            loadCreditAlerts();
        }, 120000);
    }

    // Register Cmd+K items
    if (typeof registerCmdKItem === 'function') {
        registerCmdKItem({ group: 'Principal', label: 'Dashboard', href: '/pos/dashboard', icon: '📊' });
        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: 'Facturación', href: '/pos/invoicing', icon: '📄' });
        registerCmdKItem({ group: 'Principal', label: 'Reportes', href: '/pos/reports', icon: '📈' });
        registerCmdKItem({ group: 'Principal', label: 'Configuración', href: '/pos/config', icon: '⚙️' });
    }

    document.addEventListener('DOMContentLoaded', init);

    return { init, setTheme };
})();
