<?php
/**
 * Depto de Engenharia e Automação - Master Automação - Autor: Derlivon Silva
 *
 * Vendas / Por Vendedor — shell instantâneo.
 * - Tabela ranking (endpoint principal) carrega 1º (preserva versão 1.4.2)
 * - Métricas extras + gráficos (endpoint /extras) carregam em paralelo, depois
 */
?>
<div class="pbi-page-header">
    <h1 class="pbi-page-title"><i class="bi bi-person-badge me-2 text-accent"></i>Vendas por Vendedor</h1>
</div>
<?php include __DIR__ . '/_submenu.php' ?>

<?php $actionUrl = '/vendas/por-vendedor'; $mostrarVendedor = false; include __DIR__ . '/_filtro.php'; ?>

<!-- ── KPIs (3 originais + 3 novos) ────────────────────────────────────────── -->
<div class="pbi-kpi-grid mb-4" id="kpi-grid">
    <?php for ($i = 0; $i < 3; $i++): ?>
    <div class="pbi-kpi-card">
        <div class="pbi-kpi-label pbi-skeleton" style="width:60%;height:.8rem;border-radius:4px">&nbsp;</div>
        <div class="pbi-kpi-value pbi-skeleton mt-2" style="width:80%;height:1.6rem;border-radius:4px">&nbsp;</div>
    </div>
    <?php endfor; ?>
</div>
<div class="row g-3 mb-4" id="kpi-extras-row">
    <div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Vendedor #1</div><div class="pbi-kpi-value pbi-skeleton mt-2" style="height:1.4rem;border-radius:4px">&nbsp;</div></div></div>
    <div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Equipe ativa</div><div class="pbi-kpi-value pbi-skeleton mt-2" style="height:1.4rem;border-radius:4px">&nbsp;</div></div></div>
    <div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Gap top1 × último</div><div class="pbi-kpi-value pbi-skeleton mt-2" style="height:1.4rem;border-radius:4px">&nbsp;</div></div></div>
    <div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Evolução vs período anterior</div><div class="pbi-kpi-value pbi-skeleton mt-2" style="height:1.4rem;border-radius:4px">&nbsp;</div></div></div>
</div>
<div class="pbi-hint mb-3" style="margin-top:0"><strong>Ticket Médio</strong> = valor médio por venda (faturamento ÷ nº de notas). <strong>Notas</strong> = quantidade de vendas emitidas. <strong>Gap</strong> = diferença em pontos percentuais (pp) entre o 1º e o último vendedor.</div>

<!-- ── Tabela de Vendedores (endpoint PRINCIPAL — intocado) ─────────────────── -->
<div class="pbi-card" id="card-vendedor">
    <div class="pbi-card-header d-flex justify-content-between">
        <span><i class="bi bi-table me-2"></i>Ranking de Vendedores</span>
        <small class="text-muted" id="vendedor-badge">
            <span class="pbi-skeleton d-inline-block" style="width:80px;height:.75rem;border-radius:3px">&nbsp;</span>
        </small>
    </div>
    <div class="pbi-hint mb-2" style="margin-top:0;padding-left:1rem;padding-right:1rem">Ranking de vendedores no período. <strong>Part.%</strong> = quanto cada vendedor representa do faturamento total.</div>
    <div id="vendedor-body">
        <div class="table-responsive">
            <table class="pbi-table">
                <thead><tr>
                    <th>#</th>
                    <th>Vendedor</th>
                    <th class="text-end">Notas</th>
                    <th class="text-end">Ticket Médio</th>
                    <th class="text-end">Total</th>
                    <th style="width:100px">Part.%</th>
                </tr></thead>
                <tbody>
                <?php for ($i = 0; $i < 6; $i++): ?>
                <tr>
                    <?php foreach ([20,120,45,80,90,60] as $w): ?>
                    <td><span class="pbi-skeleton d-inline-block" style="width:<?= $w ?>px;height:.75rem;border-radius:3px">&nbsp;</span></td>
                    <?php endforeach; ?>
                </tr>
                <?php endfor; ?>
                </tbody>
            </table>
        </div>
    </div>
</div>

