<?= $this->extend('layouts/main') ?>

<?= $this->section('content') ?>

<style>
    :root {
      --bg-dash:   #f8fafc;
      --bg-card:   #ffffff;
      --border-sim:rgba(0,0,0,0.06);
      --accent:    #3b82f6;
      --accent2:   #6366f1;
      --success:   #10b981;
      --warning:   #f59e0b;
      --danger:    #ef4444;
      --text-main: #0f172a;
      --text-muted:#64748b;
    }

    .stat-grid {
        display: grid;
        grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
        gap: 16px;
        margin-bottom: 28px;
    }
    .stat-card {
        background: var(--bg-card);
        border: 1px solid var(--border-sim);
        border-radius: 14px;
        padding: 20px;
        position: relative;
        overflow: hidden;
        transition: border-color .2s, transform .2s;
    }
    .stat-card:hover {
        border-color: rgba(59,130,246,.3);
        transform: translateY(-2px);
    }
    .stat-card::before {
        content: '';
        position: absolute;
        inset: 0;
        background: radial-gradient(circle at top right, rgba(59,130,246,.03), transparent 70%);
    }
    .stat-card .stat-icon {
        width: 40px; height: 40px;
        border-radius: 10px;
        display: flex; align-items: center; justify-content: center;
        font-size: 1.15rem;
        margin-bottom: 14px;
    }
    .stat-card .stat-value {
        font-size: 1.65rem;
        font-weight: 800;
        color: var(--text-main);
        line-height: 1;
        margin-bottom: 4px;
    }
    .stat-card .stat-label {
        font-size: .75rem;
        color: var(--text-muted);
        text-transform: uppercase;
        letter-spacing: .05em;
    }
    .stat-card .stat-change {
        position: absolute;
        top: 20px; right: 20px;
        font-size: .72rem;
        font-weight: 700;
        padding: 3px 8px;
        border-radius: 20px;
    }
    .change-up   { background: rgba(34,197,94,.1); color: #059669; }
    .change-down { background: rgba(239,68,68,.1);  color: #dc2626; }
    .change-neu  { background: rgba(100,116,139,.1); color: #64748b; }

    .icon-blue   { background: rgba(59,130,246,.15); color: #3b82f6; }
    .icon-purple { background: rgba(99,102,241,.15); color: #6366f1; }
    .icon-yellow { background: rgba(245,158,11,.15); color: #f59e0b; }
    .icon-green  { background: rgba(16,185,129,.15); color: #10b981; }

    .chart-row { display: grid; gap: 1.25rem; margin-bottom: 1.25rem; }
    .chart-row.col-2-side { grid-template-columns: 1fr 1fr; }
    .chart-row.col-3      { grid-template-columns: 2fr 1fr; }
    @media(max-width:992px) {
        .chart-row.col-2-side,
        .chart-row.col-3 { grid-template-columns: 1fr; }
    }

    .chart-card { background: var(--bg-card); border: 1px solid var(--border-sim); border-radius: 14px; overflow: hidden; }
    .chart-head {
      padding: 1.1rem 1.4rem; border-bottom: 1px solid var(--border-sim);
      display: flex; align-items: center; gap: .75rem;
    }
    .chart-head h3 { font-size: .95rem; font-weight: 700; flex: 1; margin: 0; color: var(--text-main); }
    .chart-body { padding: 1.5rem; position: relative; width: 100%; }
    .chart-body canvas { max-width: 100%; height: auto !important; display: block; }

    .sim-table { width: 100%; border-collapse: collapse; font-size: .85rem; }
    .sim-table thead th {
        padding: 12px 16px; text-align: left;
        color: var(--text-muted); font-size: .72rem;
        text-transform: uppercase; letter-spacing: .06em;
        border-bottom: 1px solid var(--border-sim); background: #f8fafc;
    }
    .sim-table tbody td {
        padding: 14px 16px; color: #334155; border-bottom: 1px solid var(--border-sim);
    }
    .badge-sim { padding: 3px 10px; border-radius: 20px; font-size: .7rem; font-weight: 700; }
    .badge-ecer     { background: rgba(59,130,246,0.12); color: #3b82f6; }
    .badge-reseller { background: rgba(99,102,241,0.12); color: #6366f1; }
    .badge-maklon   { background: rgba(245,158,11,0.12); color: #d97706; }

    .export-dropdown { position: relative; display: inline-block; }
    .export-menu {
        display: none; position: absolute;
        background: #fff; min-width: 200px;
        box-shadow: 0 8px 16px rgba(0,0,0,.2);
        padding: 12px 16px; z-index: 10;
        border-radius: 8px; border: 1px solid var(--border-sim);
        right: 0; top: 100%; margin-top: 4px;
    }
    .export-menu a {
        color: var(--text-main); padding: 12px 0; text-decoration: none;
        display: flex; align-items: center; gap: 8px; cursor: pointer;
        border-bottom: 1px solid var(--border-sim);
    }
    .export-menu a:last-child { border-bottom: none; }
    .export-menu a:hover { color: var(--accent); }
    .export-menu.show { display: block; }

    .toast-notification {
        position: fixed; bottom: 20px; right: 20px;
        background: #10b981; color: #fff;
        padding: 16px 24px; border-radius: 8px;
        box-shadow: 0 4px 12px rgba(0,0,0,.15);
        z-index: 9999; animation: slideIn .3s ease-in;
    }
    .toast-notification.error { background: #ef4444; }
    @keyframes slideIn {
        from { transform: translateX(400px); opacity: 0; }
        to   { transform: translateX(0);     opacity: 1; }
    }

    .loading-spinner {
        display: inline-block; width: 20px; height: 20px;
        border: 3px solid rgba(59,130,246,.3); border-radius: 50%;
        border-top-color: #3b82f6; animation: spin 1s ease-in-out infinite;
    }
    @keyframes spin { to { transform: rotate(360deg); } }

    .skeleton {
        background: linear-gradient(90deg,#f0f0f0 25%,#e0e0e0 50%,#f0f0f0 75%);
        background-size: 200% 100%; animation: loading 1.5s infinite;
        border-radius: 14px;
    }
    @keyframes loading {
        0%   { background-position: 200% 0; }
        100% { background-position: -200% 0; }
    }
</style>

<!-- PAGE HEADER -->
<div class="page-header d-flex justify-content-between align-items-center mb-4">
    <div>
        <h1 class="h3 mb-1"><i class="bi bi-bar-chart-fill text-primary"></i> Business Analytics</h1>
        <p class="text-muted small">Ringkasan performa penjualan (Ecer, Reseller, Maklon).</p>
    </div>
    <div class="header-actions d-flex gap-2">
        <select id="periodSelect" class="form-select form-select-sm bg-dark text-light border-secondary" style="width:auto;">
            <option value="7">7 Hari Terakhir</option>
            <option value="30">Bulan Ini</option>
            <option value="90">3 Bulan Terakhir</option>
            <option value="365">Tahun Ini</option>
            <option value="all" selected>Semua Data</option>
        </select>
        <div class="export-dropdown">
            <button id="exportBtn" class="btn btn-sm btn-primary">
                <i class="bi bi-download"></i> Export
            </button>
            <div id="exportMenu" class="export-menu">
                <a id="exportPDF" href="#"><i class="bi bi-file-pdf"></i> Export as PDF</a>
                <a id="exportCSV" href="#"><i class="bi bi-file-earmark-spreadsheet"></i> Export as CSV</a>
            </div>
        </div>
    </div>
</div>

<!-- STAT CARDS -->
<div class="stat-grid" id="statCardsContainer">
    <div class="stat-card skeleton" style="height:140px;"></div>
    <div class="stat-card skeleton" style="height:140px;"></div>
    <div class="stat-card skeleton" style="height:140px;"></div>
    <div class="stat-card skeleton" style="height:140px;"></div>
</div>

<!-- ROW 1: Revenue Chart + Jenis Penjualan Donut -->
<div class="chart-row col-2-side">
    <div class="chart-card">
        <div class="chart-head">
            <i class="bi bi-lightning-charge-fill text-warning"></i>
            <h3>Tren Penjualan Harian</h3>
        </div>
        <div class="chart-body">
            <canvas id="salesChart"></canvas>
        </div>
    </div>
    <div class="chart-card">
        <div class="chart-head">
            <i class="bi bi-pie-chart-fill text-info"></i>
            <h3>Komposisi Jenis Penjualan</h3>
        </div>
        <div class="chart-body">
            <canvas id="jenisChart"></canvas>
        </div>
    </div>
</div>

<!-- ROW 2: Bar Jenis + KPI Bulan Ini vs Lalu -->
<div class="chart-row col-2-side">
    <div class="chart-card">
        <div class="chart-head">
            <i class="bi bi-bar-chart-steps text-success"></i>
            <h3>Revenue per Jenis Penjualan</h3>
        </div>
        <div class="chart-body">
            <canvas id="jenisBarChart"></canvas>
        </div>
    </div>
    <div class="chart-card">
        <div class="chart-head">
            <i class="bi bi-calendar2-check text-warning"></i>
            <h3>Bulan Ini vs Bulan Lalu</h3>
        </div>
        <div class="chart-body d-flex align-items-center justify-content-center flex-column gap-3">
            <div class="text-center">
                <div style="font-size:1.5rem;font-weight:800;color:var(--accent);" id="revBulanIni">Rp 0</div>
                <div style="font-size:.8rem;color:var(--text-muted);margin-top:.3rem;">Bulan Ini</div>
            </div>
            <div style="width:100%;height:1px;background:var(--border-sim);"></div>
            <div class="text-center">
                <div style="font-size:1.3rem;font-weight:700;color:var(--text-muted);" id="revBulanLalu">Rp 0</div>
                <div style="font-size:.8rem;color:var(--text-muted);margin-top:.3rem;">Bulan Lalu</div>
            </div>
            <div style="width:100%;height:1px;background:var(--border-sim);"></div>
            <div class="text-center">
                <div style="font-size:1.6rem;font-weight:800;" id="persentaseBulan">0%</div>
                <div style="font-size:.8rem;color:var(--text-muted);margin-top:.3rem;">Pertumbuhan</div>
            </div>
        </div>
    </div>
</div>

<!-- ROW 3: Top 5 Produk -->
<div class="chart-card mt-2">
    <div class="chart-head">
        <i class="bi bi-award-fill text-primary"></i>
        <h3>Top 5 Produk Terlaris</h3>
    </div>
    <div class="table-responsive">
        <table class="sim-table" id="topProductsTable">
            <thead>
                <tr>
                    <th style="width:50px">#</th>
                    <th>Nama Produk</th>
                    <th>Qty Terjual</th>
                    <th>Pendapatan</th>
                </tr>
            </thead>
            <tbody id="productTableBody">
                <tr>
                    <td colspan="4" class="text-center text-muted py-4">
                        <div class="loading-spinner"></div> Memuat data...
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

<!-- ROW 4: Detail Jenis -->
<div class="chart-card mt-3">
    <div class="chart-head">
        <i class="bi bi-layers text-info"></i>
        <h3>Detail per Jenis Penjualan</h3>
    </div>
    <div class="table-responsive">
        <table class="sim-table">
            <thead>
                <tr>
                    <th>Jenis</th>
                    <th>Transaksi</th>
                    <th>Total Revenue</th>
                </tr>
            </thead>
            <tbody id="jenisDetailBody">
                <tr>
                    <td colspan="3" class="text-center text-muted py-3">
                        <div class="loading-spinner"></div>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
</div>

<?= $this->endSection() ?>

<?= $this->section('js') ?>
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.0/dist/chart.umd.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.4.1/html2canvas.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
<script>
    let analyticsData = null;
    let salesChart    = null;
    let jenisChart    = null;
    let jenisBarChart = null;

    // ── Toast ──────────────────────────────────────────────
    function showToast(msg, type = 'success') {
        const t = document.createElement('div');
        t.className = 'toast-notification' + (type === 'error' ? ' error' : '');
        t.textContent = msg;
        document.body.appendChild(t);
        setTimeout(() => t.remove(), 3000);
    }

    // ── Format IDR ─────────────────────────────────────────
    function formatRp(n) {
        return new Intl.NumberFormat('id-ID', {
            style: 'currency', currency: 'IDR',
            minimumFractionDigits: 0, maximumFractionDigits: 0
        }).format(n);
    }

    // ── Load Data ──────────────────────────────────────────
    function loadAnalyticsData(range = 'all') {
        fetch(`<?= base_url('analytics/data') ?>?range=${range}`, {
            method: 'GET',
            headers: { 'X-Requested-With': 'XMLHttpRequest' }
        })
        .then(r => { if (!r.ok) throw new Error('HTTP ' + r.status); return r.json(); })
        .then(data => {
            if (!data.success) throw new Error(data.error || 'Gagal memuat data');
            analyticsData = data;
            updateStatCards(data);
            updateCharts(data);
            updateProductTable(data);
            updateJenisDetail(data);
            showToast('Data berhasil dimuat');
        })
        .catch(err => {
            console.error(err);
            showToast('Gagal memuat data: ' + err.message, 'error');
        });
    }

    // ── Stat Cards ─────────────────────────────────────────
    function updateStatCards(data) {
        const kpi          = data.kpi || {};
        const totalRevenue = parseFloat(kpi.total_revenue)    || 0;
        const totalQty     = parseInt(kpi.total_qty_terjual)  || 0;
        const totalOrder   = parseInt(kpi.total_order)        || 0;
        const avgOrder     = parseFloat(kpi.avg_order_value)  || 0;

        const revLalu      = parseFloat(data.rev_bulan_lalu)  || 0;
        const revIni       = parseFloat(data.rev_bulan_ini)   || 0;
        const growth       = revLalu > 0 ? ((revIni - revLalu) / revLalu * 100).toFixed(1) : 0;
        const growthClass  = growth >= 0 ? 'change-up' : 'change-down';
        const growthLabel  = (growth >= 0 ? '+' : '') + growth + '%';

        document.getElementById('statCardsContainer').innerHTML = `
            <div class="stat-card">
                <span class="stat-change ${growthClass}">${growthLabel}</span>
                <div class="stat-icon icon-blue"><i class="bi bi-graph-up-arrow"></i></div>
                <div class="stat-value">${formatRp(totalRevenue)}</div>
                <div class="stat-label">Total Revenue</div>
            </div>
            <div class="stat-card">
                <span class="stat-change change-up">+${totalQty.toLocaleString('id-ID')}</span>
                <div class="stat-icon icon-purple"><i class="bi bi-box-seam-fill"></i></div>
                <div class="stat-value">${totalQty.toLocaleString('id-ID')}</div>
                <div class="stat-label">Produk Terjual</div>
            </div>
            <div class="stat-card">
                <span class="stat-change change-neu">${totalOrder}</span>
                <div class="stat-icon icon-yellow"><i class="bi bi-bag-check-fill"></i></div>
                <div class="stat-value">${totalOrder.toLocaleString('id-ID')}</div>
                <div class="stat-label">Total Transaksi</div>
            </div>
            <div class="stat-card">
                <span class="stat-change change-neu">avg</span>
                <div class="stat-icon icon-green"><i class="bi bi-calculator-fill"></i></div>
                <div class="stat-value">${formatRp(avgOrder)}</div>
                <div class="stat-label">Rata-rata per Transaksi</div>
            </div>
        `;
    }

    // ── Charts ─────────────────────────────────────────────
    function updateCharts(data) {
        const COLORS = ['#3b82f6', '#6366f1', '#f59e0b', '#10b981', '#ef4444'];

        // 1. Sales Line Chart
        if (data.revenue_chart && data.revenue_chart.length > 0) {
            const labels   = data.revenue_chart.map(d => new Date(d.tgl).toLocaleDateString('id-ID'));
            const revenues = data.revenue_chart.map(d => parseFloat(d.revenue) / 1e6);

            if (salesChart) salesChart.destroy();
            salesChart = new Chart(document.getElementById('salesChart'), {
                type: 'line',
                data: {
                    labels,
                    datasets: [{
                        label: 'Revenue (Jt)',
                        data: revenues,
                        borderColor: '#3b82f6',
                        backgroundColor: 'rgba(59,130,246,.1)',
                        borderWidth: 3, tension: 0.4, fill: true,
                        pointRadius: 4, pointBackgroundColor: '#3b82f6',
                        pointBorderColor: '#fff', pointBorderWidth: 2
                    }]
                },
                options: {
                    responsive: true, maintainAspectRatio: true,
                    plugins: { legend: { display: false } },
                    scales: {
                        y: { grid: { color: 'rgba(0,0,0,.04)' }, ticks: { color: '#64748b' }, beginAtZero: true },
                        x: { grid: { display: false }, ticks: { color: '#64748b', maxTicksLimit: 10 } }
                    }
                }
            });
        }

        // 2. Jenis Penjualan Donut
        if (data.jenis_breakdown && data.jenis_breakdown.length > 0) {
            const labels = data.jenis_breakdown.map(d => d.jenis);
            const values = data.jenis_breakdown.map(d => parseInt(d.jml_order));

            if (jenisChart) jenisChart.destroy();
            jenisChart = new Chart(document.getElementById('jenisChart'), {
                type: 'doughnut',
                data: {
                    labels,
                    datasets: [{
                        data: values,
                        backgroundColor: COLORS.slice(0, labels.length),
                        borderWidth: 0, hoverOffset: 10
                    }]
                },
                options: {
                    responsive: true, maintainAspectRatio: true,
                    plugins: {
                        legend: {
                            position: 'bottom',
                            labels: { color: '#64748b', font: { size: 11 }, usePointStyle: true, padding: 15 }
                        }
                    },
                    cutout: '68%'
                }
            });
        }

        // 3. Revenue per Jenis Bar Chart
        if (data.jenis_breakdown && data.jenis_breakdown.length > 0) {
            const labels = data.jenis_breakdown.map(d => d.jenis);
            const values = data.jenis_breakdown.map(d => parseFloat(d.revenue) / 1e6);

            if (jenisBarChart) jenisBarChart.destroy();
            jenisBarChart = new Chart(document.getElementById('jenisBarChart'), {
                type: 'bar',
                data: {
                    labels,
                    datasets: [{
                        label: 'Revenue (Jt)',
                        data: values,
                        backgroundColor: COLORS.slice(0, labels.length),
                        borderRadius: 8, borderWidth: 0
                    }]
                },
                options: {
                    indexAxis: 'y',
                    responsive: true, maintainAspectRatio: true,
                    plugins: { legend: { display: false } },
                    scales: {
                        x: { grid: { color: 'rgba(0,0,0,.04)' }, ticks: { color: '#64748b' }, beginAtZero: true },
                        y: { grid: { display: false }, ticks: { color: '#64748b' } }
                    }
                }
            });
        }

        // 4. Bulan Ini vs Bulan Lalu
        const revIni  = parseFloat(data.rev_bulan_ini)  || 0;
        const revLalu = parseFloat(data.rev_bulan_lalu) || 0;
        const growth  = revLalu > 0 ? ((revIni - revLalu) / revLalu * 100).toFixed(1) : 0;

        document.getElementById('revBulanIni').textContent  = formatRp(revIni);
        document.getElementById('revBulanLalu').textContent = formatRp(revLalu);

        const elGrowth = document.getElementById('persentaseBulan');
        elGrowth.textContent = (growth >= 0 ? '+' : '') + growth + '%';
        elGrowth.style.color = growth >= 0 ? '#10b981' : '#ef4444';
    }

    // ── Product Table ──────────────────────────────────────
    function updateProductTable(data) {
        const tbody = document.getElementById('productTableBody');
        if (!data.top_products || data.top_products.length === 0) {
            tbody.innerHTML = '<tr><td colspan="4" class="text-center text-muted py-4">Tidak ada data produk</td></tr>';
            return;
        }
        tbody.innerHTML = data.top_products.map((p, i) => `
            <tr>
                <td><strong>${i + 1}</strong></td>
                <td class="fw-bold">${p.nama_produk || 'N/A'}</td>
                <td>${(p.total_qty || 0).toLocaleString('id-ID')}</td>
                <td class="text-success fw-bold">${formatRp(p.total_revenue || 0)}</td>
            </tr>
        `).join('');
    }

    // ── Jenis Detail Table ─────────────────────────────────
    function updateJenisDetail(data) {
        const tbody = document.getElementById('jenisDetailBody');
        if (!data.jenis_detail || data.jenis_detail.length === 0) {
            tbody.innerHTML = '<tr><td colspan="3" class="text-center text-muted">Tidak ada data</td></tr>';
            return;
        }
        const badgeMap = {
            'Ecer':     'badge-ecer',
            'Reseller': 'badge-reseller',
            'Maklon':   'badge-maklon'
        };
        const iconMap = {
            'Ecer':     '🛒',
            'Reseller': '🤝',
            'Maklon':   '📦'
        };
        tbody.innerHTML = data.jenis_detail.map(j => `
            <tr>
                <td>
                    <span class="badge-sim ${badgeMap[j.jenis] || 'badge-ecer'}">
                        ${iconMap[j.jenis] || ''} ${j.jenis}
                    </span>
                </td>
                <td>${(j.jml_transaksi || 0).toLocaleString('id-ID')}</td>
                <td class="text-success fw-bold">${formatRp(j.total_nilai || 0)}</td>
            </tr>
        `).join('');
    }

    // ── Export Dropdown ────────────────────────────────────
    document.getElementById('exportBtn').addEventListener('click', function(e) {
        e.preventDefault();
        document.getElementById('exportMenu').classList.toggle('show');
    });
    document.addEventListener('click', function(e) {
        if (!document.querySelector('.export-dropdown').contains(e.target))
            document.getElementById('exportMenu').classList.remove('show');
    });

    // ── Export PDF ─────────────────────────────────────────
    document.getElementById('exportPDF').addEventListener('click', function(e) {
        e.preventDefault();
        const btn = document.getElementById('exportBtn');
        btn.innerHTML = '<i class="bi bi-hourglass-split"></i> Generating...';
        btn.disabled  = true;
        document.getElementById('exportMenu').classList.remove('show');

        html2canvas(document.querySelector('.page-header').parentElement, {
            scale: 2, useCORS: true, backgroundColor: '#ffffff', logging: false
        }).then(canvas => {
            const { jsPDF } = window.jspdf;
            const pdf = new jsPDF('p', 'mm', 'a4');
            const pw  = pdf.internal.pageSize.getWidth();
            const ph  = pdf.internal.pageSize.getHeight();
            const ih  = (canvas.height * pw) / canvas.width;
            const img = canvas.toDataURL('image/jpeg', 0.95);

            let left = ih, pos = 0;
            pdf.addImage(img, 'JPEG', 0, pos, pw, ih);
            left -= ph;
            while (left > 0) {
                pos = left - ih; pdf.addPage();
                pdf.addImage(img, 'JPEG', 0, pos, pw, ih);
                left -= ph;
            }
            pdf.save('analytics-' + new Date().toISOString().split('T')[0] + '.pdf');
            showToast('PDF berhasil diunduh!');
        }).catch(err => {
            console.error(err);
            showToast('Gagal membuat PDF.', 'error');
        }).finally(() => {
            btn.innerHTML = '<i class="bi bi-download"></i> Export';
            btn.disabled  = false;
        });
    });

    // ── Export CSV ─────────────────────────────────────────
    document.getElementById('exportCSV').addEventListener('click', function(e) {
        e.preventDefault();
        if (!analyticsData) { showToast('Belum ada data.', 'error'); return; }

        try {
            const csv = [];
            csv.push('BUSINESS ANALYTICS REPORT');
            csv.push('Generated: ' + new Date().toLocaleString('id-ID'));
            csv.push('');

            const kpi = analyticsData.kpi || {};
            csv.push('KPI');
            csv.push('Total Transaksi,Total Revenue,Avg per Transaksi,Total Qty Terjual');
            csv.push(`${kpi.total_order||0},${kpi.total_revenue||0},${parseFloat(kpi.avg_order_value||0).toFixed(0)},${kpi.total_qty_terjual||0}`);
            csv.push('');

            csv.push('TOP PRODUK');
            csv.push('No,Nama Produk,Qty,Revenue');
            (analyticsData.top_products || []).forEach((p, i) =>
                csv.push(`${i+1},"${p.nama_produk||''}",${p.total_qty||0},${p.total_revenue||0}`)
            );
            csv.push('');

            csv.push('JENIS PENJUALAN');
            csv.push('Jenis,Transaksi,Revenue');
            (analyticsData.jenis_detail || []).forEach(j =>
                csv.push(`${j.jenis},${j.jml_transaksi||0},${j.total_nilai||0}`)
            );

            const link = document.createElement('a');
            link.href     = 'data:text/csv;charset=utf-8,' + encodeURIComponent(csv.join('\n'));
            link.download = 'analytics-' + new Date().toISOString().split('T')[0] + '.csv';
            link.click();
            showToast('CSV berhasil diunduh!');
            document.getElementById('exportMenu').classList.remove('show');
        } catch(err) {
            console.error(err);
            showToast('Gagal membuat CSV.', 'error');
        }
    });

    // ── Period Change ──────────────────────────────────────
    document.getElementById('periodSelect').addEventListener('change', function(e) {
        loadAnalyticsData(e.target.value);
    });

    // ── Init ───────────────────────────────────────────────
    document.addEventListener('DOMContentLoaded', () => loadAnalyticsData('all'));
</script>
<?= $this->endSection() ?>