<!-- ── Gráficos (endpoint /extras) ─────────────────────────────────────────── -->
<div class="row g-3 mt-1" id="card-graficos">
    <div class="col-12 col-lg-7">
        <div class="pbi-card h-100">
            <div class="pbi-card-header"><i class="bi bi-bar-chart-line me-2"></i>Ranking visual (Top 10)</div>
            <div id="chart-ranking" style="height:380px"></div>
        </div>
    </div>
    <div class="col-12 col-lg-5">
        <div class="pbi-card h-100">
            <div class="pbi-card-header"><i class="bi bi-pie-chart me-2"></i>Participação no faturamento</div>
            <div id="chart-donut" style="height:380px"></div>
        </div>
    </div>
    <div class="col-12">
        <div class="pbi-card">
            <div class="pbi-card-header"><i class="bi bi-graph-up me-2"></i>Evolução diária — Top 5 vendedores</div>
            <div id="chart-evol" style="height:360px"></div>
        </div>
    </div>
    <div class="col-12">
        <div class="pbi-card">
            <div class="pbi-card-header"><i class="bi bi-calendar-week me-2"></i>Heatmap dia-da-semana × vendedor</div>
            <div class="pbi-hint" style="padding-left:1rem;padding-right:1rem;margin-top:0">Intensidade da cor = faturamento naquele dia da semana ao longo do período.</div>
            <div id="chart-heatmap" style="height:380px"></div>
        </div>
    </div>
</div>

<!-- ── Tabela aprofundada (clientes, dias ativos, devoluções) ──────────────── -->
<div class="pbi-card mt-3" id="card-aprofundado">
    <div class="pbi-card-header"><i class="bi bi-zoom-in me-2"></i>Detalhamento por vendedor (Top 10)</div>
    <div class="pbi-hint" style="padding-left:1rem;padding-right:1rem;margin-top:0">
        <strong>Clientes</strong>: clientes distintos atendidos no período. <strong>Dias ativos</strong>: dias com pelo menos 1 venda. <strong>Devol.</strong>: notas canceladas no período.
    </div>
    <div id="aprofundado-body">
        <div class="px-3 py-4 text-center text-muted"><span class="spinner-border spinner-border-sm me-2"></span>Carregando detalhes…</div>
    </div>
</div>

<script src="/assets/js/echarts.min.js?v=<?= \App\Core\Versao::ATUAL ?>"></script>
<script>
window.__VENDAS = {
    dataIni: <?= json_encode($filtros['data_ini']) ?>,
    dataFim: <?= json_encode($filtros['data_fim']) ?>,
    actionUrl: <?= json_encode($actionUrl) ?>
};
</script>

<style>
@keyframes pbi-pulse { 0%,100%{opacity:1} 50%{opacity:.4} }
.pbi-skeleton { background:var(--pbi-border,#e2e8f0); animation:pbi-pulse 1.4s ease-in-out infinite; pointer-events:none; color:transparent!important; }
.pbi-kpi-mini-sub { font-size:.78rem; color:var(--pbi-muted, #64748b); margin-top:.15rem; font-weight:500; }
.pbi-kpi-mini-val { font-size:1.2rem; font-weight:700; line-height:1.2; word-break:break-word; }
.pbi-kpi-mini-val.pos { color:#16a34a }
.pbi-kpi-mini-val.neg { color:#dc2626 }
</style>

<script>
(function () {
'use strict';

var ini = window.__VENDAS.dataIni;
var fim = window.__VENDAS.dataFim;
var qs  = '?data_ini=' + encodeURIComponent(ini) + '&data_fim=' + encodeURIComponent(fim);

function fmtR(v) { return 'R$ ' + parseFloat(v||0).toLocaleString('pt-BR',{minimumFractionDigits:2,maximumFractionDigits:2}); }
function fmtRk(v) { var n=parseFloat(v||0); if(Math.abs(n)>=1000) return 'R$ '+(n/1000).toLocaleString('pt-BR',{minimumFractionDigits:1,maximumFractionDigits:1})+'k'; return fmtR(n); }
function fmtN(v,d) { d=d===undefined?0:d; return parseFloat(v||0).toLocaleString('pt-BR',{minimumFractionDigits:d,maximumFractionDigits:d}); }
function fmtPct(v,d) { d=d===undefined?1:d; return fmtN(v,d)+'%'; }
function fmtDataBr(s){ if(!s) return '—'; var p=String(s).substring(0,10).split('-'); return p.length===3?p[2]+'/'+p[1]+'/'+p[0]:s; }
function esc(s) { var d=document.createElement('div'); d.textContent=s==null?'':String(s); return d.innerHTML; }
function apiFetch(url) {
    return fetch(url,{credentials:'same-origin'})
        .then(function(r){if(!r.ok) return r.json().then(function(e){throw new Error(e.erro||'HTTP '+r.status);}); return r.json();});
}
function showErr(elId, msg) {
    var el=document.getElementById(elId);
    if(el) el.innerHTML='<div class="px-3 py-3 alert alert-warning small"><i class="bi bi-exclamation-triangle me-2"></i>'+esc(msg)+'</div>';
}
function atualizarAnosAbas(anos) {
    var container = document.querySelector('.pbi-periodo-tabs');
    if (!container) return;
    var actionUrl = window.__VENDAS.actionUrl;
    var anoAtual  = parseInt(ini.substring(0,4));
    var hoje      = pbiHoje();
    var html = anos.map(function(a){
        a=parseInt(a);
        var cls=(a===anoAtual)?' active':'';
        return '<a href="'+actionUrl+'?data_ini='+a+'-01-01&data_fim='+a+'-12-31" class="pbi-tab-ano'+cls+'" onclick="setPeriodoSession('+a+',0)">'+a+'</a>';
    }).join('');
    var hojeBtn='<a href="'+actionUrl+'?data_ini='+hoje+'&data_fim='+hoje+'" class="pbi-tab-ano"><i class="bi bi-broadcast me-1"></i>Hoje</a>';
    container.innerHTML = hojeBtn + html;
}

/* ── KPIs originais (3) ─────────────────────────────────────────────────── */
function renderKpis(linhas) {
    var totFat=0, totQtd=0;
    linhas.forEach(function(l){ totFat+=parseFloat(l.TOTAL||0); totQtd+=parseInt(l.QTD_NOTAS||0); });
    var ticket=totQtd>0?totFat/totQtd:0;
    var defs=[
        {label:'Faturamento Total', val:fmtR(totFat), cls:'text-accent'},
        {label:'Total de Notas',    val:fmtN(totQtd,0), cls:''},
        {label:'Ticket Médio',      val:fmtR(ticket), cls:''},
    ];
    document.getElementById('kpi-grid').innerHTML = defs.map(function(d){
        return '<div class="pbi-kpi-card"><div class="pbi-kpi-label">'+d.label+'</div>'
             + '<div class="pbi-kpi-value '+d.cls+'">'+d.val+'</div></div>';
    }).join('');
}

/* ── KPIs extras (4) ────────────────────────────────────────────────────── */
function renderKpisExtras(m) {
    if (!m) { document.getElementById('kpi-extras-row').classList.add('d-none'); return; }
    var top1 = m.top1 || {};
    var top1Html = '<div class="pbi-kpi-mini-val text-accent">'+esc(top1.nome||'—')+'</div>'
                 + '<div class="pbi-kpi-mini-sub">'+fmtR(top1.total||0)+' · '+fmtPct(top1.pct||0)+' do total</div>';

    var equipeHtml = '<div class="pbi-kpi-mini-val">'+fmtN(m.equipe||0,0)+' vendedor(es)</div>'
                   + '<div class="pbi-kpi-mini-sub">com vendas no período</div>';

    var gapHtml = '<div class="pbi-kpi-mini-val">'+fmtPct(m.gap_pp||0)+'</div>'
                + '<div class="pbi-kpi-mini-sub">diferença de participação</div>';

    var evol = m.evol_pct;
    var evolHtml;
    if (evol === null || evol === undefined) {
        evolHtml = '<div class="pbi-kpi-mini-val">—</div><div class="pbi-kpi-mini-sub">sem período anterior</div>';
    } else {
        var cls = evol>=0?'pos':'neg';
        var ico = evol>=0?'arrow-up-right':'arrow-down-right';
        evolHtml = '<div class="pbi-kpi-mini-val '+cls+'"><i class="bi bi-'+ico+' me-1"></i>'+(evol>=0?'+':'')+fmtPct(evol)+'</div>'
                 + '<div class="pbi-kpi-mini-sub">vs '+fmtDataBr(m.ini_ant)+'–'+fmtDataBr(m.fim_ant)+'</div>';
    }

    var row = document.getElementById('kpi-extras-row');
    row.innerHTML =
        '<div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Vendedor #1</div>'+top1Html+'</div></div>'
        + '<div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Equipe ativa</div>'+equipeHtml+'</div></div>'
        + '<div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Gap top1 × último</div>'+gapHtml+'</div></div>'
        + '<div class="col-12 col-md-6 col-lg-3"><div class="pbi-kpi-card h-100"><div class="pbi-kpi-label">Evolução vs período anterior</div>'+evolHtml+'</div></div>';
}

/* ── Tabela ranking (intocada) ──────────────────────────────────────────── */
function renderVendedor(linhas) {
    document.getElementById('vendedor-badge').textContent = linhas.length + ' vendedor(es)';
    if (!linhas.length) {
        document.getElementById('vendedor-body').innerHTML =
            '<div class="pbi-card-body text-center text-muted py-5"><i class="bi bi-inbox fs-2"></i><p class="mt-2">Nenhum dado.</p></div>';
        return;
    }
    var totFat = linhas.reduce(function(s,l){return s+parseFloat(l.TOTAL||0);},0);
    var totQtd = linhas.reduce(function(s,l){return s+parseInt(l.QTD_NOTAS||0);},0);
    var rows = linhas.map(function(l, i){
        var pct = totFat>0 ? parseFloat(l.TOTAL||0)/totFat*100 : 0;
        var barW = Math.min(100, Math.round(pct*10)/10);
        return '<tr>'
            +'<td class="text-muted">'+(i+1)+'</td>'
            +'<td class="fw-semibold">'+esc(l.VENDEDOR||'—')+'</td>'
            +'<td class="text-end text-muted">'+fmtN(l.QTD_NOTAS,0)+'</td>'
            +'<td class="text-end">'+fmtR(l.TICKET_MEDIO)+'</td>'
            +'<td class="text-end fw-semibold text-accent">'+fmtR(l.TOTAL)+'</td>'
            +'<td><div class="pbi-progress"><div class="pbi-progress-bar" style="width:'+barW+'%"></div></div>'
            +'<small class="text-muted">'+fmtN(pct,1)+'%</small></td>'
            +'</tr>';
    }).join('');
    document.getElementById('vendedor-body').innerHTML =
        '<div class="table-responsive"><table class="pbi-table">'
        +'<thead><tr><th>#</th><th>Vendedor</th><th class="text-end">Notas</th>'
        +'<th class="text-end">Ticket Médio</th><th class="text-end">Total</th><th style="width:100px">Part.%</th></tr></thead>'
        +'<tbody>'+rows+'</tbody>'
        +'<tfoot><tr class="pbi-table-total"><td colspan="2"><strong>Total</strong></td>'
        +'<td class="text-end"><strong>'+fmtN(totQtd,0)+'</strong></td><td></td>'
        +'<td class="text-end text-accent"><strong>'+fmtR(totFat)+'</strong></td><td></td></tr></tfoot>'
        +'</table></div>';
}

/* ── Gráficos ──────────────────────────────────────────────────────────── */
var chartRanking=null, chartDonut=null, chartEvol=null, chartHeat=null;
function corPaleta() {
    var v = getComputedStyle(document.documentElement).getPropertyValue('--pbi-accent').trim();
    return v || '#3b82f6';
}
function paletaSerie() { return ['#3b82f6','#10b981','#f59e0b','#ec4899','#8b5cf6','#06b6d4','#ef4444','#14b8a6','#f97316','#6366f1']; }

function desenharRanking(linhas) {
    var el = document.getElementById('chart-ranking');
    if (!el || !window.echarts) return;
    var top = linhas.slice(0, 10).reverse(); // ECharts inverte (de baixo pra cima)
    var nomes  = top.map(function(l){return l.VENDEDOR;});
    var vals   = top.map(function(l){return parseFloat(l.TOTAL||0);});
    var cor    = corPaleta();
    chartRanking && chartRanking.dispose();
    chartRanking = echarts.init(el);
    chartRanking.setOption({
        grid: {left: 130, right: 40, top: 20, bottom: 30, containLabel: false},
        tooltip: {trigger:'axis', axisPointer:{type:'shadow'}, valueFormatter: fmtR},
        xAxis: {type:'value', axisLabel:{formatter: fmtRk}},
        yAxis: {type:'category', data:nomes, axisLabel:{interval:0, width:120, overflow:'truncate'}},
        series: [{type:'bar', data:vals, itemStyle:{color:cor, borderRadius:[0,6,6,0]}, label:{show:true, position:'right', formatter: function(p){return fmtRk(p.value);}, fontSize:11}}]
    });
}

function desenharDonut(linhas) {
    var el = document.getElementById('chart-donut');
    if (!el || !window.echarts) return;
    // mostra top 7 + "Outros"
    var ordenado = linhas.slice().sort(function(a,b){return parseFloat(b.TOTAL||0)-parseFloat(a.TOTAL||0);});
    var top7 = ordenado.slice(0,7);
    var outros = ordenado.slice(7).reduce(function(s,l){return s+parseFloat(l.TOTAL||0);},0);
    var data = top7.map(function(l){return {name:l.VENDEDOR, value:parseFloat(l.TOTAL||0)};});
    if (outros > 0) data.push({name:'Outros', value:outros, itemStyle:{color:'#94a3b8'}});

    chartDonut && chartDonut.dispose();
    chartDonut = echarts.init(el);
    chartDonut.setOption({
        tooltip: {trigger:'item', formatter: function(p){return p.name+'<br/>'+fmtR(p.value)+' ('+fmtPct(p.percent)+')';}},
        legend: {bottom:0, left:'center', type:'scroll'},
        color: paletaSerie(),
        series: [{
            type:'pie', radius:['45%','72%'], center:['50%','45%'],
            avoidLabelOverlap: true,
            label:{formatter:'{b}\n{d}%', fontSize:11},
            labelLine:{length:8, length2:8},
            data: data
        }]
    });
}

function desenharEvolucao(ev) {
    var el = document.getElementById('chart-evol');
    if (!el || !window.echarts) return;
    if (!ev || !ev.datas || !ev.datas.length || !ev.series.length) {
        el.innerHTML = '<div class="text-center text-muted py-5">Sem dados de evolução temporal pra esse período.</div>';
        return;
    }
    var datasBr = ev.datas.map(function(d){var p=d.split('-');return p[2]+'/'+p[1];});
    var paleta  = paletaSerie();
    var series  = ev.series.map(function(s,i){
        return {name:s.nome, type:'line', smooth:true, symbol:'circle', symbolSize:6,
                lineStyle:{width:2.5, color:paleta[i%paleta.length]},
                itemStyle:{color:paleta[i%paleta.length]},
                data:s.valores};
    });
    chartEvol && chartEvol.dispose();
    chartEvol = echarts.init(el);
    chartEvol.setOption({
        grid: {left:60, right:30, top:50, bottom:60, containLabel:true},
        tooltip: {trigger:'axis', valueFormatter:fmtR},
        legend: {top:0, type:'scroll'},
        xAxis: {type:'category', data:datasBr, boundaryGap:false, axisLabel:{rotate:0}},
        yAxis: {type:'value', axisLabel:{formatter:fmtRk}},
        series: series
    });
}

function desenharHeatmap(h) {
    var el = document.getElementById('chart-heatmap');
    if (!el || !window.echarts) return;
    if (!h || !h.vendedores || !h.vendedores.length || !h.matriz.length) {
        el.innerHTML = '<div class="text-center text-muted py-5">Sem dados pra heatmap.</div>';
        return;
    }
    var dias  = ['Domingo','Segunda','Terça','Quarta','Quinta','Sexta','Sábado'];
    var nomes = h.vendedores;
    var data = [];
    var maxV = 0;
    h.matriz.forEach(function(linha, iv){
        linha.forEach(function(v, id){
            data.push([id, iv, v]);
            if (v > maxV) maxV = v;
        });
    });
    chartHeat && chartHeat.dispose();
    chartHeat = echarts.init(el);
    chartHeat.setOption({
        grid:{left:150, right:60, top:30, bottom:60, containLabel:false},
        tooltip:{position:'top', formatter:function(p){return nomes[p.value[1]]+' · '+dias[p.value[0]]+'<br/>'+fmtR(p.value[2]);}},
        xAxis:{type:'category', data:dias, splitArea:{show:true}, axisLabel:{rotate:0}},
        yAxis:{type:'category', data:nomes, splitArea:{show:true}, axisLabel:{width:140, overflow:'truncate', fontSize:11}},
        visualMap:{min:0, max:maxV||1, calculable:true, orient:'horizontal', left:'center', bottom:5,
                   inRange:{color:['#f1f5f9','#bfdbfe','#3b82f6','#1d4ed8','#1e3a8a']}, textStyle:{fontSize:11}},
        series:[{name:'Faturamento', type:'heatmap', data:data,
                 label:{show:false},
                 emphasis:{itemStyle:{shadowBlur:10, shadowColor:'rgba(0,0,0,.4)'}}}]
    });
}

/* ── Tabela aprofundada ─────────────────────────────────────────────────── */
function renderAprofundado(linhas) {
    var body = document.getElementById('aprofundado-body');
    if (!linhas || !linhas.length) {
        body.innerHTML = '<div class="px-3 py-4 text-center text-muted">Sem dados aprofundados pra esse período.</div>';
        return;
    }
    var rows = linhas.map(function(l, i){
        var devolHtml = l.qtd_canc > 0
            ? '<span class="text-danger">'+fmtN(l.qtd_canc,0)+' · '+fmtRk(l.valor_canc)+'</span>'
            : '<span class="text-muted">—</span>';
        return '<tr>'
            +'<td class="text-muted">'+(i+1)+'</td>'
            +'<td class="fw-semibold">'+esc(l.nome||'—')+'</td>'
            +'<td class="text-end text-muted">'+fmtN(l.qtd_notas,0)+'</td>'
            +'<td class="text-end fw-semibold text-accent">'+fmtR(l.total)+'</td>'
            +'<td class="text-end">'+fmtR(l.ticket)+'</td>'
            +'<td class="text-end">'+fmtN(l.clientes,0)+'</td>'
            +'<td class="text-end">'+fmtN(l.dias_ativos,0)+'</td>'
            +'<td class="text-center">'+fmtDataBr(l.primeira)+'</td>'
            +'<td class="text-center">'+fmtDataBr(l.ultima)+'</td>'
            +'<td class="text-end">'+devolHtml+'</td>'
            +'</tr>';
    }).join('');
    body.innerHTML =
        '<div class="table-responsive"><table class="pbi-table">'
        +'<thead><tr><th>#</th><th>Vendedor</th><th class="text-end">Notas</th><th class="text-end">Total</th>'
        +'<th class="text-end">Ticket</th><th class="text-end">Clientes</th><th class="text-end">Dias ativos</th>'
        +'<th class="text-center">Primeira</th><th class="text-center">Última</th><th class="text-end">Devol.</th>'
        +'</tr></thead>'
        +'<tbody>'+rows+'</tbody></table></div>';
}

/* ── Boot ───────────────────────────────────────────────────────────────── */
window.addEventListener('DOMContentLoaded', function () {
    // 1) Endpoint PRINCIPAL (intocado) — ranking
    apiFetch('/api/vendas/por-vendedor' + qs)
        .then(function(d) {
            var linhas = d.linhas || [];
            renderKpis(linhas);
            renderVendedor(linhas);
            if (d.anos && d.anos.length) atualizarAnosAbas(d.anos);
            // gráficos que dependem só de "linhas"
            desenharRanking(linhas);
            desenharDonut(linhas);
        })
        .catch(function(e) {
            showErr('kpi-grid', 'Erro ao carregar dados: ' + e.message);
            showErr('vendedor-body', 'Erro: ' + e.message);
        });

    // 2) Endpoint EXTRAS (em paralelo, falha silenciosa não derruba página)
    apiFetch('/api/vendas/por-vendedor/extras' + qs)
        .then(function(d) {
            renderKpisExtras(d.metricas);
            desenharEvolucao(d.evolucao);
            desenharHeatmap(d.dia_semana);
            renderAprofundado(d.aprofundado);
        })
        .catch(function(e) {
            console.warn('Extras falhou:', e.message);
            document.getElementById('kpi-extras-row').innerHTML =
                '<div class="col-12"><div class="alert alert-warning small mb-0">Não foi possível carregar os indicadores extras: '+esc(e.message)+'</div></div>';
            ['chart-ranking','chart-donut','chart-evol','chart-heatmap'].forEach(function(id){
                var el=document.getElementById(id); if(el) el.innerHTML='<div class="text-center text-muted py-5">Indisponível.</div>';
            });
        });

    // Redimensiona gráficos quando janela muda
    window.addEventListener('resize', function(){
        if (chartRanking) chartRanking.resize();
        if (chartDonut)   chartDonut.resize();
        if (chartEvol)    chartEvol.resize();
        if (chartHeat)    chartHeat.resize();
    });
});

})();
</script>
