<?php

require_once(dirname(__DIR__) . '/config/db.php');
require_once __DIR__ . '/home_service.php';
require_once __DIR__ . '/home_consolidado_helper.php';
require_once(dirname(__DIR__) . '/views/card.php');
require_once(dirname(__DIR__) . '/lib/SimpleCache.php');

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

// ============================
// LIMPAR FILTROS (se parâmetro limpar_filtros=1)
// ============================
if (isset($_GET['limpar_filtros']) && (string)$_GET['limpar_filtros'] === '1') {
    $_SESSION['filtros_dashboard'] = [];
    // Redirecionar para home limpo
    header('Location: ?');
    exit;
}

// ============================
// FILTROS GLOBAIS
// ============================
$cdpessoa = (int)($_SESSION['usuario']['id'] ?? $_SESSION['cdpessoa'] ?? 0);
$cdempresaSessao = (int)($_SESSION['cdempresa'] ?? 0);

// Inicializar filtros na SESSION se não existirem
if (!isset($_SESSION['filtros_dashboard'])) {
    $_SESSION['filtros_dashboard'] = [];
}

// Guardar país anterior (para detectar quando o usuário mudou o país explicitamente)
$cdpaisAnteriorSessao = (int)($_SESSION['filtros_dashboard']['cdpais'] ?? 0);

// ============================
// VERIFICAR SE FILTROS FORAM APLICADOS (GET params presentes)
// ============================
$filtrosAplicados = isset($_GET['ano']) || isset($_GET['cdpais']) || isset($_GET['cdempresa']) || 
                    isset($_GET['cdcentrocusto']) || isset($_GET['trimestre']) || isset($_GET['mes']) || isset($_GET['cdmoeda']);

// ============================
// VISÃO DO DASHBOARD
// - default: por variável
// - auto: ao consolidar (multi-empresa) e se o usuário não tiver escolhido explicitamente
// ============================
function urlComVisaoDashboard(string $visao): string {
    $params = $_GET;
    $params['visao'] = $visao;
    $qs = http_build_query($params);
    return $qs ? ('?' . $qs) : '?';
}

$visoesPermitidas = ['variavel', 'modelo'];
$visaoParam = isset($_GET['visao']) ? strtolower(trim((string)$_GET['visao'])) : null;
if ($visaoParam && in_array($visaoParam, $visoesPermitidas, true)) {
    $_SESSION['dashboard_visao'] = $visaoParam;
    $_SESSION['dashboard_visao_explicit'] = true;
}

$visaoDashboard = (string)($_SESSION['dashboard_visao'] ?? 'variavel');
if (!in_array($visaoDashboard, $visoesPermitidas, true)) {
    $visaoDashboard = 'variavel';
}

// Obter filtros da requisição (GET parameters) ou da SESSION
$empresasFiltro = obterEmpresasPessoa($pdo, $cdpessoa);

// ============================
// FILTRO DE MOEDA
// ============================
$moedasFiltro = obterMoedasAtivas($pdo);

// Moeda padrão: moeda da empresa ativa (logada)
$cdmoedaSessao = 0;
if ($cdempresaSessao > 0) {
    try {
        $stMoeda = $pdo->prepare('SELECT cdmoeda FROM back.empresa WHERE cdempresa = :emp LIMIT 1');
        $stMoeda->execute([':emp' => $cdempresaSessao]);
        $cdmoedaSessao = (int)($stMoeda->fetchColumn() ?: 0);
    } catch (Throwable $e) {
        $cdmoedaSessao = 0;
    }
}

$cdmoedaFiltro = (int)($filtrosAplicados && isset($_GET['cdmoeda']) ? $_GET['cdmoeda'] : ($_SESSION['filtros_dashboard']['cdmoeda'] ?? $cdmoedaSessao));

// Validar moeda selecionada
$moedasAcessiveis = array_map(fn($m) => (int)$m['cdmoeda'], $moedasFiltro);
if ($cdmoedaFiltro > 0 && !in_array($cdmoedaFiltro, $moedasAcessiveis, true)) {
    $cdmoedaFiltro = $cdmoedaSessao;
}

// Multi-select de empresas (por padrão, NENHUMA SELECIONADA)
// IMPORTANTE: GET['cdempresa[]'] vem como array quando múltiplos valores via URL
// 1. Se GET tem cdempresa[] (array) → usar GET
// 2. Senão, se SESSION tem cdempresa → usar SESSION
// 3. Senão → usar array vazio []
$empresasSelecionadas = [];

if (isset($_GET['cdempresa'])) {
    // GET com cdempresa[] vem como array do JavaScript/form
    $empresasSelecionadas = $_GET['cdempresa'];
} elseif (isset($_SESSION['filtros_dashboard']['cdempresa']) && !empty($_SESSION['filtros_dashboard']['cdempresa'])) {
    // Se GET não tem, mas SESSION tem → usar SESSION
    $empresasSelecionadas = $_SESSION['filtros_dashboard']['cdempresa'];
}

// Garantir que é um array (pode vir como string se vazio ou único valor)
if (!is_array($empresasSelecionadas)) {
    $empresasSelecionadas = !empty($empresasSelecionadas) ? [$empresasSelecionadas] : [];
}

error_log("[FILTROS-ARRAY] Após garantir array: " . json_encode($empresasSelecionadas), 0);

// Converter para inteiros e remover vazios e duplicatas
$empresasSelecionadas = array_unique(array_map('intval', array_filter($empresasSelecionadas, function($v) {
    return !empty($v) && (int)$v > 0;
})));

error_log("[FILTROS-INTEIROS] Após filtrar inteiros: " . json_encode($empresasSelecionadas), 0);

// ====== NOTA: Validação de empresas acessíveis será feita DEPOIS de filtrar por país ======

// Obter todos os centros de custo (não filtrados por empresa)
$centrosCustoFiltro = obterCentrosCusto($pdo);
$cdcentrocustoFiltro = (int)($filtrosAplicados && isset($_GET['cdcentrocusto']) ? $_GET['cdcentrocusto'] : ($_SESSION['filtros_dashboard']['cdcentrocusto'] ?? 0));

// Filtro de ano (consolidando anos dos exercícios) - PADRÃO PARA ANO CORRENTE
$anosFiltro = obterExercicios($pdo);
$anoFiltro = (int)($filtrosAplicados && isset($_GET['ano']) ? $_GET['ano'] : ($_SESSION['filtros_dashboard']['ano'] ?? date('Y')));

// Se ano não encontrado nos exercícios, usar ano corrente
if (!array_filter($anosFiltro, fn($a) => (int)$a['anoref'] === $anoFiltro)) {
    $anoFiltro = (int)date('Y');
}

// Filtro de mês (1-12) - MULTI-SELEÇÃO
// Aceita GET mes[] (array) ou mes (string única). Se vazio, usa SESSION; se ainda vazio, mês corrente.
$mesesSelecionados = [];
if (isset($_GET['mes'])) {
    $mesesSelecionados = $_GET['mes'];
} elseif (isset($_SESSION['filtros_dashboard']['mes']) && !empty($_SESSION['filtros_dashboard']['mes'])) {
    $mesesSelecionados = $_SESSION['filtros_dashboard']['mes'];
}
if (!is_array($mesesSelecionados)) {
    $mesesSelecionados = !empty($mesesSelecionados) ? [$mesesSelecionados] : [];
}
$mesesSelecionados = array_unique(array_map('intval', array_filter($mesesSelecionados, function ($v) {
    $iv = (int)$v;
    return $iv >= 1 && $iv <= 12;
})));
sort($mesesSelecionados);
if (empty($mesesSelecionados)) {
    $mesesSelecionados = [(int)date('n')];
}

$trimestresFiltro = obterTrimestres();
$trimestreFiltro = (int)($filtrosAplicados && isset($_GET['trimestre']) ? $_GET['trimestre'] : ($_SESSION['filtros_dashboard']['trimestre'] ?? 0));
// Default: 0 = Todos (sem filtrar por trimestre)
if ($trimestreFiltro < 0 || $trimestreFiltro > 4) {
    $trimestreFiltro = 0;
}

// Filtro de país (países das empresas que o usuário tem acesso)
$paisesFiltro = obterPaisesAcessiveis($pdo, $cdpessoa);
$cdpaisFiltro = (int)($filtrosAplicados && isset($_GET['cdpais']) ? $_GET['cdpais'] : ($_SESSION['filtros_dashboard']['cdpais'] ?? 0));

// Validar se país selecionado está acessível
$paisesAcessiveis = array_map(fn($p) => (int)$p['cdpais'], $paisesFiltro);
if ($cdpaisFiltro > 0 && !in_array($cdpaisFiltro, $paisesAcessiveis)) {
    $cdpaisFiltro = 0;
}

// SE há filtro de país, filtrar as empresas para apenas aquelas do país selecionado
if ($cdpaisFiltro > 0) {
    $empresasFiltro = array_filter($empresasFiltro, fn($emp) => (int)($emp['cdpais'] ?? 0) === $cdpaisFiltro);
    error_log("[FILTROS-PAÍS] Filtrando empresas pelo país: cdpais=" . $cdpaisFiltro . " | empresas restantes: " . json_encode(array_map(fn($e) => (int)$e['cdempresa'], $empresasFiltro)), 0);
}

// SE há filtro de moeda, filtrar as empresas para apenas aquelas da moeda selecionada
if ($cdmoedaFiltro > 0) {
    $empresasFiltro = array_filter($empresasFiltro, fn($emp) => (int)($emp['cdmoeda'] ?? 0) === $cdmoedaFiltro);
    error_log("[FILTROS-MOEDA] Filtrando empresas pela moeda: cdmoeda=" . $cdmoedaFiltro . " | empresas restantes: " . json_encode(array_map(fn($e) => (int)$e['cdempresa'], $empresasFiltro)), 0);
}

// AGORA: Validar se todas as empresas selecionadas estão acessíveis (APÓS filtro de país)
$empresasAcessiveis = array_map(fn($e) => (int)$e['cdempresa'], $empresasFiltro);
$empresasSelecionadas = array_intersect($empresasSelecionadas, $empresasAcessiveis);

// Se o usuário interagiu explicitamente com o filtro de país (mesmo escolhendo o mesmo valor),
// OU se mudou o país em relação ao anterior, marcar automaticamente TODAS as empresas do filtro atual.
// Isso garante o comportamento desejado ao escolher "Todos" já no primeiro carregamento.
$paisExplicit = isset($_GET['pais_explicit']) && (string)$_GET['pais_explicit'] === '1';
if (array_key_exists('cdpais', $_GET) && ($paisExplicit || $cdpaisFiltro !== $cdpaisAnteriorSessao)) {
    $empresasSelecionadas = $empresasAcessiveis;
}

// Se a seleção ficou vazia, definir um padrão coerente:
// - Se há filtro de país: usar TODAS as empresas restantes (do país)
// - Caso contrário: usar a empresa ativa da sessão como padrão (primeira carga / sem seleção explícita)
if (empty($empresasSelecionadas)) {
    if ($cdpaisFiltro > 0) {
        $empresasSelecionadas = $empresasAcessiveis;
    } elseif ($cdempresaSessao > 0 && in_array($cdempresaSessao, $empresasAcessiveis, true)) {
        $empresasSelecionadas = [$cdempresaSessao];
    } else {
        $empresasSelecionadas = [];
    }
}

// ============================
// SALVAR FILTROS NA SESSION IMEDIATAMENTE
// (ANTES de verificar/usar cache)
// ============================
// Garantir que empresas selecionadas é sempre um array
$empresasSelecionadasSessao = is_array($empresasSelecionadas) ? $empresasSelecionadas : [];
$_SESSION['filtros_dashboard']['cdempresa'] = $empresasSelecionadasSessao;
$_SESSION['filtros_dashboard']['cdcentrocusto'] = $cdcentrocustoFiltro;
$_SESSION['filtros_dashboard']['ano'] = $anoFiltro;
$_SESSION['filtros_dashboard']['trimestre'] = $trimestreFiltro;
$_SESSION['filtros_dashboard']['mes'] = $mesesSelecionados;
$_SESSION['filtros_dashboard']['cdpais'] = $cdpaisFiltro;
$_SESSION['filtros_dashboard']['cdmoeda'] = $cdmoedaFiltro;

// DEBUG: Mostrar estado dos filtros no erro_log
error_log("[FILTROS] filtrosAplicados=" . ($filtrosAplicados ? 'SIM' : 'NÃO') . 
    " | GET[cdempresa]=" . json_encode($_GET['cdempresa'] ?? null) . 
    " | empresasSelecionadas (PRÉ-VALIDAÇÃO)=" . json_encode($empresasSelecionadas) . 
    " | SESSION[cdempresa]=" . json_encode($_SESSION['filtros_dashboard']['cdempresa'] ?? null), 0);

// DEBUG: Log após validação
error_log("[FILTROS-VALIDAÇÃO] empresasSelecionadas (PÓS)=" . json_encode($empresasSelecionadas) . 
    " | empresasAcessiveis=" . json_encode($empresasAcessiveis) . 
    " | count(empresasSelecionadas)=" . count($empresasSelecionadas), 0);

// ============================
// OTIMIZADO: Cache pesado do dashboard (principal)
// ⚠️ CACHE DESABILITADO - Sempre recalcula para garantir filtros corretos
// Usar empresa selecionada ou empresa da sessão para cache key
$empresaForCache = !empty($empresasSelecionadas) ? reset($empresasSelecionadas) : $cdempresaSessao;
$empresasHashCache = !empty($empresasSelecionadas) ? md5(implode(',', $empresasSelecionadas)) : 'none';
$mesesHashCache = !empty($mesesSelecionados) ? md5(implode(',', $mesesSelecionados)) : 'none';
$cacheKeyHeavy = "dashboard_heavy_{$empresasHashCache}_{$cdcentrocustoFiltro}_{$anoFiltro}_{$trimestreFiltro}_{$mesesHashCache}_{$cdpaisFiltro}_v3";
$isWarm = isset($_GET['warm']) && (string)$_GET['warm'] === '1';

// ⚠️ CACHE DESABILITADO - Forçar sempre null para recalcular
$dados = null;

if ($dados === null || !is_array($dados) || !($dados['ok'] ?? false)) {
    // Usar empresa selecionada para cálculos, mas empresa da sessão para exibição
    $empresaParaDados = !empty($empresasSelecionadas) ? $empresasSelecionadas : [$cdempresaSessao];

    // Se a empresa da sessão não estiver na seleção (ex: filtro de moeda/país),
    // usar a primeira empresa selecionada para exibição/moeda, evitando inconsistência.
    $cdempresaExibicao = $cdempresaSessao;
    if (!empty($empresaParaDados) && $cdempresaExibicao > 0 && !in_array($cdempresaExibicao, $empresaParaDados, true)) {
        $cdempresaExibicao = (int)$empresaParaDados[0];
    }
    
    // DEBUG: Log das empresas que serão usadas
    error_log("[DEBUG FILTROS] Chamando obterDadosDashboard com empresas: " . json_encode($empresaParaDados) . ", $filtrosAplicados=" . ($filtrosAplicados ? 'SIM' : 'NÃO'), 0);
    
    $dados = obterDadosDashboard($pdo, 0, $cdcentrocustoFiltro, $anoFiltro, $trimestreFiltro, $mesesSelecionados, $empresaParaDados, $cdempresaExibicao, $cdpaisFiltro);
    // ⚠️ CACHE DESABILITADO - Não salva em cache
    // if ($dados['ok'] ?? false) {
    //     SimpleCache::set($cacheKeyHeavy, $dados, 30);
    // }
}

if (!($dados['ok'] ?? false)) {
    $mensagem = htmlspecialchars((string)($dados['msg'] ?? 'Falha ao calcular Dashboard.'), ENT_QUOTES, 'UTF-8');
    echo "<div class='alert alert-danger'>" . $mensagem . "</div>";
    return;
}

// Profiling opcional via ?profile=1
$mostrarProfile = isset($_GET['profile']) && (string)$_GET['profile'] === '1';
$profileSteps = $dados['profile'] ?? [];

// Buscar última sincronização bem-sucedida
$ultimaSincronizacao = obterUltimaSincronizacao($pdo, $cdempresaSessao);

$cdempresa  = (int)$dados['empresa'];
$dsempresa  = (string)($dados['dsempresa'] ?? '');
$anoref     = (int)$dados['anoref'];
$mesAtual   = (int)$dados['mesAtual'];
$moeda      = $dados['moeda'];
$dashboards = $dados['dashboards'];
$serieYtd   = $dados['serieYtd'] ?? null;

// Auto-switch: quando consolidar empresas via filtro (multi-seleção)
if (!$visaoParam && !((bool)($_SESSION['dashboard_visao_explicit'] ?? false))) {
    if (is_array($empresasSelecionadas) && count($empresasSelecionadas) > 1) {
        $visaoDashboard = 'modelo';
        $_SESSION['dashboard_visao'] = 'modelo';
    }
}

// ============================
// MOSTRAR ALERTA SE FILTROS FORAM APLICADOS
// ============================
if ($filtrosAplicados) {
    $empresasNomes = [];
    foreach ($empresasSelecionadas as $empId) {
        foreach ($empresasFiltro as $emp) {
            if ((int)$emp['cdempresa'] === $empId) {
                $empresasNomes[] = $emp['dsapelido'];
                break;
            }
        }
    }
    
    // Encontrar nome do centro de custo
    $centroCustoNome = 'Todos';
    if ($cdcentrocustoFiltro > 0) {
        foreach ($centrosCustoFiltro as $cc) {
            if ((int)$cc['cdcentrocusto'] === $cdcentrocustoFiltro) {
                $centroCustoNome = $cc['dscentro'];
                break;
            }
        }
    }
    
    // Encontrar nome do país
    $paisNome = 'Todos';
    if ($cdpaisFiltro > 0) {
        foreach ($paisesFiltro as $p) {
            if ((int)$p['cdpais'] === $cdpaisFiltro) {
                $paisNome = $p['dspais'];
                break;
            }
        }
    }
    
    // Encontrar nome do trimestre
    $trimestreNome = 'Todos';
    foreach ($trimestresFiltro as $t) {
        if ((int)$t['numero'] === $trimestreFiltro) {
            $trimestreNome = $t['descricao'];
            break;
        }
    }
    
    // Encontrar nome da moeda
    $moedaNome = '';
    foreach ($moedasFiltro as $m) {
        if ((int)$m['cdmoeda'] === $cdmoedaFiltro) {
            $moedaNome = $m['simbolo'];
            break;
        }
    }
}

// Dados auxiliares para gráficos (um por variável de dashboard)
$chartData = [];
foreach ($dashboards as $dash) {
    $labels        = [];
    $anoOrcado     = [];
    $anoReal       = [];
    $anoRealAnt    = [];
    $mesOrcado     = [];
    $mesReal       = [];
    $mesRealAnt    = [];

    foreach ($dash['secoes'] as $sec) {
        $labels[]     = $sec['titulo'];
        $anoOrcado[]  = (float)$sec['ano']['orcado'];
        $anoReal[]    = (float)$sec['ano']['realizado'];
        $anoRealAnt[] = (float)$sec['ano']['realizadoAnterior'];
        $mesOrcado[]  = (float)$sec['mes']['orcado'];
        $mesReal[]    = (float)$sec['mes']['realizado'];
        $mesRealAnt[] = (float)$sec['mes']['realizadoAnterior'];
    }

    $chartData[] = [
        'id'     => (int)$dash['cdvariavel'],
        'nome'   => $dash['nome'],
        'labels' => $labels,
        'ano'    => [
            'orcado'            => $anoOrcado,
            'realizado'         => $anoReal,
            'realizadoAnterior' => $anoRealAnt,
        ],
        'mes'    => [
            'orcado'            => $mesOrcado,
            'realizado'         => $mesReal,
            'realizadoAnterior' => $mesRealAnt,
        ],
    ];
}

function formatarValorDashboard(float $v, string $mascara, array $moeda): string {
    if ($mascara === 'percentual') {
        return number_format($v * 100, 2, ',', '.') . ' %';
    }

    $simbolo = $moeda['simbolo'] ?? 'R$';
    $formato = $moeda['formato'] ?? 'decimal';
    $casas   = ($formato === 'inteiro') ? 0 : 2;

    return $simbolo . ' ' . number_format($v, $casas, ',', '.');
}

function formatarPercentDashboard(float $v): string {
    return number_format($v * 100, 1, ',', '.') . ' %';
}

/**
 * Retorna a classe de cor CSS baseada na projeção.
 * - Para metas: Verde (>=100%), Amarelo (95-99.99%), Vermelho (<95%)
 * - Para orçamento: Verde (<=80%), Amarelo (<=90%), Vermelho (>90%)
 */
function obterClasseCorProjecao(?float $projPerc, ?string $modelo = null): string {
    $m = strtolower(trim((string)$modelo));
    $v = ($projPerc === null) ? 0.0 : abs((float)$projPerc); // Usar valor absoluto para suportar orçamentos negativos

    if ($m === 'orcamento') {
        if ($v <= 0.80) return 'text-success';
        if ($v <= 0.90) return 'text-warning';
        return 'text-danger';
    }

    if ($v >= 1.0) return 'text-success';
    if ($v >= 0.95) return 'text-warning';
    return 'text-danger';
}

/**
 * Retorna a cor HEX baseada na projeção.
 * - Para metas: Verde (>=100%), Amarelo (95-99.99%), Vermelho (<95%)
 * - Para orçamento: Verde (<=80%), Amarelo (<=90%), Vermelho (>90%)
 */
function obterCorHexProjecao(?float $projPerc, ?string $modelo = null): string {
    $m = strtolower(trim((string)$modelo));
    $v = ($projPerc === null) ? 0.0 : abs((float)$projPerc); // Usar valor absoluto para suportar orçamentos negativos

    if ($m === 'orcamento') {
        if ($v <= 0.80) return '#16a34a';
        if ($v <= 0.90) return '#f59e0b';
        return '#dc2626';
    }

    if ($v >= 1.0) return '#16a34a';
    if ($v >= 0.95) return '#f59e0b';
    return '#dc2626';
}

/**
 * Retorna dicionário de linguagem baseado no modelo da variável
 * @param string $modelo 'meta' ou 'orcamento'
 * @return array Dicionário com labels de linguagem
 */
function obterLinguagem(string $modelo): array {
    $modeloNorm = strtolower(trim($modelo));
    
    // Para qualquer modelo diferente de 'orcamento', usa linguagem de "Meta"
    // (inclui: meta, submeta, resultado e futuros modelos).
    if ($modeloNorm !== 'orcamento') {
        $descricao = match ($modeloNorm) {
            'submeta' => 'SubMeta',
            'meta' => 'Metas',
            'resultado' => 'Resultado',
            default => ucfirst($modeloNorm),
        };

        return [
            'planejado'        => 'Meta',
            'realizado'        => 'Realizado',
            'percentual_label' => 'Realizado',
            'restante'         => 'A Realizar',
            'percentual_desc'  => '% Realizado',
            'restante_desc'    => '% que Resta',
            'vs_anterior'      => 'Sob o Ano Anterior',
            'projecao'         => 'Projeção',
            'descricao'        => $descricao,
        ];
    }
    
    // Padrão para 'orcamento'
    return [
        'planejado'        => 'Orçamento',
        'realizado'        => 'Gasto Realizado',
        'percentual_label' => 'Consumido',
        'restante'         => 'Disponivel',
        'percentual_desc'  => '% do orçamento consumido',
        'restante_desc'    => '% de saldo disponível',
        'vs_anterior'      => 'Vs Período Anterior',
        'projecao'         => 'Projeção de Gasto',
        'descricao'        => 'Orçamento',
    ];
}

function boolFromDb($v): bool {
    if (is_bool($v)) {
        return $v;
    }
    if (is_int($v)) {
        return $v === 1;
    }
    $s = strtolower(trim((string)$v));
    return in_array($s, ['1', 'true', 't', 'yes', 'on'], true);
}

$nomesMes      = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
$nomeMesAtual  = $nomesMes[$mesAtual-1] ?? '';

// Dados de calendário (sem cache)
$anoCorrente  = (int)date('Y');
$mesCorrente  = (int)date('n');
$diaCorrente  = (int)date('j');

$ultimoDia = (int)cal_days_in_month(CAL_GREGORIAN, $mesCorrente, $anoCorrente);

// Calcula fins de semana restantes (mês inteiro)
$finsSemanaRestantes = 0;
for ($d = 1; $d <= $ultimoDia; $d++) {
    $ts = mktime(0, 0, 0, $mesCorrente, $d, $anoCorrente);
    $w  = (int)date('w', $ts);
    if ($w === 6) { $finsSemanaRestantes++; }
}

// Busca feriados do mês inteiro (sem projeção)
$feriadosBase = obterFeriadosMesBase($pdo, $mesCorrente, $anoCorrente, 1);
$feriadosData = [
    'qtd' => count($feriadosBase),
    'lista' => $feriadosBase,
];
$feriadoDiaUtil = obterFeriadoDiaUtil($pdo);

// Recalcula valores que dependem do dia corrente
$diasRestantesMesCorrente = max(0, $ultimoDia - $diaCorrente + 1);

// Filtra feriados restantes a partir do dia corrente
$feriadosBaseTodos = $feriadosData['lista'] ?? [];
$feriadosRestantes = array_filter($feriadosBaseTodos, function($f) use ($diaCorrente, $mesCorrente) {
    $parts = explode('/', $f['data']);
    return count($parts) === 2 && (int)$parts[0] >= $diaCorrente;
});
$feriadosRestantes = array_values($feriadosRestantes);
$qtdFeriadosRestantes = count($feriadosRestantes);

// Recalcula fins de semana restantes
$finsSemanaRestantes = 0;
for ($d = $diaCorrente; $d <= $ultimoDia; $d++) {
    $ts = mktime(0, 0, 0, $mesCorrente, $d, $anoCorrente);
    $w  = (int)date('w', $ts);
    if ($w === 6) { $finsSemanaRestantes++; }
}



// Dias restantes do ano (usado nas telas)
$diaAnoAtualGlobal = (int)date('z') + 1; // 1 a 366
$diasAnoAnteriorGlobal = date('L') ? 366 : 365;
$diasRestantesAno = $diasAnoAnteriorGlobal - $diaAnoAtualGlobal;

// Percentual de projeção de feriados (busca única)
$percentualProjecaoFeriado = obterPercentualProjecaoFeriado($pdo);

    // Pré-calcula contas por variável usando fórmulas já carregadas
    $contasPorVariavel = [];
    // Conjunto total de contas usadas no dashboard
    $contasDashboard = [];
    foreach ($dashboards as $dash) {
        $contasUsadas = [];
        foreach ($dash['secoes'] as $sec) {
            if (!empty($sec['formula'])) {
                preg_match_all('/\d+/', $sec['formula'], $m);
                foreach ($m[0] as $cd) {
                    $contasUsadas[(int)$cd] = true;
                    $contasDashboard[(int)$cd] = true;
                }
            }
        }
        $contasPorVariavel[(int)$dash['cdvariavel']] = array_keys($contasUsadas);
    }

    $contasDashboard = array_keys($contasDashboard);
    // Mapa [conta][dia] => valor do ano anterior (mês corrente)
    $mapContaDiaMes = obterValoresContasDiasAnoAnteriorMes($pdo, $cdempresa, $mesCorrente, $contasDashboard);
    
    // Mapa [conta][dia] => valor do mês atual - CONSOLIDADO para múltiplas empresas
    $mapContaDiaMesAtual = [];
    $empresasParaDadosDias = !empty($empresaParaDados) ? $empresaParaDados : [$cdempresa];
    foreach ($empresasParaDadosDias as $cdempEmp) {
        $mapEmp = obterValoresContasDiasMesAtual($pdo, (int)$cdempEmp, $mesCorrente, $anoCorrente, $contasDashboard);
        // Consolida os valores por dia
        foreach ($mapEmp as $conta => $diasValores) {
            if (!isset($mapContaDiaMesAtual[$conta])) {
                $mapContaDiaMesAtual[$conta] = [];
            }
            foreach ($diasValores as $dia => $valor) {
                $mapContaDiaMesAtual[$conta][$dia] = ($mapContaDiaMesAtual[$conta][$dia] ?? 0.0) + $valor;
            }
        }
    }

    // KPIs por variável (cada dashboard como âncora)
    $kpisVariaveis      = [];
    $mascaraPorVariavel = [];
    $modeloPorVariavel  = [];
    $metaOrcAnoTotal = 0.0;
    $metaRealAnoTotal = 0.0;
    $metaOrcMesTotal = 0.0;
    $metaRealMesTotal = 0.0;
    $metaOrcTrimTotal = 0.0;
    $metaRealTrimTotal = 0.0;
    foreach ($dashboards as $dash) {
        if (empty($dash['secoes'])) {
            continue;
        }

        $vid = (int)$dash['cdvariavel'];
        $modelo = $dash['modelo'] ?? 'orcamento';
        $isOrcamento = (strtolower(trim((string)$modelo)) === 'orcamento');
        $modeloPorVariavel[$vid] = $modelo;

        $orcAnoTotal     = 0.0;
        $realAnoTotal    = 0.0;
        $realAnoAntTotal = 0.0;
        $projAnoTotal    = 0.0;
        $orcMesTotal     = 0.0;
        $realMesTotal    = 0.0;
        $realMesAntTotal = 0.0;
        $projMesTotal    = 0.0;
        $orcTrimTotal    = 0.0;
        $realTrimTotal   = 0.0;
        $realTrimAntTotal = 0.0;
        $projTrimTotal   = 0.0;

        foreach ($dash['secoes'] as $secResumo) {
            $anoResumo = $secResumo['ano'];
            $orcAnoTotal     += (float)$anoResumo['orcado'];
            $realAnoTotal    += (float)$anoResumo['realizado'];
            $realAnoAntTotal += (float)$anoResumo['realizadoAnterior'];
            $projAnoTotal    += (float)$anoResumo['projValor'];
            
            $mesResumo = $secResumo['mes'];
            $orcMesTotal     += (float)$mesResumo['orcado'];
            $realMesTotal    += (float)$mesResumo['realizado'];
            $realMesAntTotal += (float)($mesResumo['realizadoAnterior'] ?? 0.0);
            $projMesTotal    += (float)($mesResumo['projValor'] ?? 0.0);
            
            $trimResumo = $secResumo['trimestre'];
            $orcTrimTotal    += (float)$trimResumo['orcado'];
            $realTrimTotal   += (float)$trimResumo['realizado'];
            $realTrimAntTotal += (float)($trimResumo['realizadoAnterior'] ?? 0.0);
            $projTrimTotal   += (float)$trimResumo['projValor'];

            // Acúmulo para resumo das variáveis do tipo 'meta'
            if (($modelo ?? 'orcamento') === 'meta') {
                $metaOrcAnoTotal  += (float)$anoResumo['orcado'];
                $metaRealAnoTotal += (float)$anoResumo['realizado'];
                $metaOrcMesTotal  += (float)$mesResumo['orcado'];
                $metaRealMesTotal += (float)$mesResumo['realizado'];
                $metaOrcTrimTotal += (float)$trimResumo['orcado'];
                $metaRealTrimTotal += (float)$trimResumo['realizado'];
            }
        }

        // Modelo ORÇAMENTO: normaliza sinal (débito pode vir negativo)
        if ($isOrcamento) {
            $orcAnoTotal = abs($orcAnoTotal);
            $realAnoTotal = abs($realAnoTotal);
            $realAnoAntTotal = abs($realAnoAntTotal);
            $projAnoTotal = abs($projAnoTotal);
            $orcMesTotal = abs($orcMesTotal);
            $realMesTotal = abs($realMesTotal);
            $realMesAntTotal = abs($realMesAntTotal);
            $orcTrimTotal = abs($orcTrimTotal);
            $realTrimTotal = abs($realTrimTotal);
            $realTrimAntTotal = abs($realTrimAntTotal);
            $projTrimTotal = abs($projTrimTotal);
        }

        // Para ORÇAMENTO: atingPerc = consumo/realizado %; para META/SUBMETA: atingPerc = alcance%
        if ($isOrcamento) {
            // Orçamento: usa período (mes) para o cálculo principal
            $atingidoPerc   = ($orcMesTotal != 0.0) ? ($realMesTotal / $orcMesTotal) : 0.0;
        } else {
            // Meta/Submeta: usa ano para o cálculo principal (consolidado)
            $atingidoPerc   = ($orcAnoTotal != 0.0) ? ($realAnoTotal / $orcAnoTotal) : 0.0;
        }
        $restantePerc   = max(0.0, 1.0 - $atingidoPerc);
        
        // Obter valores do período anterior já calculados no loop
        $realMesAntPeriodo = $realMesAntTotal;
        $realAnoAntPeriodo = $realAnoAntTotal;
        
        // Calcula variações
        $varMesAnterior = ($realMesAntPeriodo != 0.0) ? (($realMesTotal - $realMesAntPeriodo) / abs($realMesAntPeriodo)) : null;
        $varAnoAnterior = ($realAnoAntPeriodo != 0.0) ? (($realAnoTotal - $realAnoAntPeriodo) / abs($realAnoAntPeriodo)) : null;
        
        // Projeções: usar os valores já calculados no serviço (respeita multi-mês e regras de período)
        $projMesValor = (float)$projMesTotal;
        $projMesPerc  = ($orcMesTotal != 0.0) ? ($projMesValor / $orcMesTotal) : 0.0;
        
        $projTrimValor = (float)$projTrimTotal;
        $projTrimPerc  = ($orcTrimTotal != 0.0) ? ($projTrimValor / $orcTrimTotal) : 0.0;
        
        $projAnoValor = (float)$projAnoTotal;
        $projAnoPerc  = ($orcAnoTotal != 0.0) ? ($projAnoValor / $orcAnoTotal) : 0.0;
        
        // Variações vs. período anterior
        $varTrimAnterior = null;
        if ($realTrimAntTotal != 0.0) {
            $varTrimAnterior = (($realTrimTotal - $realTrimAntTotal) / abs($realTrimAntTotal));
        }

        $kpisVariaveis[] = [
            'id'            => (int)$dash['cdvariavel'],
            'nome'          => $dash['nome'],
            'modelo'        => $modelo,
            'grafico'       => $dash['grafico'] ?? false,
            'orcAno'        => $orcAnoTotal,
            'realAno'       => $realAnoTotal,
            'realAnoAnt'    => $realAnoAntPeriodo,
            'atingPerc'     => $atingidoPerc,
            'restantePerc'  => $restantePerc,
            'varAno'        => $varAnoAnterior,
            'projAnoValor'  => $projAnoValor,
            'projAnoPerc'   => $projAnoPerc,
            'orcMes'        => $orcMesTotal,
            'realMes'       => $realMesTotal,
            'realMesAnt'    => $realMesAntPeriodo,
            'varMes'        => $varMesAnterior,
            'projMesValor'  => $projMesValor,
            'projMesPerc'   => $projMesPerc,
            'orcTrim'       => $orcTrimTotal,
            'realTrim'      => $realTrimTotal,
            'realTrimAnt'   => $realTrimAntTotal,
            'varTrim'       => $varTrimAnterior,
            'projTrimValor' => $projTrimValor,
            'projTrimPerc'  => $projTrimPerc,
        ];

        $mascaraPorVariavel[(int)$dash['cdvariavel']] = $dash['secoes'][0]['mascara'] ?? 'moeda';
    }

    // Resumo BI usa a primeira variável como principal
    $kpiResumo = $kpisVariaveis[0] ?? null;
    $mascaraPrincipal = null;
    $modeloPrincipal = 'orcamento';
    if ($kpiResumo) {
        $mascaraPrincipal = $mascaraPorVariavel[$kpiResumo['id']] ?? 'moeda';
        $modeloPrincipal = $modeloPorVariavel[$kpiResumo['id']] ?? 'orcamento';
    }

    // Dados dos gráficos (cards do topo): apenas variáveis com grafico = true
    $metasCharts = [];
    foreach ($kpisVariaveis as $kv) {
        if (!boolFromDb($kv['grafico'] ?? false)) {
            continue;
        }

        $modelo = $modeloPorVariavel[$kv['id']] ?? 'orcamento';
        
        // Obter dados diários para esta variável (últimos 7 dias)
        $diasHistorico = [];
        $contasVar = $contasPorVariavel[(int)$kv['id']] ?? [];
        if (!empty($contasVar) && !empty($mapContaDiaMesAtual)) {
            // Pega os últimos 7 dias
            $diasDisponibles = [];
            foreach ($contasVar as $conta) {
                if (isset($mapContaDiaMesAtual[$conta])) {
                    foreach ($mapContaDiaMesAtual[$conta] as $dia => $valor) {
                        $diasDisponibles[$dia] = ($diasDisponibles[$dia] ?? 0.0) + $valor;
                    }
                }
            }
            // Ordena decrescente (últimos dias primeiro)
            krsort($diasDisponibles);
            $diasHistorico = array_slice($diasDisponibles, 0, 7, true);
        }
        
        $metasCharts[] = [
            'id'     => $kv['id'],
            'nome'   => $kv['nome'],
            'modelo' => $modelo,
            'orcAno' => $kv['orcAno'],
            'realAno'=> $kv['realAno'],
            'orcMes' => $kv['orcMes'],
            'realMes'=> $kv['realMes'],
            'projAnoPerc' => $kv['projAnoPerc'],
            'projMesPerc' => $kv['projMesPerc'],
            'restantePerc' => $kv['restantePerc'] ?? 0.0,
            'diasHistorico' => $diasHistorico,
        ];
    }

    // Visão consolidada por modelo (variáveis do tipo Dashboard)
    $visaoConsolidadaPorModelo = montarVisaoConsolidadaPorModelo($kpisVariaveis);

    // ==== ORÇAMENTO CONSOLIDADO ====
    // Agrupa TODOS os valores de orçamento (variáveis com modelo = 'orcamento')
    $orcamentoConsolidado = [
        'orcMes'        => 0.0,
        'realMes'       => 0.0,
        'projMesValor'  => 0.0,
        'orcTrim'       => 0.0,
        'realTrim'      => 0.0,
        'projTrimValor' => 0.0,
        'orcAno'        => 0.0,
        'realAno'       => 0.0,
        'projAnoValor'  => 0.0,
        'projMesPerc'   => 0.0,
        'projTrimPerc'  => 0.0,
        'projAnoPerc'   => 0.0,
    ];
    $orcamentoVariavelIds = [];
    
    foreach ($kpisVariaveis as $kv) {
        if ((strtolower(trim((string)($modeloPorVariavel[$kv['id']] ?? 'orcamento'))) === 'orcamento')) {
            $orcamentoVariavelIds[] = (int)$kv['id'];
            $orcamentoConsolidado['orcMes']        += (float)($kv['orcMes'] ?? 0.0);
            $orcamentoConsolidado['realMes']       += (float)($kv['realMes'] ?? 0.0);
            $orcamentoConsolidado['projMesValor']  += (float)($kv['projMesValor'] ?? 0.0);
            $orcamentoConsolidado['orcTrim']       += (float)($kv['orcTrim'] ?? 0.0);
            $orcamentoConsolidado['realTrim']      += (float)($kv['realTrim'] ?? 0.0);
            $orcamentoConsolidado['projTrimValor'] += (float)($kv['projTrimValor'] ?? 0.0);
            $orcamentoConsolidado['orcAno']        += (float)($kv['orcAno'] ?? 0.0);
            $orcamentoConsolidado['realAno']       += (float)($kv['realAno'] ?? 0.0);
            $orcamentoConsolidado['projAnoValor']  += (float)($kv['projAnoValor'] ?? 0.0);
        }
    }
    
    // Calcular percentuais do consolidado com base na projeção (não apenas realizado)
    if ($orcamentoConsolidado['orcMes'] > 0) {
        $orcamentoConsolidado['projMesPerc'] = $orcamentoConsolidado['projMesValor'] / $orcamentoConsolidado['orcMes'];
    }
    if ($orcamentoConsolidado['orcTrim'] > 0) {
        $orcamentoConsolidado['projTrimPerc'] = $orcamentoConsolidado['projTrimValor'] / $orcamentoConsolidado['orcTrim'];
    }
    if ($orcamentoConsolidado['orcAno'] > 0) {
        $orcamentoConsolidado['projAnoPerc'] = $orcamentoConsolidado['projAnoValor'] / $orcamentoConsolidado['orcAno'];
    }

    // Visão consolidada POR EMPRESA: ao consolidar (multi-empresa), gera um dataset por empresa selecionada
    $visaoConsolidadaEmpresas = [];
    if ($visaoDashboard === 'modelo') {
        // Mapa de nomes para fallback (lista acessível já filtrada)
        $mapNomeEmpresa = [];
        foreach ($empresasFiltro as $emp) {
            $eid = (int)($emp['cdempresa'] ?? 0);
            if ($eid <= 0) continue;
            $mapNomeEmpresa[$eid] = (string)($emp['dsapelido'] ?? $emp['dsempresa'] ?? ('Empresa ' . $eid));
        }

        // Se não houver empresas selecionadas por algum motivo, usa empresa exibida
        $empresasParaConsolidar = $empresasSelecionadas;
        if (empty($empresasParaConsolidar) && $cdempresaSessao > 0) {
            $empresasParaConsolidar = [$cdempresaSessao];
        }

        // Se for 1 empresa, reutiliza o KPI já calculado (mais completo)
        if (is_array($empresasParaConsolidar) && count($empresasParaConsolidar) === 1) {
            $eid = (int)$empresasParaConsolidar[0];
            $visaoConsolidadaEmpresas[] = [
                'cdempresa' => $eid,
                'dsempresa' => (string)($dsempresa ?: ($mapNomeEmpresa[$eid] ?? ('Empresa ' . $eid))),
                'modelos'   => $visaoConsolidadaPorModelo,
            ];
        } else {
            foreach ($empresasParaConsolidar as $eidRaw) {
                $eid = (int)$eidRaw;
                if ($eid <= 0) continue;

                $dadosEmp = obterDadosDashboard($pdo, 0, $cdcentrocustoFiltro, $anoFiltro, $trimestreFiltro, $mesesSelecionados, [$eid], $eid, $cdpaisFiltro);
                if (!($dadosEmp['ok'] ?? false)) {
                    continue;
                }

                $dashEmp = $dadosEmp['dashboards'] ?? [];
                $anorefEmp = (int)($dadosEmp['anoref'] ?? $anoref);
                $mesAtualEmp = (int)($dadosEmp['mesAtual'] ?? $mesAtual);

                // KPIs mínimos para consolidação/gráfico (mantém projeção se disponível)
                $kpisEmp = montarKpisBasicosFromDashboards(
                    $dashEmp,
                    $mesAtualEmp,
                    $anorefEmp,
                    $mesesSelecionados,
                    $mesCorrente,
                    $anoCorrente,
                    (int)$trimestreFiltro,
                    $diaCorrente,
                    $ultimoDia,
                    $diasRestantesMesCorrente,
                    $diaAnoAtualGlobal,
                    $diasRestantesAno,
                    (int)($feriadosData['qtd'] ?? 0),
                    (bool)$feriadoDiaUtil
                );

                $visaoConsolidadaEmpresas[] = [
                    'cdempresa' => $eid,
                    'dsempresa' => (string)($dadosEmp['dsempresa'] ?? ($mapNomeEmpresa[$eid] ?? ('Empresa ' . $eid))),
                    'modelos'   => montarVisaoConsolidadaPorModelo($kpisEmp),
                ];
            }
        }
    }

    // Payload comparativo: por MODELO/PERÍODO, lista empresas (para gráfico único por modelo)
    $dashboardConsolidadoComparativo = [];
    if ($visaoDashboard === 'modelo') {
        $ordemModelosComparativo = ['meta', 'submeta', 'resultado', 'orcamento'];
        $periodosComparativo = ['mes', 'trimestre', 'ano'];

        foreach ($ordemModelosComparativo as $modeloComp) {
            foreach ($periodosComparativo as $periodoComp) {
                $empresasArr = [];
                $hasProj = false;

                foreach (($visaoConsolidadaEmpresas ?? []) as $empBucket) {
                    $eid = (int)($empBucket['cdempresa'] ?? 0);
                    if ($eid <= 0) continue;
                    $nomeEmp = (string)($empBucket['dsempresa'] ?? ('Empresa ' . $eid));

                    $mData = $empBucket['modelos'][$modeloComp][$periodoComp] ?? null;
                    if (!$mData) continue;

                    $totalReal = (float)($mData['total_real'] ?? 0);
                    $totalOrc  = (float)($mData['total_orc'] ?? 0);
                    $percTotal = (float)($mData['perc_total'] ?? 0);

                    $projTotal = null;
                    $vars = $mData['vars'] ?? [];
                    if (is_array($vars) && !empty($vars)) {
                        $sumProj = 0.0;
                        $temProj = false;
                        foreach ($vars as $v) {
                            if (array_key_exists('proj_valor', $v) && $v['proj_valor'] !== null) {
                                $sumProj += (float)$v['proj_valor'];
                                $temProj = true;
                            }
                        }
                        if ($temProj) {
                            $projTotal = $sumProj;
                            $hasProj = true;
                        }
                    }

                    $projPerc = null;
                    if ($projTotal !== null && $totalOrc != 0.0) {
                        $projPerc = ((float)$projTotal / (float)$totalOrc);
                    }

                    // Não incluir empresas sem qualquer valor (evita cards vazios como RESULTADO = 0)
                    if ($totalOrc == 0.0 && $totalReal == 0.0 && ($projTotal === null || $projTotal == 0.0)) {
                        continue;
                    }

                    $empresasArr[] = [
                        'cdempresa'  => $eid,
                        'dsempresa'  => $nomeEmp,
                        'total_real' => $totalReal,
                        'total_orc'  => $totalOrc,
                        'perc_total' => $percTotal,
                        'proj_total' => $projTotal,
                        'proj_perc'  => $projPerc,
                    ];
                }

                $dashboardConsolidadoComparativo[$modeloComp][$periodoComp] = [
                    'empresas' => $empresasArr,
                    'hasProj'  => $hasProj,
                ];
            }
        }
    }

    // Termômetro financeiro (somado entre empresas) para o modelo ORÇAMENTO
    $orcamentoTermometro = [];
    if ($visaoDashboard === 'modelo') {
        $orcVars = array_values(array_filter(($kpisVariaveis ?? []), function($kv) use ($modeloPorVariavel) {
            $id = (int)($kv['id'] ?? 0);
            $m = strtolower(trim((string)($modeloPorVariavel[$id] ?? ($kv['modelo'] ?? ''))));
            return $m === 'orcamento';
        }));

        $buildRanking = function(string $orcKey, string $realKey) use ($orcVars) {
            $items = [];
            foreach ($orcVars as $kv) {
                $orcV = (float)($kv[$orcKey] ?? 0.0);
                $realV = (float)($kv[$realKey] ?? 0.0);
                if ($orcV <= 0.0) continue;
                $items[] = [
                    'nome' => (string)($kv['nome'] ?? ''),
                    'perc' => ($realV / $orcV),
                ];
            }
            if (empty($items)) {
                return ['maior' => null, 'menor' => null];
            }
            usort($items, fn($a, $b) => ($b['perc'] <=> $a['perc']));
            return [
                'maior' => $items[0] ?? null,
                'menor' => $items[count($items) - 1] ?? null,
            ];
        };

        $sumBucket = function(string $periodo) use ($dashboardConsolidadoComparativo) {
            $empresas = $dashboardConsolidadoComparativo['orcamento'][$periodo]['empresas'] ?? [];
            $orc = 0.0;
            $real = 0.0;
            $hasProj = false;
            $projSum = 0.0;
            foreach ($empresas as $e) {
                $orc += (float)($e['total_orc'] ?? 0.0);
                $real += (float)($e['total_real'] ?? 0.0);
                if (array_key_exists('proj_total', $e) && $e['proj_total'] !== null) {
                    $projSum += (float)$e['proj_total'];
                    $hasProj = true;
                }
            }
            return [
                'orc' => $orc,
                'real' => $real,
                'proj' => $hasProj ? $projSum : null,
            ];
        };

        foreach (['mes', 'trimestre', 'ano'] as $p) {
            $tot = $sumBucket($p);
            $orc = (float)($tot['orc'] ?? 0.0);
            $real = (float)($tot['real'] ?? 0.0);
            $proj = $tot['proj'];
            $saldo = max(0.0, $orc - $real);
            $consumoPerc = ($orc != 0.0) ? ($real / $orc) : 0.0;
            $projPerc = ($proj !== null && $orc != 0.0) ? (((float)$proj) / $orc) : null;

            $rank = match ($p) {
                'mes' => $buildRanking('orcMes', 'realMes'),
                'trimestre' => $buildRanking('orcTrim', 'realTrim'),
                default => $buildRanking('orcAno', 'realAno'),
            };

            $orcamentoTermometro[$p] = [
                'orc' => $orc,
                'real' => $real,
                'saldo' => $saldo,
                'proj' => $proj,
                'consumoPerc' => $consumoPerc,
                'projPerc' => $projPerc,
                'ranking' => $rank,
            ];
        }
    }


if ($isWarm) {
    header('Content-Type: application/json; charset=utf-8');
    echo json_encode(['ok' => true]);
    return;
}

?>

<!-- Alerta de Filtros Aplicados -->
<?php if ($filtrosAplicados): ?>
    <div class="alert alert-info alert-dismissible fade show mb-3 py-2 px-3" role="alert">
        <small class="d-block d-md-inline">
            📅 <strong><?= htmlspecialchars((string)$anoFiltro) ?></strong> |
            🗓️ <strong><?= htmlspecialchars((string)$nomeMesAtual) ?></strong> |
            🌍 <strong><?= htmlspecialchars($paisNome) ?></strong> |
            💱 <strong><?= htmlspecialchars($moedaNome) ?></strong> |
            🏢 <strong><?= htmlspecialchars(count($empresasNomes) > 0 ? implode(', ', $empresasNomes) : 'Nenhuma') ?></strong> |
            📍 <strong><?= htmlspecialchars($centroCustoNome) ?></strong> |
            📊 <strong><?= htmlspecialchars($trimestreNome) ?></strong>
        </small>
        <button type="button" class="btn-close" data-bs-dismiss="alert"></button>
    </div>
    
    <!-- DEBUG: Mostrar dados do filtro -->
    <?php if (isset($_GET['debug_filtros']) && $_GET['debug_filtros'] === '1'): ?>
        <div class="alert alert-warning mb-3 p-3" style="font-family: monospace; font-size: 11px; line-height: 1.6;">
            <strong style="font-size: 13px; display: block; margin-bottom: 10px;">🔍 DEBUG - FILTROS</strong>
            
            <table style="width: 100%; border-collapse: collapse;">
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;"><strong>Parâmetro</strong></td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><strong>Valor</strong></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">filtrosAplicados</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><?= $filtrosAplicados ? '✅ SIM' : '❌ NÃO' ?></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">GET[cdempresa]</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= json_encode($_GET['cdempresa'] ?? null) ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">SESSION[cdempresa]</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= json_encode($_SESSION['filtros_dashboard']['cdempresa'] ?? null) ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">empresasSelecionadas</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= json_encode($empresasSelecionadas) ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">empresaParaDados</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= json_encode($empresaParaDados ?? []) ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">cdcentrocustoFiltro</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= (int)$cdcentrocustoFiltro ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">anoFiltro</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= (int)$anoFiltro ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">mesFiltro</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= json_encode($mesesSelecionados ?? []) ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">trimestreFiltro</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= (int)$trimestreFiltro ?></code></td>
                </tr>
                <tr>
                    <td style="border: 1px solid #ddd; padding: 5px;">cdpaisFiltro</td>
                    <td style="border: 1px solid #ddd; padding: 5px;"><code><?= (int)$cdpaisFiltro ?></code></td>
                </tr>
            </table>
            
            <div style="margin-top: 10px; border-top: 1px solid #ddd; padding-top: 10px;">
                <strong>📋 Empresas Acessíveis:</strong>
                <br><code><?= json_encode(array_map(fn($e) => ['id' => (int)$e['cdempresa'], 'nome' => $e['dsapelido']], $empresasFiltro)) ?></code>
            </div>
        </div>
    <?php endif; ?>
<?php endif; ?>


<div class="d-flex align-items-center justify-content-between mb-3 gap-2 flex-wrap">
    <h4 class="mb-0 d-flex align-items-center gap-2">
        <i class="bi bi-speedometer2"></i>
        <span>Dashboard</span>
        <small class="text-muted ms-2"><?= htmlspecialchars($dsempresa) ?> (<?= (int)$cdempresa ?>) · Ano <?= htmlspecialchars((string)$anoref) ?></small>
    </h4>
    
    <!-- 📊 Última sincronização (discreta) -->
    <?php if ($ultimaSincronizacao): ?>
        <?php 
            $dt = new DateTime($ultimaSincronizacao);
            $dtFormatada = $dt->format('d/m/Y H:i:s');
            $horas_passadas = (time() - $dt->getTimestamp()) / 3600;
            $recente = $horas_passadas <= 24;
            $classBorder = $recente ? 'border-success' : 'border-danger';
            $classText = $recente ? 'text-success' : 'text-danger';
        ?>
        <small class="d-flex align-items-center gap-1 px-2 py-1 border rounded <?= $classBorder ?>" style="font-size: 0.85rem;">
            <i class="bi bi-arrow-repeat <?= $classText ?>" style="font-size: 0.85rem;"></i>
            <span class="<?= $classText ?>">
                <?= htmlspecialchars($dtFormatada) ?>
            </span>
        </small>
    <?php endif; ?>
</div>

<!-- Desktop: Filtros expandidos (abaixo do título) -->
<div class="card border-0 shadow-sm mb-4 d-none d-md-block">
    <div class="card-body">
        <form method="GET" id="filtrosFormDesktop" class="row g-2 align-items-end">
            <!-- Ano -->
            <div class="col-md-1">
                <label for="filtroAnoDesktop" class="form-label fw-semibold" style="font-size: 0.75rem;">📅 Ano</label>
                <select class="form-select form-select-sm" id="filtroAnoDesktop" name="ano">
                    <?php foreach ($anosFiltro as $ano): ?>
                        <option value="<?= (int)$ano['anoref'] ?>" <?= ((int)$ano['anoref'] === $anoFiltro) ? 'selected' : '' ?>>
                            <?= (int)$ano['anoref'] ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

            <!-- Mês (Multi-select) -->
            <div class="col-md-2">
                <label class="form-label fw-semibold" style="font-size: 0.75rem;">🗓️ Mês</label>
                <div class="dropdown" data-bs-auto-close="outside">
                    <button class="btn btn-outline-secondary btn-sm w-100 text-start d-flex justify-content-between align-items-center" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        <span id="mesesLabelDesktop" style="font-size: 0.8rem;">Selecione</span>
                        <i class="bi bi-chevron-down" style="font-size: 0.8rem;"></i>
                    </button>
                    <ul class="dropdown-menu w-100" style="max-height: 250px; overflow-y: auto;">
                        <li>
                            <div class="dropdown-item">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" id="selecionarTodosMesesDesktop" onchange="toggleTodosMeses()" />
                                    <label class="form-check-label" for="selecionarTodosMesesDesktop">
                                        <small class="fw-bold">Selecionar Todos</small>
                                    </label>
                                </div>
                            </div>
                        </li>
                        <li><hr class="dropdown-divider"></li>
                        <?php $mesesNomes = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']; ?>
                        <?php foreach ($mesesNomes as $idx => $nomeMes): ?>
                            <?php $mesNum = $idx + 1; ?>
                            <li>
                                <div class="dropdown-item">
                                    <div class="form-check">
                                        <input class="form-check-input mes-checkbox" type="checkbox"
                                            id="mesDesktop_<?= (int)$mesNum ?>"
                                            name="mes[]"
                                            value="<?= (int)$mesNum ?>"
                                            onchange="atualizarLabelMeses()"
                                            <?= in_array((int)$mesNum, $mesesSelecionados, true) ? 'checked' : '' ?> />
                                        <label class="form-check-label" for="mesDesktop_<?= (int)$mesNum ?>">
                                            <small><?= htmlspecialchars((string)$nomeMes) ?></small>
                                        </label>
                                    </div>
                                </div>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            </div>
            
            <!-- País -->
            <div class="col-md-1">
                <label for="filtroPaisDesktop" class="form-label fw-semibold" style="font-size: 0.75rem;">🌍 País</label>
                <select class="form-select form-select-sm" id="filtroPaisDesktop" name="cdpais">
                    <option value="0">Todos</option>
                    <?php foreach ($paisesFiltro as $pais): ?>
                        <option value="<?= (int)$pais['cdpais'] ?>" <?= ((int)$pais['cdpais'] === $cdpaisFiltro) ? 'selected' : '' ?>>
                            <?= htmlspecialchars((string)$pais['dspais']) ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

            <!-- Moeda -->
            <div class="col-md-1">
                <label for="filtroMoedaDesktop" class="form-label fw-semibold" style="font-size: 0.75rem;">💱 Moeda</label>
                <select class="form-select form-select-sm" id="filtroMoedaDesktop" name="cdmoeda">
                    <?php foreach ($moedasFiltro as $m): ?>
                        <option value="<?= (int)$m['cdmoeda'] ?>" <?= ((int)$m['cdmoeda'] === $cdmoedaFiltro) ? 'selected' : '' ?>>
                            <?= htmlspecialchars((string)($m['simbolo'] ?? '')) ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

            <!-- Empresas (Multi-select com checkboxes em dropdown) -->
            <div class="col-md-2">
                <label class="form-label fw-semibold" style="font-size: 0.75rem;">🏢 Empresas</label>
                <div class="dropdown" data-bs-auto-close="outside">
                    <button class="btn btn-outline-secondary btn-sm w-100 text-start d-flex justify-content-between align-items-center" type="button" data-bs-toggle="dropdown" aria-expanded="false">
                        <span id="empresasLabelDesktop" style="font-size: 0.8rem;">Nenhuma</span>
                        <i class="bi bi-chevron-down" style="font-size: 0.8rem;"></i>
                    </button>
                    <ul class="dropdown-menu w-100" style="max-height: 250px; overflow-y: auto;">
                        <!-- Selecionar Todas -->
                        <li>
                            <div class="dropdown-item">
                                <div class="form-check">
                                    <input class="form-check-input" type="checkbox" id="selecionarTodasDesktop" 
                                        onchange="toggleTodasEmpresas()" />
                                    <label class="form-check-label" for="selecionarTodasDesktop">
                                        <small class="fw-bold">Selecionar Todas</small>
                                    </label>
                                </div>
                            </div>
                        </li>
                        <li><hr class="dropdown-divider"></li>
                        <!-- Checkboxes de empresas -->
                        <?php foreach ($empresasFiltro as $emp): ?>
                            <li>
                                <div class="dropdown-item">
                                    <div class="form-check">
                                        <input class="form-check-input empresa-checkbox" type="checkbox" 
                                            id="empresaDesktop_<?= (int)$emp['cdempresa'] ?>" 
                                            name="cdempresa[]" 
                                            value="<?= (int)$emp['cdempresa'] ?>"
                                            onchange="atualizarLabelEmpresas()"
                                            <?= in_array((int)$emp['cdempresa'], $empresasSelecionadas) ? 'checked' : '' ?> />
                                        <label class="form-check-label" for="empresaDesktop_<?= (int)$emp['cdempresa'] ?>">
                                            <small><?= htmlspecialchars((string)$emp['dsapelido']) ?></small>
                                        </label>
                                    </div>
                                </div>
                            </li>
                        <?php endforeach; ?>
                    </ul>
                </div>
            </div>

            <!-- Centro de Custo -->
            <div class="col-md-2">
                <label for="filtroCentroCustoDesktop" class="form-label fw-semibold" style="font-size: 0.75rem;">📍 Centro</label>
                <select class="form-select form-select-sm" id="filtroCentroCustoDesktop" name="cdcentrocusto">
                    <option value="0">Todos</option>
                    <?php foreach ($centrosCustoFiltro as $cc): ?>
                        <option value="<?= (int)$cc['cdcentrocusto'] ?>" <?= ((int)$cc['cdcentrocusto'] === $cdcentrocustoFiltro) ? 'selected' : '' ?>>
                            <?= htmlspecialchars((string)$cc['dscentro']) ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>

            <!-- Trimestre -->
            <div class="col-md-1">
                <label for="filtroTrimestreDesktop" class="form-label fw-semibold" style="font-size: 0.75rem;">📊 Trim.</label>
                <select class="form-select form-select-sm" id="filtroTrimestreDesktop" name="trimestre">
                    <option value="0" <?= ($trimestreFiltro === 0) ? 'selected' : '' ?>>Todos</option>
                    <?php foreach ($trimestresFiltro as $trim): ?>
                        <option value="<?= (int)$trim['numero'] ?>" <?= ((int)$trim['numero'] === $trimestreFiltro) ? 'selected' : '' ?>>
                            <?= htmlspecialchars((string)$trim['descricao']) ?>
                        </option>
                    <?php endforeach; ?>
                </select>
            </div>
            
            <!-- Botões (direita, discretos) -->
            <div class="col-md-2 d-flex gap-2">
                <button type="button" class="btn btn-outline-secondary btn-sm flex-grow-1" onclick="limparFiltros()" title="Limpar filtros">
                    <i class="bi bi-arrow-clockwise"></i>
                </button>
                <button type="button" class="btn btn-outline-primary btn-sm flex-grow-1" onclick="aplicarFiltros()" title="Aplicar filtros">
                    <i class="bi bi-search"></i>
                </button>
            </div>
        </form>
    </div>
</div>
<!-- Mobile: Accordion retraído -->
<div class="card border-0 shadow-sm mb-4 d-md-none">
    <div class="card-header bg-white border-bottom p-2 cursor-pointer" data-bs-toggle="collapse" data-bs-target="#filtrosCollapseMobile" aria-expanded="false" style="cursor: pointer;">
        <small class="fw-semibold">
            <i class="bi bi-funnel"></i> Filtros
        </small>
    </div>
    
    <div id="filtrosCollapseMobile" class="collapse">
        <div class="card-body">
            <form method="GET" id="filtrosForm" class="row g-3">
                <!-- Ano -->
                <div class="col-12">
                    <label for="filtroAno" class="form-label fw-semibold">Ano</label>
                    <select class="form-select form-select-sm" id="filtroAno" name="ano">
                        <?php foreach ($anosFiltro as $ano): ?>
                            <option value="<?= (int)$ano['anoref'] ?>" <?= ((int)$ano['anoref'] === $anoFiltro) ? 'selected' : '' ?>>
                                <?= (int)$ano['anoref'] ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <!-- Mês (Multi-select) -->
                <div class="col-12">
                    <label class="form-label fw-semibold">Mês</label>
                    <div class="border rounded p-2" style="max-height: 180px; overflow-y: auto;">
                        <div class="form-check mb-1">
                            <input class="form-check-input" type="checkbox" id="selecionarTodosMeses" onchange="toggleTodosMeses()" />
                            <label class="form-check-label" for="selecionarTodosMeses">
                                <small class="fw-bold">Selecionar Todos</small>
                            </label>
                        </div>
                        <hr class="my-1" />
                        <?php $mesesNomes = ['Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez']; ?>
                        <?php foreach ($mesesNomes as $idx => $nomeMes): ?>
                            <?php $mesNum = $idx + 1; ?>
                            <div class="form-check mb-1">
                                <input class="form-check-input mes-checkbox" type="checkbox"
                                    id="mes_<?= (int)$mesNum ?>"
                                    name="mes[]"
                                    value="<?= (int)$mesNum ?>"
                                    <?= in_array((int)$mesNum, $mesesSelecionados, true) ? 'checked' : '' ?> />
                                <label class="form-check-label" for="mes_<?= (int)$mesNum ?>">
                                    <small><?= htmlspecialchars((string)$nomeMes) ?></small>
                                </label>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
                
                <!-- País -->
                <div class="col-12">
                    <label for="filtroPais" class="form-label fw-semibold">País</label>
                    <select class="form-select form-select-sm" id="filtroPais" name="cdpais">
                        <option value="0">Todos</option>
                        <?php foreach ($paisesFiltro as $pais): ?>
                            <option value="<?= (int)$pais['cdpais'] ?>" <?= ((int)$pais['cdpais'] === $cdpaisFiltro) ? 'selected' : '' ?>>
                                <?= htmlspecialchars((string)$pais['dspais']) ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <!-- Moeda -->
                <div class="col-12">
                    <label for="filtroMoeda" class="form-label fw-semibold">Moeda</label>
                    <select class="form-select form-select-sm" id="filtroMoeda" name="cdmoeda">
                        <?php foreach ($moedasFiltro as $m): ?>
                            <option value="<?= (int)$m['cdmoeda'] ?>" <?= ((int)$m['cdmoeda'] === $cdmoedaFiltro) ? 'selected' : '' ?>>
                                <?= htmlspecialchars((string)($m['simbolo'] ?? '')) ?> - <?= htmlspecialchars((string)($m['dsmoeda'] ?? '')) ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <!-- Empresas (Multi-select com checkboxes) -->
                <div class="col-12">
                    <label class="form-label fw-semibold">Empresas</label>
                    <div class="border rounded p-2" style="max-height: 180px; overflow-y: auto;">
                        <!-- Selecionar Todas -->
                        <div class="form-check mb-1">
                            <input class="form-check-input" type="checkbox" id="selecionarTodas" 
                                onchange="toggleTodasEmpresas()" />
                            <label class="form-check-label" for="selecionarTodas">
                                <small class="fw-bold">Selecionar Todas</small>
                            </label>
                        </div>
                        <hr class="my-1" />
                        <!-- Checkboxes de empresas -->
                        <?php foreach ($empresasFiltro as $emp): ?>
                            <div class="form-check mb-1">
                                <input class="form-check-input empresa-checkbox" type="checkbox" 
                                    id="empresa_<?= (int)$emp['cdempresa'] ?>" 
                                    name="cdempresa[]" 
                                    value="<?= (int)$emp['cdempresa'] ?>"
                                    <?= in_array((int)$emp['cdempresa'], $empresasSelecionadas) ? 'checked' : '' ?> />
                                <label class="form-check-label" for="empresa_<?= (int)$emp['cdempresa'] ?>">
                                    <small><?= htmlspecialchars((string)$emp['dsapelido']) ?></small>
                                </label>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>

                <!-- Centro de Custo -->
                <div class="col-12">
                    <label for="filtroCentroCusto" class="form-label fw-semibold">Centro de Custo</label>
                    <select class="form-select form-select-sm" id="filtroCentroCusto" name="cdcentrocusto">
                        <option value="0">Todos</option>
                        <?php foreach ($centrosCustoFiltro as $cc): ?>
                            <option value="<?= (int)$cc['cdcentrocusto'] ?>" <?= ((int)$cc['cdcentrocusto'] === $cdcentrocustoFiltro) ? 'selected' : '' ?>>
                                <?= htmlspecialchars((string)$cc['dscentro']) ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>

                <!-- Trimestre -->
                <div class="col-12">
                    <label for="filtroTrimestre" class="form-label fw-semibold">Trimestre</label>
                    <select class="form-select form-select-sm" id="filtroTrimestre" name="trimestre">
                        <option value="0" <?= ($trimestreFiltro === 0) ? 'selected' : '' ?>>Todos</option>
                        <?php foreach ($trimestresFiltro as $trim): ?>
                            <option value="<?= (int)$trim['numero'] ?>" <?= ((int)$trim['numero'] === $trimestreFiltro) ? 'selected' : '' ?>>
                                <?= htmlspecialchars((string)$trim['descricao']) ?>
                            </option>
                        <?php endforeach; ?>
                    </select>
                </div>
                
                <!-- Botões (discretos) -->
                <div class="col-12 d-flex justify-content-end gap-2">
                    <button type="button" class="btn btn-outline-secondary btn-sm" onclick="limparFiltros()" title="Limpar filtros">
                        <i class="bi bi-arrow-clockwise"></i> Limpar
                    </button>
                    <button type="button" class="btn btn-outline-primary btn-sm" onclick="aplicarFiltros()" title="Aplicar filtros">
                        <i class="bi bi-search"></i> Filtrar
                    </button>
                </div>
            </form>
        </div>
    </div>
</div>


<?php if ($mostrarProfile && !empty($profileSteps)): ?>
    <div class="alert alert-secondary py-2 px-3 small mb-3">
        <div class="fw-semibold mb-1">Profiling (ms)</div>
        <div class="d-flex flex-wrap gap-3">
            <?php foreach ($profileSteps as $p): ?>
                <div><strong><?= htmlspecialchars($p['label']) ?>:</strong> <?= number_format((float)$p['ms'], 2, ',', '.') ?></div>
            <?php endforeach; ?>
        </div>
    </div>
<?php endif; ?>
<hr>

<!-- Toggle de Visão (Por variável / Consolidado por modelo) -->
<div class="d-flex justify-content-start align-items-center mb-3">
    <div class="btn-group btn-group-sm" role="group" aria-label="Visão do Dashboard">
        <a href="<?= htmlspecialchars(urlComVisaoDashboard('variavel')) ?>" class="btn <?= $visaoDashboard === 'variavel' ? 'btn-primary' : 'btn-outline-secondary' ?>">
            Detalhado
        </a>
        <a href="<?= htmlspecialchars(urlComVisaoDashboard('modelo')) ?>" class="btn <?= $visaoDashboard === 'modelo' ? 'btn-primary' : 'btn-outline-secondary' ?>">
            Consolidado
        </a>
    </div>
</div>


<!-- ⚠️ Alerta de sincronização atrasada -->
<?php if ($ultimaSincronizacao): ?>
    <?php 
        $dt = new DateTime($ultimaSincronizacao);
        $horas_passadas = (time() - $dt->getTimestamp()) / 3600;
        if ($horas_passadas > 24):
    ?>
        <div class="alert alert-warning alert-dismissible fade show mb-3" role="alert">
            <i class="bi bi-exclamation-triangle-fill"></i>
            <strong>Sincronização atrasada!</strong>
            Os dados não são sincronizados há mais de 24 horas. 
            <a href="#" onclick="abrirSyncModal(event)" class="alert-link">Clique aqui para sincronizar agora</a>.
            <button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
        </div>
    <?php endif; ?>
<?php endif; ?>
<!-- Container da visão de gráficos/BI -->
<?php if ($visaoDashboard !== 'modelo'): ?>
<div class="mb-4 dashboard-metas-grid">
    
    <?php 
    // Reorganizar metasCharts por prioridade: Meta → Orçamento → Submeta
    $metasChartsPorTipo = ['meta' => [], 'orcamento' => [], 'submeta' => [], 'resultado' => []];
    foreach ($metasCharts as $meta) {
        $modeloVar = $modeloPorVariavel[$meta['id']] ?? 'meta';
        $modeloNorm = strtolower(trim((string)$modeloVar));
        if (isset($metasChartsPorTipo[$modeloNorm])) {
            $metasChartsPorTipo[$modeloNorm][] = $meta;
        }
    }
    
    // Ordem de renderização: Meta, Orçamento, Submeta, Resultado
    $metasChartsOrdenadas = array_merge(
        $metasChartsPorTipo['meta'],
        $metasChartsPorTipo['orcamento'],
        $metasChartsPorTipo['submeta'],
        $metasChartsPorTipo['resultado']
    );
    ?>
    
    <!-- CARDS DE META (DONUTS) -->
    <?php foreach ($metasChartsOrdenadas as $meta):
        $modeloVariavel = $modeloPorVariavel[$meta['id']] ?? 'meta';
        if (strtolower(trim((string)$modeloVariavel)) !== 'meta') {
            continue;
        }
        
        $percAno = ($meta['orcAno'] > 0) ? ($meta['realAno'] / $meta['orcAno']) : 0.0;
        $percMes = ($meta['orcMes'] > 0) ? ($meta['realMes'] / $meta['orcMes']) : 0.0;
        $restantePercMes = max(0.0, 1.0 - $percMes);
        $percAnoTxt = formatarPercentDashboard($percAno);
        $percMesTxt = formatarPercentDashboard($percMes);
        $restantePercMesTxt = formatarPercentDashboard($restantePercMes);
        // Cores baseadas na PROJEÇÃO, não no percentual atingido
        $clsAno = obterClasseCorProjecao($meta['projAnoPerc'], $modeloVariavel);
        $clsMes = obterClasseCorProjecao($meta['projMesPerc'], $modeloVariavel);
        $colAnoHex = obterCorHexProjecao($meta['projAnoPerc'], $modeloVariavel);
        $colMesHex = obterCorHexProjecao($meta['projMesPerc'], $modeloVariavel);
        $colRestHex = '#e2e8f0';
    ?>
        <div class="card border-0 shadow-sm dashboard-card-horizontal">
            <div class="card-body d-flex align-items-center gap-4 p-3" style="min-width: 0;">
                <!-- Lado esquerdo: Donut -->
                <div class="dashboard-chart-wrapper-donut-horizontal">
                    <canvas id="chart-kpi-donut-<?php echo (int)$meta['id']; ?>"></canvas>
                </div>
                
                <!-- Lado direito: Informações -->
                <div class="flex-grow-1 d-flex flex-column justify-content-between" style="min-width: 0;">
                    <!-- Título e Badge -->
                    <div class="d-flex justify-content-between align-items-start mb-2">
                        <div>
                            <div class="text-uppercase small text-secondary fw-semibold"><?php echo htmlspecialchars($meta['nome']); ?></div>
                        </div>
                        <?php 
                            $modeloDescricao = ucfirst($modeloVariavel);
                            $modeloClass = match ($modeloVariavel) {
                                'submeta' => 'bg-success',
                                'resultado' => 'bg-secondary',
                                default => 'bg-info',
                            };
                        ?>
                        <span class="badge <?= $modeloClass ?> text-white border"><?= $modeloDescricao ?></span>
                    </div>
                    
                    <!-- Valor percentual principal (MÊS) e A Realizar -->
                    <div class="mb-2">
                        <div class="d-flex align-items-center gap-2">
                            <div class="flex-grow-1">
                                <div class="text-uppercase small text-secondary fw-semibold mb-1">
                                    <?= ($modeloVariavel === 'orcamento') ? 'Gasto Realizado' : 'Realizado' ?>
                                </div>
                                <div class="donut-metric-horizontal <?= $clsMes ?>">
                                    <?= $percMesTxt ?>
                                </div>
                                <div class="small text-muted" style="font-size: 0.75rem; color: #999; margin-top: 0.25rem;">
                                    (<?= formatarValorDashboard((float)$meta['realMes'], $mascaraPrincipal, $moeda) ?>)
                                </div>
                            </div>
                            <div class="flex-grow-1">
                                <div class="text-uppercase small text-secondary fw-semibold mb-1">
                                    <?= ($modeloVariavel === 'orcamento') ? 'Orçamento' : 'A Realizar' ?>
                                </div>
                                <div class="donut-metric-horizontal <?= $clsMes ?>">
                                    <?= $restantePercMesTxt ?>
                                </div>
                                <div class="small text-muted" style="font-size: 0.75rem; color: #999; margin-top: 0.25rem;">
                                    (<?= formatarValorDashboard((float)$meta['orcMes'] - (float)$meta['realMes'], $mascaraPrincipal, $moeda) ?>)
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Informações adicionais (dias, feriados) - apenas para Meta e Submeta -->
                    <div class="small text-muted mt-2">
    <div>
        Vamos Lá, Ainda Temos <?= (int)$diasRestantesMesCorrente ?> dias<br>
        Com (<?= (int)$finsSemanaRestantes ?> fim(s) de semana)
    </div>

    <?php 
        // Mostrar feriados apenas para Meta e Submeta
        if (in_array($modeloVariavel, ['meta', 'submeta'], true)) {
            // Projeta feriados usando contas específicas desta variável
            $contasVar = $contasPorVariavel[(int)$meta['id']] ?? [];
            if (empty($contasVar)) {
                $contasVar = $contasDashboard;
            }

            $feriadosProjVar = [];
            if (!empty($mapContaDiaMes)) {
                $feriadosProjVar = calcularProjecaoFeriadosComMapa(
                    $feriadosBaseTodos,
                    $mapContaDiaMes,
                    $contasVar,
                    $percentualProjecaoFeriado
                );
            }

            if (empty($feriadosProjVar)) {
                $feriadosProjVar = calcularProjecaoFeriados(
                    $pdo,
                    $cdempresa,
                    $feriadosBaseTodos,
                    $contasVar,
                    $percentualProjecaoFeriado
                );
            }

            $feriadosPorVariavelRestantes = array_filter($feriadosProjVar ?? [], function($f) use ($diaCorrente) {
                $parts = explode('/', $f['data']);
                return count($parts) === 2 && (int)$parts[0] >= $diaCorrente;
            });
            $feriadosPorVariavelRestantes = array_values($feriadosPorVariavelRestantes);
            $qtdFeriadosPorVariavel = count($feriadosPorVariavelRestantes);
            
            // Verifica se há feriado na semana corrente (a partir de hoje)
            $temFeriadoNaSemana = false;
            if ($qtdFeriadosPorVariavel > 0) {
                $diaSemanaCorrente = (int)date('N');  // 1 (segunda) a 7 (domingo)
                $dataCorrente = new DateTime();
                $dataCorrente->setTime(0, 0, 0);  // Garante 00:00:00 para comparação correta
                $domingoDaSemana = clone $dataCorrente;
                $domingoDaSemana->modify('next Sunday');
                
                foreach ($feriadosPorVariavelRestantes as $f) {
                    $parts = explode('/', $f['data']);
                    if (count($parts) === 2) {
                        $diaFeriado = (int)$parts[0];
                        $mesFeriado = (int)$parts[1];
                        $dataFeriado = new DateTime($anoCorrente . '-' . str_pad($mesFeriado, 2, '0', STR_PAD_LEFT) . '-' . str_pad($diaFeriado, 2, '0', STR_PAD_LEFT));
                        $dataFeriado->setTime(0, 0, 0);  // Garante 00:00:00 para comparação correta
                        
                        // Inclui feriado se for hoje ou em qualquer dia até o fim da semana
                        if ($dataFeriado >= $dataCorrente && $dataFeriado <= $domingoDaSemana) {
                            $temFeriadoNaSemana = true;
                            break;
                        }
                    }
                }
            }
        ?>

            <?php if ($qtdFeriadosPorVariavel > 0): ?>
                <a href="#"
                   class="feriados-toggle link-secondary text-decoration-none"
                   data-feriados="<?= (int)$meta['id'] ?>"
                   <?php if ($temFeriadoNaSemana): ?>data-open-on-load="true"<?php endif; ?>>
                    Teremos <?= (int)$qtdFeriadosPorVariavel ?> feriado(s)
                </a>

                <div id="feriados-list-<?= (int)$meta['id'] ?>"
                     class="small text-muted mt-1 <?php if ($temFeriadoNaSemana): ?>d-block<?php else: ?>d-none<?php endif; ?>"
                     style="font-size: 0.85rem;">
                    <?php foreach ($feriadosPorVariavelRestantes as $f): ?>
                        <div class="d-flex justify-content-between align-items-center py-1 border-bottom">
                            <div>
                                <span class="fw-semibold"><?= htmlspecialchars($f['data']) ?></span> <?= htmlspecialchars($f['desc']) ?>
                                <span class="text-secondary">(<?= htmlspecialchars($f['pais']) ?>)</span>
                                <small class="text-muted">Projeção:</small>
                            </div>
                            <?php if (isset($f['projecao'])): ?>
                                <div class="text-end">
                                    <div class="fw-semibold <?= (float)$f['projecao'] >= 0 ? 'text-success' : 'text-danger' ?>" style="font-size: 0.95rem;">
                                        <?= formatarValorDashboard((float)$f['projecao'], 'moeda', $moeda) ?>
                                    </div>
                                </div>
                            <?php else: ?>
                                <div class="text-end text-muted">
                                    <small>-</small>
                                </div>
                            <?php endif; ?>
                        </div>
                    <?php endforeach; ?>
                </div>
            <?php else: ?>
                <div class="text-muted fst-italic">
                    Não há feriados neste período
                </div>
            <?php endif; ?>
        <?php 
        }
        ?>
</div>

                </div>
            </div>

            <!-- Histórico dos últimos 7 dias - 100% width -->
            <?php if (!empty($meta['diasHistorico'])): ?>
            <div class="card-body border-top pt-2 pb-2" style="overflow-x: auto;">
                <div class="text-uppercase small text-secondary fw-semibold mb-1" style="margin-bottom: 0.5rem;">Últimos 7 dias</div>
                <div style="max-width: 100%; overflow-x: auto;">
                    <table class="historico-tabela">
                        <tbody>
                            <tr>
                                <?php 
                                $diasSemana = ['seg', 'ter', 'qua', 'qui', 'sex', 'sab', 'dom'];
                                foreach ($meta['diasHistorico'] as $dia => $valor): 
                                    $dataObj = DateTime::createFromFormat('j', (int)$dia);
                                    if ($dataObj) {
                                        $dataObj->setDate($anoCorrente, $mesCorrente, (int)$dia);
                                        $diaSemana = (int)$dataObj->format('N');
                                        $diaAbrev = $diasSemana[$diaSemana - 1] ?? 'seg';
                                    } else {
                                        $diaAbrev = 'seg';
                                    }
                                ?>
                                <td>
                                    <div class="historico-dia-data"><?= $diaAbrev ?> <?= (int)$dia ?>/<?= str_pad($mesCorrente, 2, '0', STR_PAD_LEFT) ?></div>
                                </td>
                                <?php endforeach; ?>
                            </tr>
                            <tr>
                                <?php foreach ($meta['diasHistorico'] as $dia => $valor): ?>
                                <td>
                                    <div class="historico-dia-valor"><?= formatarValorDashboard($valor, $mascaraPrincipal, $moeda) ?></div>
                                </td>
                                <?php endforeach; ?>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <?php endif; ?>
        </div>
    <?php endforeach; ?>
    
    <!-- CARD CONSOLIDADO DE ORÇAMENTO (SEGUNDA POSIÇÃO - APÓS META) -->
    <?php if (!empty($orcamentoVariavelIds) && count($orcamentoVariavelIds) > 0): 
        // Buscar variáveis de orçamento (mantém a ordem original)
        $orcamentoVars = array_filter($kpisVariaveis, function($kv) {
            global $modeloPorVariavel;
            return (strtolower(trim((string)($modeloPorVariavel[$kv['id']] ?? 'orcamento'))) === 'orcamento');
        });
        $orcamentoVars = array_values($orcamentoVars);
    ?>
    <div class="card border-0 shadow-sm mb-3" style="background-color: #ffffff; border-radius: 0.75rem;">
        <div class="card-header bg-light border-0" style="padding: 1rem 1.25rem; border-radius: 0.75rem 0.75rem 0 0;">
            <h5 class="mb-0 text-dark fw-bold">
                <span class="badge bg-info me-2">Orçamento</span> Orçamento por Conta
            </h5>
        </div>
        <div class="card-body" style="padding: 1.25rem; display: flex; flex-direction: column; gap: 1.5rem;">
            
            <!-- Lista de Orçamentos (vertical) -->
            <div class="orc-detalhado-container" style="grid-template-columns: 1.2fr 0.8fr; gap: 1.5rem;">
                
                <!-- Coluna 1: Barras de progresso -->
                <div style="display: flex; flex-direction: column; gap: 1.5rem;">
                    <?php foreach ($orcamentoVars as $idx => $orcamento):
                        $realMes = (float)($orcamento['realMes'] ?? 0);
                        $orcMes = (float)($orcamento['orcMes'] ?? 0);
                        $mascara = $mascaraPorVariavel[$orcamento['id']] ?? 'moeda';
                        $percMes = ($orcMes > 0) ? ($realMes / $orcMes) : 0.0;
                        $saldo = $orcMes - $realMes;
                        
                        // Cores baseadas na PROJEÇÃO, não no realizado
                        $projMesPerc = (float)($orcamento['projMesPerc'] ?? 0);
                        $corClasse = obterClasseCorProjecao($projMesPerc, 'orcamento');
                        
                        // Gradiente para visualização (função já usa abs internamente)
                        $projMesPercAbs = abs($projMesPerc);
                        if ($projMesPercAbs > 0.9) {
                            $corGradiente = 'linear-gradient(90deg, #ef4444, #dc2626)'; // Vermelho
                        } elseif ($projMesPercAbs > 0.8) {
                            $corGradiente = 'linear-gradient(90deg, #f59e0b, #d97706)'; // Amarelo
                        } else {
                            $corGradiente = 'linear-gradient(90deg, #10b981, #059669)'; // Verde
                        }
                    ?>
                        <div style="display: flex; align-items: center; gap: 0.75rem;">
                            <div style="flex: 1; min-width: 0;">
                                <!-- Nome da Conta (truncado se necessário) -->
                                <div style="font-size: 0.9rem; font-weight: 500; color: #374151; margin-bottom: 0.5rem;">
                                    <?= htmlspecialchars($orcamento['nome'] ?? $orcamento['descvar']) ?>
                                </div>
                                <!-- Barra horizontal -->
                                <div style="width: 100%; height: 24px; background-color: #e5e7eb; border-radius: 0.5rem; overflow: hidden; position: relative; cursor: pointer;" 
                                     data-bs-toggle="tooltip" 
                                     data-bs-placement="top"
                                     data-bs-html="true"
                                     title="<strong><?= htmlspecialchars($orcamento['nome'] ?? $orcamento['descvar']) ?></strong><br/>Real: <?= formatarValorDashboard($realMes, $mascara, $moeda) ?><br/>Orçado: <?= formatarValorDashboard($orcMes, $mascara, $moeda) ?><br/>Saldo: <?= formatarValorDashboard($saldo, $mascara, $moeda) ?><br/>Consumo: <?= formatarPercentDashboard($percMes) ?><br/><small>Projeção: <?= formatarPercentDashboard(abs($projMesPerc)) ?></small>">
                                    <div class="<?= $corClasse ?>" style="height: 100%; background: <?= $corGradiente ?>; width: <?= min(100, $percMes * 100) ?>%; transition: width 0.3s ease; border-radius: 0.5rem;"></div>
                                </div>
                                <!-- Percentual abaixo da barra -->
                                <div style="font-size: 0.8rem; color: #6b7280; margin-top: 0.25rem; text-align: right;">
                                    <?= formatarPercentDashboard($percMes) ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
                
                <!-- Coluna 2: Valores (Real / Prev / Saldo) -->
                <div style="display: flex; flex-direction: column; gap: 1.5rem;">
                    <?php foreach ($orcamentoVars as $idx => $orcamento):
                        $realMes = (float)($orcamento['realMes'] ?? 0);
                        $orcMes = (float)($orcamento['orcMes'] ?? 0);
                        $mascara = $mascaraPorVariavel[$orcamento['id']] ?? 'moeda';
                        $percMes = ($orcMes > 0) ? ($realMes / $orcMes) : 0.0;
                        $saldo = $orcMes - $realMes;
                    ?>
                        <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.5rem; font-size: 0.85rem;">
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Realizado</div>
                                <div style="font-weight: 600; color: #374151;">
                                    <?= formatarValorDashboard($realMes, $mascara, $moeda) ?>
                                </div>
                            </div>
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Orçado</div>
                                <div style="font-weight: 600; color: #374151;">
                                    <?= formatarValorDashboard($orcMes, $mascara, $moeda) ?>
                                </div>
                            </div>
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Saldo</div>
                                <div style="font-weight: 600; color: <?= $saldo >= 0 ? '#10b981' : '#ef4444' ?>;">
                                    <?= formatarValorDashboard($saldo, $mascara, $moeda) ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
            </div>
            
            <!-- Resumo Total no Footer -->
            <div class="border-top mt-2 pt-2">
                <div class="d-flex justify-content-between small text-muted">
                    <span>Total Realizado: <span class="fw-semibold text-dark"><?= formatarValorDashboard($orcamentoConsolidado['realMes'], 'moeda', $moeda) ?></span></span>
                    <span>Total Orçado: <span class="fw-semibold text-dark"><?= formatarValorDashboard($orcamentoConsolidado['orcMes'], 'moeda', $moeda) ?></span></span>
                    <span>% Consumido: <span class="fw-semibold text-dark"><?= formatarPercentDashboard($orcamentoConsolidado['orcMes'] > 0 ? $orcamentoConsolidado['realMes'] / $orcamentoConsolidado['orcMes'] : 0) ?></span></span>
                    <span>Projeção: <span class="fw-semibold text-dark"><?= formatarValorDashboard(abs($orcamentoConsolidado['projMesValor']), 'moeda', $moeda) ?> (<?= formatarPercentDashboard(abs($orcamentoConsolidado['projMesPerc'])) ?>)</span></span>
                </div>
            </div>
        </div>
    </div>
    <?php endif; ?>
    
    <!-- CARD DE SUBMETA (mesmo conceito que Orçamento, mas com linguagem de Meta) -->
    <?php
    $submetaVars = array_filter($kpisVariaveis, function($kv) {
        global $modeloPorVariavel;
        return (strtolower(trim((string)($modeloPorVariavel[$kv['id']] ?? 'orcamento'))) === 'submeta');
    });
    $submetaVars = array_values($submetaVars);
    
    if (!empty($submetaVars)):
        // Calcular totais consolidated para submeta com base em projeção
        $submetaConsolidado = ['realizado' => 0, 'meta' => 0, 'projValor' => 0, 'perc' => 0, 'projPerc' => 0];
        foreach ($submetaVars as $sub) {
            $submetaConsolidado['realizado'] += (float)($sub['realMes'] ?? 0);
            $submetaConsolidado['meta'] += (float)($sub['orcMes'] ?? 0);
            $submetaConsolidado['projValor'] += (float)($sub['projMesValor'] ?? 0);
        }
        if ($submetaConsolidado['meta'] > 0) {
            $submetaConsolidado['perc'] = ($submetaConsolidado['realizado'] / $submetaConsolidado['meta']) * 100;
            $submetaConsolidado['projPerc'] = ($submetaConsolidado['projValor'] / $submetaConsolidado['meta']);
        }
    ?>
    <div class="card border-0 shadow-sm mb-3" style="background-color: #ffffff; border-radius: 0.75rem;">
        <div class="card-header bg-light border-0" style="padding: 1rem 1.25rem; border-radius: 0.75rem 0.75rem 0 0;">
            <h5 class="mb-0 text-dark fw-bold">
                <span class="badge bg-info me-2">Submeta</span> Detalhado por Conta
            </h5>
        </div>
        <div class="card-body" style="padding: 1.25rem; display: flex; flex-direction: column; gap: 1.5rem;">
            
            <!-- Lista de Submetas (vertical) -->
            <div class="orc-detalhado-container" style="grid-template-columns: 1.2fr 0.8fr; gap: 1.5rem;">
                
                <!-- Coluna 1: Barras de progresso -->
                <div style="display: flex; flex-direction: column; gap: 1.5rem;">
                    <?php foreach ($submetaVars as $idx => $submeta):
                        $realMes = (float)($submeta['realMes'] ?? 0);
                        $metaMes = (float)($submeta['orcMes'] ?? 0); // Usa "Orcamento do mes" como meta da submeta
                        $mascara = $mascaraPorVariavel[$submeta['id']] ?? 'moeda';
                        $percMes = ($metaMes > 0) ? ($realMes / $metaMes) : 0.0;
                        $saldo = $metaMes - $realMes;
                        
                        // Cores baseadas na PROJEÇÃO, não no realizado
                        $projMesPerc = (float)($submeta['projMesPerc'] ?? 0);
                        $corClasse = obterClasseCorProjecao($projMesPerc, 'submeta');
                        
                        // Gradiente para visualização (função já usa abs internamente)
                        $projMesPercAbs = abs($projMesPerc);
                        if ($projMesPercAbs >= 1.0) {
                            $corGradiente = 'linear-gradient(90deg, #10b981, #059669)'; // Verde - atingiu meta
                        } elseif ($projMesPercAbs >= 0.95) {
                            $corGradiente = 'linear-gradient(90deg, #f59e0b, #d97706)'; // Amarelo - próximo à meta
                        } else {
                            $corGradiente = 'linear-gradient(90deg, #ef4444, #dc2626)'; // Vermelho - não atingiu
                        }
                    ?>
                        <div style="display: flex; align-items: center; gap: 0.75rem;">
                            <div style="flex: 1; min-width: 0;">
                                <!-- Nome da Submeta (truncado se necessário) -->
                                <div style="font-size: 0.9rem; font-weight: 500; color: #374151; margin-bottom: 0.5rem;">
                                    <?= htmlspecialchars($submeta['nome'] ?? $submeta['descvar']) ?>
                                </div>
                                <!-- Barra horizontal -->
                                <div style="width: 100%; height: 24px; background-color: #e5e7eb; border-radius: 0.5rem; overflow: hidden; position: relative; cursor: pointer;" 
                                     data-bs-toggle="tooltip" 
                                     data-bs-placement="top"
                                     data-bs-html="true"
                                     title="<strong><?= htmlspecialchars($submeta['nome'] ?? $submeta['descvar']) ?></strong><br/>Realizado: <?= formatarValorDashboard($realMes, $mascara, $moeda) ?><br/>Meta: <?= formatarValorDashboard($metaMes, $mascara, $moeda) ?><br/>Diferença: <?= formatarValorDashboard($saldo, $mascara, $moeda) ?><br/>Atingido: <?= formatarPercentDashboard($percMes) ?><br/><small>Projeção: <?= formatarPercentDashboard(abs($projMesPerc)) ?></small>">
                                    <div class="<?= $corClasse ?>" style="height: 100%; background: <?= $corGradiente ?>; width: <?= min(100, $percMes * 100) ?>%; transition: width 0.3s ease; border-radius: 0.5rem;"></div>
                                </div>
                                <!-- Percentual abaixo da barra -->
                                <div style="font-size: 0.8rem; color: #6b7280; margin-top: 0.25rem; text-align: right;">
                                    <?= formatarPercentDashboard($percMes) ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
                
                <!-- Coluna 2: Valores (Realizado / Meta / Saldo) -->
                <div style="display: flex; flex-direction: column; gap: 1.5rem;">
                    <?php foreach ($submetaVars as $idx => $submeta):
                        $realMes = (float)($submeta['realMes'] ?? 0);
                        $metaMes = (float)($submeta['orcMes'] ?? 0);
                        $mascara = $mascaraPorVariavel[$submeta['id']] ?? 'moeda';
                        $percMes = ($metaMes > 0) ? ($realMes / $metaMes) : 0.0;
                        $saldo = $metaMes - $realMes;
                        
                        // Cor baseada no percentual
                        if ($percMes >= 1.0) {
                            $corPercent = '#10b981'; // Verde
                        } elseif ($percMes >= 0.9) {
                            $corPercent = '#f59e0b'; // Amarelo
                        } else {
                            $corPercent = '#ef4444'; // Vermelho
                        }
                    ?>
                        <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 0.5rem; font-size: 0.85rem;">
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Realizado</div>
                                <div style="font-weight: 600; color: #374151;">
                                    <?= formatarValorDashboard($realMes, $mascara, $moeda) ?>
                                </div>
                            </div>
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Meta</div>
                                <div style="font-weight: 600; color: #374151;">
                                    <?= formatarValorDashboard($metaMes, $mascara, $moeda) ?>
                                </div>
                            </div>
                            <div style="text-align: center; padding: 0.5rem; background-color: #f3f4f6; border-radius: 0.375rem;">
                                <div style="font-size: 0.7rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Diferença</div>
                                <div style="font-weight: 600; color: <?= $saldo >= 0 ? '#10b981' : '#ef4444' ?>;">
                                    <?= formatarValorDashboard($saldo, $mascara, $moeda) ?>
                                </div>
                            </div>
                        </div>
                    <?php endforeach; ?>
                </div>
                
            </div>
            
            <!-- Footer: Totais consolidados de Submeta -->
            <div style="border-top: 1px solid #e5e7eb; padding-top: 1rem; margin-top: 0.5rem;">
                <div style="display: grid; grid-template-columns: repeat(5, 1fr); gap: 1rem; font-size: 0.9rem;">
                    <div style="text-align: center;">
                        <div style="font-size: 0.75rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Total Realizado</div>
                        <div style="font-weight: 600; font-size: 1.05rem; color: #1f2937;">
                            <?= formatarValorDashboard($submetaConsolidado['realizado'], $mascaraPrincipal, $moeda) ?>
                        </div>
                    </div>
                    <div style="text-align: center;">
                        <div style="font-size: 0.75rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Total Meta</div>
                        <div style="font-weight: 600; font-size: 1.05rem; color: #1f2937;">
                            <?= formatarValorDashboard($submetaConsolidado['meta'], $mascaraPrincipal, $moeda) ?>
                        </div>
                    </div>
                    <div style="text-align: center;">
                        <div style="font-size: 0.75rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">% Atingido</div>
                        <div style="font-weight: 600; font-size: 1.05rem; color: #1f2937;">
                            <?= formatarPercentDashboard($submetaConsolidado['perc'] / 100) ?>
                        </div>
                    </div>
                    <div style="text-align: center;">
                        <div style="font-size: 0.75rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">Projeção</div>
                        <div style="font-weight: 600; font-size: 1.05rem; color: #1f2937;">
                            <?= formatarValorDashboard(abs($submetaConsolidado['projValor']), $mascaraPrincipal, $moeda) ?>
                        </div>
                    </div>
                    <div style="text-align: center;">
                        <div style="font-size: 0.75rem; color: #6b7280; text-transform: uppercase; margin-bottom: 0.25rem;">% Projetado</div>
                        <div style="font-weight: 600; font-size: 1.05rem; color: #1f2937;">
                            <?= formatarPercentDashboard(abs($submetaConsolidado['projPerc'])) ?>
                        </div>
                    </div>
                </div>
            </div>
            
        </div>
    </div>
    <?php endif; ?>
    
    <!-- CARDS DE SUBMETA E RESULTADO (DONUTS INDIVIDUAIS) -->
    <?php foreach ($metasChartsOrdenadas as $meta):
        $modeloVariavel = $modeloPorVariavel[$meta['id']] ?? 'meta';
        if (!in_array(strtolower(trim((string)$modeloVariavel)), ['submeta', 'resultado'], true)) {
            continue;
        }
        
        $percAno = ($meta['orcAno'] > 0) ? ($meta['realAno'] / $meta['orcAno']) : 0.0;
        $percMes = ($meta['orcMes'] > 0) ? ($meta['realMes'] / $meta['orcMes']) : 0.0;
        $restantePercMes = max(0.0, 1.0 - $percMes);
        $percAnoTxt = formatarPercentDashboard($percAno);
        $percMesTxt = formatarPercentDashboard($percMes);
        $restantePercMesTxt = formatarPercentDashboard($restantePercMes);
        $clsAno = obterClasseCorProjecao($meta['projAnoPerc'], $modeloVariavel);
        $clsMes = obterClasseCorProjecao($meta['projMesPerc'], $modeloVariavel);
        $colAnoHex = obterCorHexProjecao($meta['projAnoPerc'], $modeloVariavel);
        $colMesHex = obterCorHexProjecao($meta['projMesPerc'], $modeloVariavel);
        $colRestHex = '#e2e8f0';
    ?>
        <div class="card border-0 shadow-sm dashboard-card-horizontal">
            <div class="card-body d-flex align-items-center gap-4 p-3" style="min-width: 0;">
                <!-- Lado esquerdo: Donut -->
                <div class="dashboard-chart-wrapper-donut-horizontal">
                    <canvas id="chart-kpi-donut-<?php echo (int)$meta['id']; ?>"></canvas>
                </div>
                
                <!-- Lado direito: Informações -->
                <div class="flex-grow-1 d-flex flex-column justify-content-between" style="min-width: 0;">
                    <!-- Título e Badge -->
                    <div class="d-flex justify-content-between align-items-start mb-2">
                        <div>
                            <div class="text-uppercase small text-secondary fw-semibold"><?php echo htmlspecialchars($meta['nome']); ?></div>
                        </div>
                        <?php 
                            $modeloDescricao = ucfirst($modeloVariavel);
                            $modeloClass = match ($modeloVariavel) {
                                'submeta' => 'bg-success',
                                'resultado' => 'bg-secondary',
                                default => 'bg-info',
                            };
                        ?>
                        <span class="badge <?= $modeloClass ?> text-white border"><?= $modeloDescricao ?></span>
                    </div>
                    
                    <!-- Valor percentual principal (MÊS) e A Realizar -->
                    <div class="mb-2">
                        <div class="d-flex align-items-center gap-2">
                            <div class="flex-grow-1">
                                <div class="text-uppercase small text-secondary fw-semibold mb-1">
                                    Realizado
                                </div>
                                <div class="donut-metric-horizontal <?= $clsMes ?>">
                                    <?= $percMesTxt ?>
                                </div>
                                <div class="small text-muted" style="font-size: 0.75rem; color: #999; margin-top: 0.25rem;">
                                    (<?= formatarValorDashboard((float)$meta['realMes'], $mascaraPrincipal, $moeda) ?>)
                                </div>
                            </div>
                            <div class="flex-grow-1">
                                <div class="text-uppercase small text-secondary fw-semibold mb-1">
                                    A Realizar
                                </div>
                                <div class="donut-metric-horizontal <?= $clsMes ?>">
                                    <?= $restantePercMesTxt ?>
                                </div>
                                <div class="small text-muted" style="font-size: 0.75rem; color: #999; margin-top: 0.25rem;">
                                    (<?= formatarValorDashboard((float)$meta['orcMes'] - (float)$meta['realMes'], $mascaraPrincipal, $moeda) ?>)
                                </div>
                            </div>
                        </div>
                    </div>
                    
                    <!-- Informações adicionais (dias, feriados) - apenas para Meta e Submeta -->
                    <div class="small text-muted mt-2">
                        <div>
                            Vamos Lá, Ainda Temos <?= (int)$diasRestantesMesCorrente ?> dias<br>
                            Com (<?= (int)$finsSemanaRestantes ?> fim(s) de semana)
                        </div>

                        <?php 
                            // Mostrar feriados apenas para Meta e Submeta
                            if (in_array($modeloVariavel, ['meta', 'submeta'], true)) {
                                $contasVar = $contasPorVariavel[(int)$meta['id']] ?? [];
                                if (empty($contasVar)) {
                                    $contasVar = $contasDashboard;
                                }

                                $feriadosProjVar = [];
                                if (!empty($mapContaDiaMes)) {
                                    $feriadosProjVar = calcularProjecaoFeriadosComMapa(
                                        $feriadosBaseTodos,
                                        $mapContaDiaMes,
                                        $contasVar,
                                        $percentualProjecaoFeriado
                                    );
                                }

                                if (empty($feriadosProjVar)) {
                                    $feriadosProjVar = calcularProjecaoFeriados(
                                        $pdo,
                                        $cdempresa,
                                        $feriadosBaseTodos,
                                        $contasVar,
                                        $percentualProjecaoFeriado
                                    );
                                }

                                $feriadosPorVariavelRestantes = array_filter($feriadosProjVar ?? [], function($f) use ($diaCorrente) {
                                    $parts = explode('/', $f['data']);
                                    return count($parts) === 2 && (int)$parts[0] >= $diaCorrente;
                                });
                                $feriadosPorVariavelRestantes = array_values($feriadosPorVariavelRestantes);
                                $qtdFeriadosPorVariavel = count($feriadosPorVariavelRestantes);
                                
                                $temFeriadoNaSemana = false;
                                if ($qtdFeriadosPorVariavel > 0) {
                                    $diaSemanaCorrente = (int)date('N');
                                    $dataCorrente = new DateTime();
                                    $dataCorrente->setTime(0, 0, 0);
                                    $domingoDaSemana = clone $dataCorrente;
                                    $domingoDaSemana->modify('next Sunday');
                                    
                                    foreach ($feriadosPorVariavelRestantes as $f) {
                                        $parts = explode('/', $f['data']);
                                        if (count($parts) === 2) {
                                            $diaFeriado = (int)$parts[0];
                                            $mesFeriado = (int)$parts[1];
                                            $dataFeriado = new DateTime($anoCorrente . '-' . str_pad($mesFeriado, 2, '0', STR_PAD_LEFT) . '-' . str_pad($diaFeriado, 2, '0', STR_PAD_LEFT));
                                            $dataFeriado->setTime(0, 0, 0);
                                            
                                            if ($dataFeriado >= $dataCorrente && $dataFeriado <= $domingoDaSemana) {
                                                $temFeriadoNaSemana = true;
                                                break;
                                            }
                                        }
                                    }
                                }
                            ?>

                                <?php if ($qtdFeriadosPorVariavel > 0): ?>
                                    <a href="#"
                                       class="feriados-toggle link-secondary text-decoration-none"
                                       data-feriados="<?= (int)$meta['id'] ?>"
                                       <?php if ($temFeriadoNaSemana): ?>data-open-on-load="true"<?php endif; ?>>
                                        Teremos <?= (int)$qtdFeriadosPorVariavel ?> feriado(s)
                                    </a>

                                    <div id="feriados-list-<?= (int)$meta['id'] ?>"
                                         class="small text-muted mt-1 <?php if ($temFeriadoNaSemana): ?>d-block<?php else: ?>d-none<?php endif; ?>"
                                         style="font-size: 0.85rem;">
                                        <?php foreach ($feriadosPorVariavelRestantes as $f): ?>
                                            <div class="d-flex justify-content-between align-items-center py-1 border-bottom">
                                                <div>
                                                    <span class="fw-semibold"><?= htmlspecialchars($f['data']) ?></span> <?= htmlspecialchars($f['desc']) ?>
                                                    <span class="text-secondary">(<?= htmlspecialchars($f['pais']) ?>)</span>
                                                    <small class="text-muted">Projeção:</small>
                                                </div>
                                                <?php if (isset($f['projecao'])): ?>
                                                    <div class="text-end">
                                                        <div class="fw-semibold <?= (float)$f['projecao'] >= 0 ? 'text-success' : 'text-danger' ?>" style="font-size: 0.95rem;">
                                                            <?= formatarValorDashboard((float)$f['projecao'], 'moeda', $moeda) ?>
                                                        </div>
                                                    </div>
                                                <?php else: ?>
                                                    <div class="text-end text-muted">
                                                        <small>-</small>
                                                    </div>
                                                <?php endif; ?>
                                            </div>
                                        <?php endforeach; ?>
                                    </div>
                                <?php else: ?>
                                    <div class="text-muted fst-italic">
                                        Não há feriados neste período
                                    </div>
                                <?php endif; ?>
                            <?php 
                            }
                            ?>
                        </div>
                    </div>
                </div>
            </div>

            <!-- Histórico dos últimos 7 dias - 100% width -->
            <?php if (!empty($meta['diasHistorico'])): ?>
            <div class="card-body border-top pt-2 pb-2" style="overflow-x: auto;">
                <div class="text-uppercase small text-secondary fw-semibold mb-1" style="margin-bottom: 0.5rem;">Últimos 7 dias</div>
                <div style="max-width: 100%; overflow-x: auto;">
                    <table class="historico-tabela">
                        <tbody>
                            <tr>
                                <?php 
                                $diasSemana = ['seg', 'ter', 'qua', 'qui', 'sex', 'sab', 'dom'];
                                foreach ($meta['diasHistorico'] as $dia => $valor): 
                                    $dataObj = DateTime::createFromFormat('j', (int)$dia);
                                    if ($dataObj) {
                                        $dataObj->setDate($anoCorrente, $mesCorrente, (int)$dia);
                                        $diaSemana = (int)$dataObj->format('N');
                                        $diaAbrev = $diasSemana[$diaSemana - 1] ?? 'seg';
                                    } else {
                                        $diaAbrev = 'seg';
                                    }
                                ?>
                                <td>
                                    <div class="historico-dia-data"><?= $diaAbrev ?> <?= (int)$dia ?>/<?= str_pad($mesCorrente, 2, '0', STR_PAD_LEFT) ?></div>
                                </td>
                                <?php endforeach; ?>
                            </tr>
                            <tr>
                                <?php foreach ($meta['diasHistorico'] as $dia => $valor): ?>
                                <td>
                                    <div class="historico-dia-valor"><?= formatarValorDashboard($valor, $mascaraPrincipal, $moeda) ?></div>
                                </td>
                                <?php endforeach; ?>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </div>
            <?php endif; ?>
        </div>
    <?php endforeach; ?>
</div>

<?php else: ?>
<div class="mb-4" id="dashboardConsolidadoComparativo">
    <?php
        $ordemModelos = ['meta', 'submeta', 'resultado', 'orcamento'];
        foreach ($ordemModelos as $modeloBloco):
            $langModelo = obterLinguagem($modeloBloco);
            $titulo = match ($modeloBloco) {
                'meta' => 'Meta',
                'submeta' => 'Submeta',
                'resultado' => 'Resultado',
                'orcamento' => 'Inicio',
                default => strtoupper($modeloBloco),
            };
            $percentLabel = ($modeloBloco === 'orcamento') ? 'Percentual Consumido (Consolidado)' : 'Percentual Atingido (Consolidado)';
            $planejadoLabel = $langModelo['planejado'] ?? (($modeloBloco === 'orcamento') ? 'Orçamento' : 'Meta');
            $realizadoLabel = $langModelo['realizado'] ?? (($modeloBloco === 'orcamento') ? 'Gasto Realizado' : 'Realizado');
            $criticoLabel = ($modeloBloco === 'orcamento') ? 'Acima de 90%' : 'Abaixo de 90% (Projeção)';

            // Se não houver nenhuma empresa com dados no mês, não exibe o card
            $bucketMes = $dashboardConsolidadoComparativo[$modeloBloco]['mes']['empresas'] ?? [];
            if (empty($bucketMes)) continue;
    ?>
        <div class="card border-0 shadow-sm mb-3" data-modelo="<?= htmlspecialchars($modeloBloco) ?>">
            <div class="card-body">
                <div class="d-flex justify-content-between align-items-start gap-2 flex-wrap">
                    <div>
                        <div class="text-uppercase small text-secondary fw-semibold">Consolidado (por empresa)</div>
                        <h5 class="mb-0"><?= htmlspecialchars($titulo) ?></h5>
                    </div>
                    <div class="btn-group btn-group-sm" role="group" aria-label="Período">
                        <button type="button" class="btn btn-outline-secondary active" data-modelo-periodo="mes">Mês</button>
                        <button type="button" class="btn btn-outline-secondary" data-modelo-periodo="trimestre">Trimestre</button>
                        <button type="button" class="btn btn-outline-secondary" data-modelo-periodo="ano">Ano</button>
                    </div>
                </div>

                <?php if ($modeloBloco === 'orcamento'): ?>
                    <div class="row g-2 mt-2">
                        <div class="col-6 col-md-3">
                            <div class="small text-muted">Gasto realizado</div>
                            <div class="fw-semibold fs-5" data-role="orc-total-real"></div>
                        </div>
                        <div class="col-6 col-md-3">
                            <div class="small text-muted">Orçamento</div>
                            <div class="fw-semibold fs-5" data-role="orc-total-orc"></div>
                        </div>
                        <div class="col-6 col-md-3">
                            <div class="small text-muted">Saldo disponível</div>
                            <div class="fw-semibold fs-5" data-role="orc-total-saldo"></div>
                        </div>
                        <div class="col-6 col-md-3" data-role-wrap="orc-total-proj" style="display:none;">
                            <div class="small text-muted">Projeção de gasto</div>
                            <div class="fw-semibold fs-5" data-role="orc-total-proj"></div>
                        </div>
                    </div>

                    <div class="row g-3 mt-2 align-items-stretch">
                        <div class="col-12 col-lg-8">
                            <div class="text-uppercase small text-secondary fw-semibold">Termômetro financeiro (agrupado)</div>
                            <div class="mt-2" style="height: 320px;">
                                <canvas id="chart-orcamento-termometro"></canvas>
                            </div>
                        </div>
                        <div class="col-12 col-lg-4">
                            <div class="text-uppercase small text-secondary fw-semibold">Consumo do orçamento</div>
                            <div class="d-flex gap-3 align-items-center mt-2">
                                <div style="width: 160px; height: 160px;" class="flex-shrink-0">
                                    <canvas id="chart-orcamento-consumo"></canvas>
                                </div>
                                <div class="flex-grow-1">
                                    <div class="small text-muted">% consumido</div>
                                    <div class="fw-bold" style="font-size: 1.35rem;" data-role="orc-consumo-perc"></div>
                                    <div class="small text-muted">Gasto / Orçamento</div>
                                </div>
                            </div>
                            <hr class="my-2">
                            <div class="text-uppercase small text-secondary fw-semibold mb-2">Mini ranking de atenção</div>
                            <div class="small">
                                <div class="d-flex justify-content-between gap-2">
                                    <div class="text-muted">Maior consumo:</div>
                                    <div class="fw-semibold text-end" data-role="orc-ranking-maior">-</div>
                                </div>
                                <div class="d-flex justify-content-between gap-2 mt-1">
                                    <div class="text-muted">Menor consumo:</div>
                                    <div class="fw-semibold text-end" data-role="orc-ranking-menor">-</div>
                                </div>
                            </div>

                            <hr class="my-2">
                            <div class="text-uppercase small text-secondary fw-semibold mb-2">Empresas (consumo)</div>
                            <div class="small">
                                <div class="d-flex justify-content-between gap-2">
                                    <div class="text-muted">Menor consumo:</div>
                                    <div class="fw-semibold text-end" data-role="orc-emp-melhor">-</div>
                                </div>
                                <div class="d-flex justify-content-between gap-2 mt-1">
                                    <div class="text-muted">Maior consumo:</div>
                                    <div class="fw-semibold text-end" data-role="orc-emp-pior">-</div>
                                </div>
                                <div class="d-flex justify-content-between gap-2 mt-1">
                                    <div class="text-muted">Acima de 90%:</div>
                                    <div class="fw-semibold text-end" data-role="orc-emp-criticos" tabindex="0" role="button" style="cursor: help;">-</div>
                                </div>
                            </div>
                        </div>
                    </div>
                <?php else: ?>

                <div class="row g-2 mt-2">
                    <div class="col-12 col-md-3">
                        <div class="small text-muted"><?= htmlspecialchars($realizadoLabel) ?></div>
                        <div class="fw-semibold fs-5" data-role="total-real"></div>
                    </div>
                    <div class="col-12 col-md-3">
                        <div class="small text-muted"><?= htmlspecialchars($planejadoLabel) ?></div>
                        <div class="fw-semibold fs-5" data-role="total-orc"></div>
                    </div>
                    <div class="col-12 col-md-3" data-role-wrap="total-proj" style="display:none;">
                        <div class="small text-muted">Projeção (Total)</div>
                        <div class="fw-semibold fs-5" data-role="total-proj"></div>
                    </div>
                    <div class="col-12 col-md-3">
                        <div class="small text-muted"><?= htmlspecialchars($percentLabel) ?></div>
                        <div class="fw-bold fs-5" data-role="perc-total"></div>
                    </div>
                </div>

                <div class="row g-2 mt-2 small">
                    <div class="col-12 col-md-4">
                        <div class="text-muted">Melhor desempenho</div>
                        <div class="fw-semibold" data-role="melhor"></div>
                    </div>
                    <div class="col-12 col-md-4">
                        <div class="text-muted">Menor desempenho</div>
                        <div class="fw-semibold" data-role="pior"></div>
                    </div>
                    <div class="col-12 col-md-4">
                        <div class="text-muted"><?= htmlspecialchars($criticoLabel) ?></div>
                        <div class="fw-semibold" data-role="criticos" tabindex="0" role="button" style="cursor: help;"></div>
                    </div>
                </div>

                <div class="mt-3" style="height: 340px;">
                    <canvas id="chart-modelo-<?= htmlspecialchars($modeloBloco) ?>"></canvas>
                </div>
                <?php endif; ?>
            </div>
        </div>
    <?php endforeach; ?>
</div>
<?php endif; ?>



<?php if (!empty($kpisVariaveis) && $visaoDashboard !== 'modelo'): ?>
<div class="mb-4 kpi-variable-grid">
    <?php foreach ($kpisVariaveis as $kpiVar): 
        $mascaraVar   = $mascaraPorVariavel[$kpiVar['id']] ?? 'moeda';
        $modelo       = $modeloPorVariavel[$kpiVar['id']] ?? 'orcamento';
        $lang         = obterLinguagem($modelo);
        $isOrcamentoVar = (strtolower(trim((string)$modelo)) === 'orcamento');
        
        // Cores baseadas na PROJEÇÃO do MÊS, TRIMESTRE e ANO
        $classeCorMes = obterClasseCorProjecao($kpiVar['projMesPerc'], $modelo);
        $classeCorTrim = obterClasseCorProjecao($kpiVar['projTrimPerc'], $modelo);
        $classeCorAno = obterClasseCorProjecao($kpiVar['projAnoPerc'], $modelo);
        
        $classeVarMesVar = 'text-muted';
        if ($kpiVar['varMes'] !== null) {
            $classeVarMesVar = ($kpiVar['varMes'] >= 0) ? 'text-success' : 'text-danger';
        }
        
        $classeVarTrimVar = 'text-muted';
        if ($kpiVar['varTrim'] !== null) {
            $classeVarTrimVar = $isOrcamentoVar
                ? (($kpiVar['varTrim'] >= 0) ? 'text-danger' : 'text-success')
                : (($kpiVar['varTrim'] >= 0) ? 'text-success' : 'text-danger');
        }
        
        $classeVarAnoVar = 'text-muted';
        if ($kpiVar['varAno'] !== null) {
            $classeVarAnoVar = ($kpiVar['varAno'] >= 0) ? 'text-success' : 'text-danger';
        }
        
        // Calcula percentuais do mês
        $percMes = ($kpiVar['orcMes'] != 0.0) ? ($kpiVar['realMes'] / $kpiVar['orcMes']) : 0.0;
        $restanteMes = max(0.0, 1.0 - $percMes);
        
        // Calcula percentuais do trimestre
        $percTrim = ($kpiVar['orcTrim'] != 0.0) ? ($kpiVar['realTrim'] / $kpiVar['orcTrim']) : 0.0;
        $restanteTrim = max(0.0, 1.0 - $percTrim);
        
        // Calcula percentuais do ano
        $percAno = ($kpiVar['orcAno'] != 0.0) ? ($kpiVar['realAno'] / $kpiVar['orcAno']) : 0.0;
        $restanteAno = max(0.0, 1.0 - $percAno);
        
        // Calcula média diária necessária para bater a meta no mês
        // Regra: se o filtro global de mês NÃO for exatamente o mês corrente (ou for multi-mês), a média diária deve ser 0.
        $isMesCorrenteSelecionado = ((int)$anoFiltro === (int)$anoCorrente
            && is_array($mesesSelecionados)
            && count($mesesSelecionados) === 1
            && (int)$mesesSelecionados[0] === (int)$mesCorrente);

        $mediaDiariaMetaMes = 0.0;
        if ($isMesCorrenteSelecionado && $diasRestantesMesCorrente > 0) {
            $mediaDiariaMetaMes = max(0.0, ($kpiVar['orcMes'] - $kpiVar['realMes']) / $diasRestantesMesCorrente);
        }
        
        // Calcula média diária necessária para bater a meta no trimestre
        // Regra: só calcula se for ano corrente e trimestre corrente (o filtro global de mês não interfere aqui)
        $trimestreSistemaVar = (int)ceil($mesCorrente / 3);
        $trimestreRefVar = ($trimestreFiltro > 0 && $trimestreFiltro <= 4) ? (int)$trimestreFiltro : $trimestreSistemaVar;
        $isTrimestreCorrenteSelecionado = ((int)$anoFiltro === (int)$anoCorrente && $trimestreRefVar === $trimestreSistemaVar);

        // Dias restantes do trimestre = dias totais do trimestre - dias já decorridos
        $mesesFinalTrimVar = (int)($trimestreRefVar * 3);
        $mesesInicioTrimVar = (int)(($trimestreRefVar - 1) * 3 + 1);
        
        $diasTrimTotalVar = 0;
        for ($m = $mesesInicioTrimVar; $m <= $mesesFinalTrimVar; $m++) {
            if ($m <= 12) {
                $diasTrimTotalVar += (int)date('t', strtotime($anoref . '-' . str_pad($m, 2, '0', STR_PAD_LEFT) . '-01'));
            }
        }
        
        $diasTrimDecorridosVar = 0;
        if ($mesCorrente < $mesesInicioTrimVar) {
            $diasTrimDecorridosVar = 0;
        } elseif ($mesCorrente > $mesesFinalTrimVar) {
            $diasTrimDecorridosVar = $diasTrimTotalVar;
        } else {
            for ($m = $mesesInicioTrimVar; $m < $mesCorrente; $m++) {
                $diasTrimDecorridosVar += (int)date('t', strtotime($anoref . '-' . str_pad((string)$m, 2, '0', STR_PAD_LEFT) . '-01'));
            }
            $diasTrimDecorridosVar += $diaCorrente;
        }
        
        $diasRestantesTrimestre = max(0, $diasTrimTotalVar - $diasTrimDecorridosVar);
        
        $mediaDiariaMetaTrim = 0.0;
        if ($isTrimestreCorrenteSelecionado && $diasRestantesTrimestre > 0) {
            $mediaDiariaMetaTrim = max(0.0, ($kpiVar['orcTrim'] - $kpiVar['realTrim']) / $diasRestantesTrimestre);
        }
        
        // Calcula média diária necessária para bater a meta no ano
        // Regra: só calcula no ano corrente
        $mediaDiariaMetaAno = 0.0;
        if ((int)$anoFiltro === (int)$anoCorrente && $diasRestantesAno > 0) {
            $mediaDiariaMetaAno = max(0.0, ($kpiVar['orcAno'] - $kpiVar['realAno']) / $diasRestantesAno);
        }
        
        // Variação do mês (vs mês anterior)
        $varMesAnterior = $kpiVar['varMes'] ?? null;
        $classeVarMesVar = 'text-muted';
        if ($varMesAnterior !== null) {
            // Para orçamento, aumento do gasto é pior (vermelho)
            $classeVarMesVar = $isOrcamentoVar
                ? (($varMesAnterior >= 0) ? 'text-danger' : 'text-success')
                : (($varMesAnterior >= 0) ? 'text-success' : 'text-danger');
        }
        
        // Variação do ano (vs ano anterior)
        $classeVarAnoVar = 'text-muted';
        if ($kpiVar['varAno'] !== null) {
            $classeVarAnoVar = $isOrcamentoVar
                ? (($kpiVar['varAno'] >= 0) ? 'text-danger' : 'text-success')
                : (($kpiVar['varAno'] >= 0) ? 'text-success' : 'text-danger');
        }
    ?>
    <div class="kpi-variable-card" data-kpi-id="<?= (int)$kpiVar['id'] ?>">
        <div class="card-body">
            <!-- Cabeçalho com Título, Badge e Toggle -->
            <div class="d-flex justify-content-between align-items-center mb-2 gap-2 flex-wrap">
                <div class="flex-grow-1 min-w-0">
                    <h5 class="mb-1 text-truncate"><?= htmlspecialchars($kpiVar['nome']) ?></h5>
                    <small class="text-muted text-truncate d-block"><?= htmlspecialchars($lang['descricao']) ?></small>
                </div>
                <div class="d-flex align-items-center gap-2 flex-shrink-0">
                    <span class="badge bg-secondary text-nowrap"><?= ucfirst($modelo) ?></span>
                    <div class="btn-group btn-group-sm kpi-period-toggle" role="group">
                        <button type="button" class="btn btn-outline-secondary active" data-period="mes">Mês</button>
                        <button type="button" class="btn btn-outline-secondary" data-period="trimestre">Trimestre</button>
                        <button type="button" class="btn btn-outline-secondary" data-period="ano">Ano</button>
                    </div>
                </div>
            </div>
            
            <!-- Cards de dados (Mês por padrão, Ano oculto) -->
            <div class="kpi-period-content" data-period="mes">
                <div class="kpi-compact">
                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['planejado']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['orcMes'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['planejado']) ?> do mês</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['realizado']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['realMes'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Valor já <?= strtolower($lang['realizado']) ?></div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard(max(0, $kpiVar['orcMes'] - $kpiVar['realMes']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Saldo disponível' : 'Saldo a realizar' ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= $isOrcamentoVar ? 'Gasto Diário' : 'Média Diária para Meta' ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($mediaDiariaMetaMes, $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Máximo por dia' : 'Por dia' ?> (<?= $diasRestantesMesCorrente ?> dias)</div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['projecao']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorMes ?> text-nowrap"><?= formatarValorDashboard(abs($kpiVar['projMesValor']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Expectativa (<span class="<?= $classeCorMes ?>"><?= formatarPercentDashboard(abs($kpiVar['projMesPerc'])) ?></span>)</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['vs_anterior']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeVarMesVar ?> text-nowrap"><?= formatarValorDashboard($kpiVar['realMesAnt'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">
                                Vs <?= formatarValorDashboard($kpiVar['realMes'], $mascaraVar, $moeda) ?>
                                <?php if ($varMesAnterior !== null): ?>
                                    <span class="<?= $classeVarMesVar ?>">(<?= ($varMesAnterior >= 0 ? '+' : '') . formatarPercentDashboard($varMesAnterior) ?>)</span>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorMes ?> text-nowrap"><?= formatarPercentDashboard($restanteMes) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['restante_desc']) ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['percentual_label']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorMes ?> text-nowrap"><?= formatarPercentDashboard($percMes) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['percentual_desc']) ?></div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- Cards de dados - TRIMESTRE (oculto por padrão) -->
            <div class="kpi-period-content d-none" data-period="trimestre">
                <div class="kpi-compact">
                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['planejado']) ?> (Trimestre)</div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['orcTrim'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['planejado']) ?> do trimestre</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['realizado']) ?> (Trimestre)</div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['realTrim'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Valor já <?= strtolower($lang['realizado']) ?></div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard(max(0, $kpiVar['orcTrim'] - $kpiVar['realTrim']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Saldo disponível' : 'Saldo a realizar' ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= $isOrcamentoVar ? 'Gasto Diário' : 'Média Diária para Meta' ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($mediaDiariaMetaTrim, $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Máximo por dia' : 'Necessário por dia' ?> (<?= $diasRestantesTrimestre ?> dias)</div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['projecao']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorTrim ?> text-nowrap"><?= formatarValorDashboard(abs($kpiVar['projTrimValor']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Expectativa (<span class="<?= $classeCorTrim ?>"><?= formatarPercentDashboard(abs($kpiVar['projTrimPerc'])) ?></span>)</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['vs_anterior']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeVarTrimVar ?> text-nowrap"><?= formatarValorDashboard($kpiVar['realTrimAnt'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">
                                Vs <?= formatarValorDashboard($kpiVar['realTrim'], $mascaraVar, $moeda) ?>
                                <?php if ($kpiVar['varTrim'] !== null): ?>
                                    <span class="<?= $classeVarTrimVar ?>"> (<?= ($kpiVar['varTrim'] >= 0 ? '+' : '') . formatarPercentDashboard($kpiVar['varTrim']) ?>)</span>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorTrim ?> text-nowrap"><?= formatarPercentDashboard($restanteTrim) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['restante_desc']) ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['percentual_label']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorTrim ?> text-nowrap"><?= formatarPercentDashboard($percTrim) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['percentual_desc']) ?></div>
                        </div>
                    </div>
                </div>
            </div>
            
            <!-- Cards de dados - ANO (oculto por padrão) -->
            <div class="kpi-period-content d-none" data-period="ano">
                <div class="kpi-compact">
                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['planejado']) ?> (Ano)</div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['orcAno'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['planejado']) ?> do ano</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['realizado']) ?> (Ano)</div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($kpiVar['realAno'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Valor já <?= strtolower($lang['realizado']) ?></div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard(max(0, $kpiVar['orcAno'] - $kpiVar['realAno']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Saldo disponível' : 'Saldo a realizar' ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= $isOrcamentoVar ? 'Gasto Diário' : 'Média Diária para Meta' ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value text-nowrap"><?= formatarValorDashboard($mediaDiariaMetaAno, $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= $isOrcamentoVar ? 'Máximo por dia' : 'Necessário por dia' ?> (<?= $diasRestantesAno ?> dias)</div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['projecao']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorAno ?> text-nowrap"><?= formatarValorDashboard(abs($kpiVar['projAnoValor']), $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">Expectativa (<span class="<?= $classeCorAno ?>"><?= formatarPercentDashboard(abs($kpiVar['projAnoPerc'])) ?></span>)</div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['vs_anterior']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeVarAnoVar ?> text-nowrap"><?= formatarValorDashboard($kpiVar['realAnoAnt'], $mascaraVar, $moeda) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap">
                                Vs <?= formatarValorDashboard($kpiVar['realAno'], $mascaraVar, $moeda) ?>
                                <?php if ($kpiVar['varAno'] !== null): ?>
                                    <span class="<?= $classeVarAnoVar ?>"> (<?= ($kpiVar['varAno'] >= 0 ? '+' : '') . formatarPercentDashboard($kpiVar['varAno']) ?>)</span>
                                <?php endif; ?>
                            </div>
                        </div>
                    </div>

                    <div class="kpi-row">
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['restante']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorAno ?> text-nowrap"><?= formatarPercentDashboard($kpiVar['restantePerc']) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['restante_desc']) ?></div>
                        </div>
                        <div class="kpi-cell">
                            <div class="kpi-label"><?= htmlspecialchars($lang['percentual_label']) ?></div>
                            <div class="kpi-value-line">
                                <span class="kpi-value <?= $classeCorAno ?> text-nowrap"><?= formatarPercentDashboard($kpiVar['atingPerc']) ?></span>
                            </div>
                            <div class="kpi-sub text-muted text-nowrap"><?= htmlspecialchars($lang['percentual_desc']) ?></div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
    <?php endforeach; ?>
</div>
<?php endif; ?>
</div>



<style>
/* Grid responsivo para cards de metas */
.dashboard-metas-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}
@media (min-width: 768px) {
    .dashboard-metas-grid {
        grid-template-columns: repeat(2, minmax(300px, 1fr));
    }
}
@media (min-width: 992px) {
    .dashboard-metas-grid {
        grid-template-columns: repeat(3, minmax(320px, 1fr));
    }
}
@media (min-width: 1400px) {
    .dashboard-metas-grid {
        grid-template-columns: repeat(4, minmax(340px, 1fr));
    }
}

/* Histórico dos últimos 7 dias - Tabela estilo planilha compacta */
.historico-tabela {
    width: 100%;
    min-width: auto;
    border-collapse: collapse;
    font-size: 0.8rem;
    margin: 0;
    padding: 0;
}

.historico-tabela tbody tr {
    margin: 0;
    padding: 0;
}

.historico-tabela td {
    padding: 2px 1px;
    text-align: center;
    vertical-align: middle;
    border: none;
    margin: 0;
    white-space: nowrap;
}

.historico-dia-data {
    font-size: 0.7rem;
    color: #64748b;
    font-weight: 500;
    white-space: nowrap;
    line-height: 1;
    margin: 0;
    padding: 0;
    text-transform: lowercase;
}

.historico-dia-valor {
    font-size: 1.1rem;
    font-weight: 600;
    color: #000;
    white-space: nowrap;
    line-height: 1.1;
    margin: 0;
    padding: 0;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Mobile: reduz ainda mais */
@media (max-width: 576px) {
    .historico-tabela {
        font-size: 0.75rem;
    }
    .historico-tabela td {
        padding: 1px 0.5px;
    }
    .historico-dia-data {
        font-size: 0.65rem;
    }
    .historico-dia-valor {
        font-size: 0.95rem;
    }
}


/* Card horizontal estilo imagem */
.dashboard-card-horizontal {
    background: linear-gradient(145deg, #f8f9fa, #ffffff);
    border-radius: 8px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.03);
    min-height: 160px;
}
.dashboard-card-horizontal:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0,0,0,0.08);
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.dashboard-card-horizontal .card-body {
    padding: 16px;
}
.dashboard-chart-wrapper-donut-horizontal {
    position: relative;
    width: 140px;
    height: 140px;
    flex-shrink: 0;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dashboard-chart-wrapper-donut-horizontal canvas {
    max-width: 100%;
    max-height: 100%;
}
.donut-metric-horizontal {
    font-size: 2rem;
    font-weight: 700;
    line-height: 1;
}
.donut-legend-horizontal {
    display: flex;
    flex-direction: column;
    gap: 6px;
    min-width: 0;
}
.donut-legend-horizontal .legend-item-horizontal {
    display: flex;
    align-items: center;
    gap: 8px;
    color: #6b7280;
    font-size: 0.9rem;
    min-width: 0;
}
.donut-legend-horizontal .legend-item-horizontal span:first-child {
    flex-shrink: 0;
}
.donut-legend-horizontal .legend-item-horizontal span:nth-child(2) {
    min-width: 0;
    flex: 0 1 auto;
}
.donut-legend-horizontal .legend-item-horizontal span:last-child {
    white-space: nowrap;
    font-weight: 600;
}
.donut-legend-horizontal .legend-box-horizontal {
    width: 16px;
    height: 6px;
    border-radius: 2px;
    display: inline-block;
    flex-shrink: 0;
}

/* Responsividade para mobile */
@media (max-width: 768px) {
    .dashboard-card-horizontal {
        min-height: auto;
    }
    .dashboard-card-horizontal .card-body {
        flex-direction: column;
        gap: 1rem;
        padding: 12px;
    }
    .dashboard-chart-wrapper-donut-horizontal {
        width: 120px;
        height: 120px;
    }
    .donut-metric-horizontal {
        font-size: 1.75rem;
    }
    .donut-legend-horizontal .legend-item-horizontal {
        font-size: 0.85rem;
    }
}
.kpi-card {
    background: linear-gradient(135deg, #f8fafc, #ffffff);
    border-radius: 8px;
}
.dashboard-chart-wrapper-line {
    position: relative;
    height: 280px;
}
.kpi-label {
    letter-spacing: 0.03em;
}
.kpi-icon {
    font-size: 1.2rem;
}
.dashboard-chart-wrapper {
    position: relative;
    height: 260px;
}
/* Grid super compacto para cards em desktop */
#dashboardChartsContainer .row.g-3 {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 10px;
    align-items: stretch;
}
#dashboardChartsContainer .col-12.col-sm-6.col-lg-4.col-xl-3 {
    padding: 0;
    margin: 0;
}
.dashboard-card .card-body {
    padding: 8px 8px 6px 8px;
}
.dashboard-card .mb-2, .dashboard-card .mb-1, .dashboard-card .mb-0 {
    margin-bottom: 0.18rem !important;
}
.dashboard-card .small {
    font-size: 0.92em;
}
.dashboard-card .fw-semibold {
    font-weight: 500 !important;
}
/* Pequenas interações para desktop */
.dashboard-card {
    transition: transform 0.2s ease, box-shadow 0.2s ease;
}
.dashboard-card:hover {
    transform: translateY(-2px);
    box-shadow: 0 6px 16px rgba(0,0,0,0.08);
}
/* Melhorias de layout para desktop (estilo semelhante ao mobile) */
@media (min-width: 992px) {
    #dashboardCardsContainer .row.g-3 {
        grid-template-columns: repeat(auto-fill, minmax(260px, 1fr));
        gap: 12px;
    }
    .dashboard-card {
        border-radius: 12px;
        box-shadow: 0 2px 10px rgba(0,0,0,0.06);
        padding: 16px 14px 10px 14px;
        background: linear-gradient(145deg, #f8fafc, #ffffff);
    }
    .dashboard-card .card-body {
        padding: 0; /* já aplicamos padding no card para ficar como mobile */
    }
    .dashboard-card .small {
        font-size: 0.95em;
    }
}
@media (min-width: 1200px) {
    #dashboardCardsContainer .row.g-3 {
        grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
        gap: 16px;
    }
}
@media (min-width: 1400px) {
    .dashboard-chart-wrapper {
        height: 320px;
    }
    #dashboardCardsContainer .row.g-3 {
        grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
    }
}
@media (max-width: 768px) {
    .dashboard-card {
        border-radius: 10px;
        padding: 16px 10px 0 10px;
    }
    .kpi-card {
        border-radius: 10px;
    }
    .dashboard-chart-wrapper-line {
        height: 220px;
    }
    .dashboard-chart-wrapper {
        height: 220px;
    }
    .dashboard-chart-wrapper-donut {
        max-width: 200px;
    }
    .kpi-icon {
        font-size: 1.2rem;
    }
    #dashboardCardsContainer .row.g-3 {
        display: flex;
        flex-wrap: wrap;
        gap: 1rem;
    }
    #dashboardCardsContainer .col-12.col-sm-6.col-lg-4.col-xl-3 {
        width: 100%;
        max-width: 100%;
    }
}
.dashboard-chart-wrapper-donut {
    position: relative;
    width: 100%;
    max-width: 240px;
    aspect-ratio: 1 / 1;
    margin: 0 auto;
    display: flex;
    align-items: center;
    justify-content: center;
}
.dashboard-chart-wrapper-donut canvas {
    max-width: 100%;
    max-height: 100%;
}
.chart-card-grid {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
    gap: 10px;
    align-items: stretch;
}
/* Grid responsivo para os cards de variáveis */
.kpi-variable-grid {
    display: grid;
    grid-template-columns: 1fr;
    gap: 12px;
}

@media (min-width: 768px) {
    .kpi-variable-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 14px;
    }
}

@media (min-width: 992px) {
    .kpi-variable-grid {
        grid-template-columns: repeat(2, 1fr);
        gap: 16px;
    }
}

@media (min-width: 1400px) {
    .kpi-variable-grid {
        grid-template-columns: repeat(3, 1fr);
        gap: 18px;
    }
}

@media (min-width: 1800px) {
    .kpi-variable-grid {
        grid-template-columns: repeat(4, 1fr);
        gap: 20px;
    }
}

/* Estilo dos KPI Cards */
.kpi-variable-card {
    background: #ffffff;
    border-radius: 12px;
    box-shadow: 0 2px 8px rgba(0,0,0,0.05);
    border: 1px solid rgba(0,0,0,0.04);
    overflow: hidden;
    transition: box-shadow 0.2s ease;
}

.kpi-variable-card:hover {
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
}

.kpi-variable-card .card-body {
    padding: 12px;
}

.kpi-variable-card h5 {
    font-size: 13px;
    font-weight: 700;
    margin-bottom: 6px;
    line-height: 1.15;
}

.kpi-variable-card .small {
    font-size: 0.75rem;
}

/* ==== ORÇAMENTO CONSOLIDADO - CARD SEÇÃO GRÁFICOS ==== */
.dashboard-card-orcamento-consolidado {
    background: #ffffff;
    border: 1px solid rgba(0, 0, 0, 0.06);
}

.dashboard-card-orcamento-consolidado:hover {
    box-shadow: 0 6px 16px rgba(0, 0, 0, 0.08) !important;
}

/* Layout em duas colunas para detalhamento */
.orc-detalhado-container {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: 20px;
    align-items: start;
}

/* Coluna Esquerda: Barras Horizontais */
.orc-detalhado-barras {
    display: flex;
    flex-direction: column;
    gap: 12px;
}

.orc-linha-item {
    display: flex;
    flex-direction: column;
    gap: 4px;
}

.orc-nome-conta {
    font-size: 0.8rem;
    color: #4b5563;
    text-transform: uppercase;
    letter-spacing: 0.05em;
    max-width: 100%;
}

.orc-barra-horizontal-wrapper {
    position: relative;
    height: 24px;
}

.orc-barra-horizontal-fundo {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #f3f4f6;
    border-radius: 4px;
    border: 1px solid #e5e7eb;
    z-index: 0;
}

.orc-barra-horizontal-container {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    z-index: 1;
}

.orc-barra-horizontal {
    height: 100%;
    border-radius: 3px;
    transition: width 0.3s ease;
    box-shadow: 0 2px 6px rgba(0, 0, 0, 0.12);
    min-width: 2px;
}

/* Cores das barras baseadas no percentual */
.orc-barra-verde {
    color: #059669;
}

.orc-barra-amarelo {
    color: #d97706;
}

.orc-barra-vermelho {
    color: #dc2626;
}

.orc-percentual-barra {
    font-size: 0.75rem;
    text-align: right;
    padding-right: 2px;
}

.orc-percentual-barra.orc-barra-verde {
    color: #059669;
}

.orc-percentual-barra.orc-barra-amarelo {
    color: #d97706;
}

.orc-percentual-barra.orc-barra-vermelho {
    color: #dc2626;
}

/* Coluna Direita: Valores */
.orc-detalhado-valores {
    display: flex;
    flex-direction: column;
    gap: 12px;
    padding-left: 12px;
    border-left: 1px solid #f3f4f6;
}

.orc-linha-valores {
    display: grid;
    grid-template-columns: repeat(3, 1fr);
    gap: 8px;
    font-size: 0.8rem;
}

.orc-valor-item {
    text-align: center;
    padding: 6px;
    background: #f9fafb;
    border-radius: 4px;
    border: 1px solid #e5e7eb;
}

.orc-valor-item .text-muted {
    font-size: 0.65rem;
    margin-bottom: 2px;
}

.orc-valor-item .fw-semibold {
    font-size: 0.8rem;
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}

/* Responsividade para tablet/mobile */
@media (max-width: 1024px) {
    .orc-detalhado-container {
        grid-template-columns: 1fr;
        gap: 16px;
    }
    
    .orc-detalhado-valores {
        border-left: none;
        border-top: 1px solid #f3f4f6;
        padding-left: 0;
        padding-top: 12px;
    }
}

@media (max-width: 768px) {
    .orc-detalhado-container {
        gap: 12px;
    }
    
    .orc-linha-valores {
        grid-template-columns: repeat(3, 1fr);
        gap: 6px;
    }
    
    .orc-valor-item {
        padding: 4px;
        font-size: 0.75rem;
    }
    
    .orc-barra-horizontal-wrapper {
        height: 20px;
    }
    
    .dashboard-card-horizontal .card-body {
        padding: 12px;
    }
}

/* Grid super compacto em mobile */
@media (max-width: 576px) {
    .orc-linha-item {
        gap: 3px;
    }
    
    .orc-nome-conta {
        font-size: 0.7rem;
    }
    
    .orc-barra-horizontal-wrapper {
        height: 18px;
    }
    
    .orc-percentage {
        font-size: 0.65rem;
    }
    
    .orc-linha-valores {
        grid-template-columns: repeat(3, 1fr);
        gap: 4px;
    }
}

/* Grid compacto em blocos de 2 colunas */

.kpi-compact {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.kpi-row {
    display: grid;
    grid-template-columns: repeat(2, minmax(120px, 1fr));
    gap: 8px 12px;
    align-items: start;
}

.kpi-cell {
    padding: 8px 10px;
    border: 1px solid #e5e7eb;
    border-radius: 8px;
    background: #f9fafb;
    min-width: 0;
}

.kpi-value-line {
    display: flex;
    align-items: baseline;
    gap: 8px;
    min-width: 0;
}

.kpi-sub {
    font-size: 0.72rem;
    color: #6b7280;
    margin-top: 2px;
}

.kpi-progress-inline {
    margin-top: 4px;
}

@media (max-width: 540px) {
    .kpi-row {
        grid-template-columns: repeat(2, minmax(140px, 1fr));
        gap: 10px 12px;
    }
    .kpi-cell {
        padding: 8px 10px;
    }
    .kpi-compact {
        gap: 10px;
    }
}

/* Desktop: mais espaço e melhor distribuição */
@media (min-width: 992px) {
    .kpi-variable-card .card-body {
        padding: 16px 18px;
    }
    
    .kpi-variable-card h5 {
        font-size: 15px;
        margin-bottom: 8px;
    }
    
    .kpi-row { 
        gap: 10px 16px;
    }
}

/* Telas grandes: layout mais respirado */
@media (min-width: 1400px) {
    .kpi-variable-card .card-body {
        padding: 18px 20px;
    }
    
    .kpi-variable-card h5 {
        font-size: 16px;
    }
    
    .kpi-row { 
        gap: 12px 18px;
    }
}

/* Toggle de período (Mês/Ano) */
.kpi-period-toggle {
    border-radius: 5px;
    overflow: hidden;
}

.kpi-period-toggle .btn {
    padding: 3px 8px;
    font-size: 0.8rem;
    border: none;
}

.kpi-period-toggle .btn.active {
    background-color: #495057;
    color: white;
    border-color: #495057;
}

/* Items de KPI */
.kpi-item {
    text-align: left;
    display: flex;
    flex-direction: column;
    gap: 0px;
}

.kpi-label {
    font-size: 0.7rem;
    color: #6b7280;
    font-weight: 600;
    line-height: 1.1;
    text-transform: uppercase;
    letter-spacing: 0.3px;
    margin-bottom: 2px;
}

.kpi-value {
    font-size: clamp(0.8rem, 1.5vw, 1.1rem);
    font-weight: 700;
    line-height: 1.25;
    white-space: nowrap;
    max-width: 100%;
}

/* Mobile: valores mais compactos */
@media (max-width: 480px) {
    .kpi-value {
        font-size: clamp(1.05rem, 3vw, 1.25rem);
    }
    
    .kpi-label {
        font-size: 0.65rem;
    }
}

/* Tablet: tamanho intermediário */
@media (min-width: 481px) and (max-width: 991px) {
    .kpi-value {
        font-size: clamp(0.75rem, 1.5vw, 1.0rem);
    }
}

/* Desktop: valores maiores e mais legíveis */
@media (min-width: 992px) {
    .kpi-value {
        font-size: clamp(0.9rem, 1.3vw, 1.2rem);
    }
    
    .kpi-label {
        font-size: 0.75rem;
        margin-bottom: 3px;
    }
}

/* Telas grandes: máxima legibilidade */
@media (min-width: 1400px) {
    .kpi-value {
        font-size: clamp(1.0rem, 1.2vw, 1.3rem);
    }
    
    .kpi-label {
        font-size: 0.78rem;
    }
}

.kpi-value.text-success,
.kpi-value.text-warning,
.kpi-value.text-danger {
    font-weight: 700;
}

.kpi-item small {
    font-size: 0.68rem;
    line-height: 1.2;
    color: #6b7280;
    margin-top: 2px;
    word-wrap: break-word;
    overflow-wrap: break-word;
}

@media (min-width: 992px) {
    .kpi-item small {
        font-size: 0.72rem;
        margin-top: 3px;
    }
}

@media (min-width: 1400px) {
    .kpi-item small {
        font-size: 0.75rem;
    }
}

/* Barra de Progresso Subtle */
.kpi-progress-bar {
    height: 4px;
    background-color: #e5e7eb;
    border-radius: 2px;
    overflow: hidden;
    cursor: pointer;
    position: relative;
    margin-top: 8px;
}

.kpi-progress-bar .progress-indicator {
    height: 100%;
    border-radius: 2px;
    transition: width 0.3s ease;
}

.kpi-progress-bar:hover .progress-indicator {
    box-shadow: 0 0 4px rgba(0,0,0,0.15);
}

@media (min-width: 992px) {
    .kpi-progress-bar {
        margin-top: 10px;
    }
}
</style>

<!-- Modal Sincronização Automática -->
<div class="modal fade" id="modalSyncAuto" tabindex="-1" data-bs-backdrop="static" data-bs-keyboard="false">
  <div class="modal-dialog modal-md modal-dialog-centered">
    <div class="modal-content">
      <div class="modal-header bg-warning py-2">
        <h6 class="modal-title"><i class="bi bi-arrow-repeat"></i> Sincronizando ERP (período automático)</h6>
        <button type="button" class="btn-close" data-bs-dismiss="modal" id="btnFecharSync"></button>
      </div>
      <div class="modal-body">
        <div id="syncResultado" class="small"></div>
        <div class="mt-3" id="syncProgresso" style="display:none;">
          <div class="progress mb-2" style="height: 6px;">
            <div class="progress-bar progress-bar-striped progress-bar-animated bg-warning" role="progressbar" style="width: 0%;"></div>
          </div>
          <ul class="small mb-0" id="syncEtapas">
            <li data-step="preparar">1) Preparando sincronização...</li>
            <li data-step="sincronizar">2) Sincronizando com ERP...</li>
            <li data-step="consolidar">3) Consolidando dados...</li>
            <li data-step="atualizar">4) Atualizando dashboard...</li>
          </ul>
        </div>
      </div>
      <div class="modal-footer py-2">
        <button class="btn btn-secondary btn-sm" data-bs-dismiss="modal" id="btnFecharSyncFooter">Fechar</button>
      </div>
    </div>
  </div>
</div>

<!-- Chart.js e inicialização dos gráficos do dashboard -->
<script src="https://cdn.jsdelivr.net/npm/chart.js@4.4.1/dist/chart.umd.min.js"></script>
<script>
    const dashboardChartData = <?= json_encode($chartData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>; // atualmente não usado, mantido para futuras evoluções
    const dashboardMoeda     = <?= json_encode($moeda, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    const dashboardAnoRef    = <?= (int)$anoref ?>;
    const dashboardMesNome   = <?= json_encode($nomeMesAtual, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    const dashboardMetas = <?= json_encode($metasCharts, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    const dashboardSerieYtd  = <?= json_encode($serieYtd, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    const dashboardModelo    = 'meta';
    const dashboardVisao      = <?= json_encode($visaoDashboard, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES) ?>;
    const dashboardConsolidadoComparativo = <?= json_encode(($dashboardConsolidadoComparativo ?? []), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE) ?>;
    const dashboardOrcamentoTermometro = <?= json_encode(($orcamentoTermometro ?? []), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR | JSON_INVALID_UTF8_SUBSTITUTE) ?>;
    
    // Função de linguagem dinâmica
    function getLinguagem(modelo) {
        if (modelo === 'meta') {
            return {
                realizado: 'Realizado',
                restante: 'A Realizar'
            };
        }
        return {
            realizado: 'Gasto Realizado',
            restante: 'Saldo Disponível'
        };
    }
    
    const dashboardLinguagem = getLinguagem(dashboardModelo);

    document.addEventListener('DOMContentLoaded', function () {
        // Toggle Mês/Ano nos KPI Cards
        function initKpiToggle() {
            document.querySelectorAll('.kpi-period-toggle').forEach((toggle) => {
                toggle.querySelectorAll('.btn').forEach((btn) => {
                    btn.addEventListener('click', (e) => {
                        e.preventDefault();
                        const period = btn.getAttribute('data-period');
                        const card = btn.closest('.kpi-variable-card');
                        if (!card) return;
                        
                        // Remove active de todos os botões do toggle
                        toggle.querySelectorAll('.btn').forEach((b) => {
                            b.classList.remove('active');
                        });
                        // Marca o clicado como ativo
                        btn.classList.add('active');
                        
                        // Oculta todos os períodos
                        card.querySelectorAll('.kpi-period-content').forEach((content) => {
                            content.classList.add('d-none');
                        });
                        // Mostra o período selecionado
                        const contentToShow = card.querySelector(`.kpi-period-content[data-period="${period}"]`);
                        if (contentToShow) {
                            contentToShow.classList.remove('d-none');
                        }
                    });
                });
            });
        }
        
        function formatValor(v) {
            if (!dashboardMoeda) return v.toFixed(2);
            const simbolo = dashboardMoeda.simbolo || 'R$';
            const formato = dashboardMoeda.formato || 'decimal';
            const casas   = (formato === 'inteiro') ? 0 : 2;
            return simbolo + ' ' + v.toLocaleString('pt-BR', { minimumFractionDigits: casas, maximumFractionDigits: casas });
        }

        function formatPercent(p) {
            const v = (p * 100);
            return v.toFixed(1).replace('.', ',') + ' %';
        }

        function toneColor(p) {
            // p é agora a projeção, não o percentual atingido
            if (p >= 1.0) return '#16a34a'; // verde
            if (p >= 0.95) return '#f59e0b'; // amarelo
            return '#dc2626'; // vermelho
        }

        function toneColorByModelo(modelo, p) {
            const v = Number(p || 0);
            if (modelo === 'orcamento') {
                // Orçamento: quanto MENOR o consumo, melhor
                if (v <= 0.80) return '#16a34a'; // verde
                if (v <= 0.90) return '#f59e0b'; // amarelo
                return '#dc2626'; // vermelho
            }
            return toneColor(v);
        }

        // ✅ Tooltip externo (HTML) para não cortar valores
        function externalTooltipHandler(context) {
            const { chart, tooltip } = context;

            let tooltipEl = document.getElementById('chartjs-tooltip');
            if (!tooltipEl) {
                tooltipEl = document.createElement('div');
                tooltipEl.id = 'chartjs-tooltip';
                tooltipEl.style.position = 'fixed';
                tooltipEl.style.pointerEvents = 'none';
                tooltipEl.style.background = 'rgba(17, 24, 39, 0.92)';
                tooltipEl.style.color = '#fff';
                tooltipEl.style.borderRadius = '8px';
                tooltipEl.style.padding = '10px 12px';
                tooltipEl.style.fontSize = '12px';
                tooltipEl.style.lineHeight = '1.2';
                tooltipEl.style.zIndex = '9999';
                tooltipEl.style.whiteSpace = 'nowrap';
                tooltipEl.style.boxShadow = '0 6px 18px rgba(0,0,0,0.18)';
                document.body.appendChild(tooltipEl);
            }

            if (tooltip.opacity === 0) {
                tooltipEl.style.opacity = 0;
                return;
            }

            const lines = tooltip.body?.map(b => b.lines).flat() || [];
            const title = tooltip.title?.[0]
                ? `<div style="font-weight:700;margin-bottom:6px">${tooltip.title[0]}</div>`
                : '';
            tooltipEl.innerHTML = title + lines.map(l => `<div>${l}</div>`).join('');

            const rect = chart.canvas.getBoundingClientRect();
            const x = rect.left + tooltip.caretX;
            const y = rect.top + tooltip.caretY;

            tooltipEl.style.opacity = 1;

            const vw = window.innerWidth;
            const vh = window.innerHeight;
            const pad = 12;

            // posição inicial (próximo do cursor)
            tooltipEl.style.left = `${x + 12}px`;
            tooltipEl.style.top  = `${y + 12}px`;

            // clamp na viewport (evita cortar na borda da tela)
            const bb = tooltipEl.getBoundingClientRect();
            let left = x + 12;
            let top  = y + 12;

            if (left + bb.width + pad > vw) left = vw - bb.width - pad;
            if (top + bb.height + pad > vh) top = vh - bb.height - pad;
            if (left < pad) left = pad;
            if (top < pad) top = pad;

            tooltipEl.style.left = `${left}px`;
            tooltipEl.style.top  = `${top}px`;
        }

        function buildKpiDonuts() {
            if (!window.Chart || !Array.isArray(dashboardMetas)) return;
            
            // Lazy loading com IntersectionObserver
            if ('IntersectionObserver' in window) {
                const observer = new IntersectionObserver((entries) => {
                    entries.forEach(entry => {
                        if (entry.isIntersecting && !entry.target.dataset.chartInit) {
                            const canvas = entry.target;
                            const metaId = canvas.id.replace('chart-kpi-donut-', '');
                            const m = dashboardMetas.find(meta => String(meta.id) === metaId);
                            if (m) {
                                createDonutChart(canvas, m);
                                canvas.dataset.chartInit = 'true';
                                observer.unobserve(canvas);
                            }
                        }
                    });
                }, { rootMargin: '50px' }); // Pré-carrega 50px antes de aparecer
                
                dashboardMetas.forEach((m) => {
                    const cid = 'chart-kpi-donut-' + String(m.id);
                    const ctx = document.getElementById(cid);
                    if (ctx) observer.observe(ctx);
                });
            } else {
                // Fallback: cria todos de uma vez (navegadores antigos)
                dashboardMetas.forEach((m) => {
                    const cid = 'chart-kpi-donut-' + String(m.id);
                    const ctx = document.getElementById(cid);
                    if (ctx) createDonutChart(ctx, m);
                });
            }
        }

        // =============================
        // Visão Consolidada por Modelo (comparativo por empresa)
        // =============================
        const chartsModelos = {}; // key: modelo
        const chartsOrcamento = { bar: null, donut: null };

        const centerTextPlugin = {
            id: 'centerText',
            afterDraw(chart, args, pluginOptions) {
                const opts = pluginOptions || {};
                const text = String(opts.text || '').trim();
                if (!text) return;
                const ctx = chart.ctx;
                const meta = chart.getDatasetMeta(0);
                if (!meta || !meta.data || !meta.data[0]) return;
                const x = meta.data[0].x;
                const y = meta.data[0].y;
                ctx.save();
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                ctx.fillStyle = opts.color || 'rgba(17,24,39,0.92)';
                ctx.font = opts.font || '800 20px system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif';
                ctx.fillText(text, x, y);
                ctx.restore();
            }
        };

        function getModeloLabels(modelo) {
            if (modelo === 'orcamento') {
                return {
                    realizado: 'Gasto Realizado',
                    restante: 'Saldo Disponível',
                    projecao: 'Projeção (total)'
                };
            }
            return {
                realizado: 'Realizado',
                restante: 'A Realizar',
                projecao: 'Projeção (total)'
            };
        }

        function escapeHtml(str) {
            return String(str)
                .replace(/&/g, '&amp;')
                .replace(/</g, '&lt;')
                .replace(/>/g, '&gt;')
                .replace(/"/g, '&quot;')
                .replace(/'/g, '&#039;');
        }

        function hexToRgba(hex, alpha) {
            const h = String(hex || '').replace('#', '').trim();
            if (h.length !== 6) return `rgba(0,0,0,${alpha})`;
            const r = parseInt(h.slice(0, 2), 16);
            const g = parseInt(h.slice(2, 4), 16);
            const b = parseInt(h.slice(4, 6), 16);
            return `rgba(${r},${g},${b},${alpha})`;
        }

        const percentInBarsPlugin = {
            id: 'percentInBars',
            afterDatasetsDraw(chart, args, pluginOptions) {
                const opts = pluginOptions || {};
                const ctx = chart.ctx;
                const totalOrc = Array.isArray(opts.totalOrc) ? opts.totalOrc : [];
                const showProj = !!opts.showProj;
                const showReal = (opts.showReal !== undefined) ? !!opts.showReal : true;
                const showRest = (opts.showRest !== undefined) ? !!opts.showRest : true;
                const showRestBelow = (opts.showRestBelow !== undefined) ? !!opts.showRestBelow : true;
                const showRealBelow = (opts.showRealBelow !== undefined) ? !!opts.showRealBelow : false;

                const idxRealGlobal = chart.data.datasets.findIndex(d => d && d._role === 'real');
                const metaRealGlobal = (idxRealGlobal >= 0) ? chart.getDatasetMeta(idxRealGlobal) : null;

                ctx.save();
                ctx.textAlign = 'center';
                ctx.textBaseline = 'middle';
                // Fonte maior para ficar mais visual no consolidado
                ctx.font = '800 14px system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif';

                chart.data.datasets.forEach((dataset, datasetIndex) => {
                    const meta = chart.getDatasetMeta(datasetIndex);
                    if (!meta || meta.hidden) return;

                    const role = dataset._role;
                    if (role !== 'real' && role !== 'rest' && role !== 'proj') return;
                    if (role === 'proj' && !showProj) return;
                    if (role === 'real' && !showReal) return;
                    if (role === 'rest' && !showRest) return;
                    // Se o realizado será desenhado abaixo (fora do stack), não desenhar dentro.
                    if (role === 'real' && showRealBelow) return;
                    // restante pode ser desenhado abaixo (fora do stack) OU dentro (no segmento cinza)
                    if (role === 'rest' && showRestBelow) return;

                    meta.data.forEach((element, index) => {
                        const v = Number(dataset.data?.[index]);
                        if (!isFinite(v) || v <= 0) return;
                        const base = Number(totalOrc[index] || 0);
                        if (!isFinite(base) || base <= 0) return;

                        const perc = v / base;
                        if (!isFinite(perc) || perc <= 0) return;

                        // Para o restante, quando NÃO estiver no rodapé, desenhar o texto usando o segmento do realizado
                        // (usuário quer o "13%" onde estava o "87%"), sem mexer na projeção.
                        let elementUse = element;
                        let usingRealGeometryForRest = false;
                        if (role === 'rest' && !showRestBelow && metaRealGlobal?.data?.[index]) {
                            elementUse = metaRealGlobal.data[index];
                            usingRealGeometryForRest = true;
                        }

                        if (!elementUse) return;
                        const elY = elementUse.y;
                        const elBase = elementUse.base;
                        if (!isFinite(elY) || !isFinite(elBase)) return;

                        const chartArea = chart.chartArea || { top: 0, bottom: chart.height };

                        // Se o realizado for muito pequeno no ANO (ou em qualquer período), não pode "sumir".
                        // Em vez de abortar, aplicamos fallback de posição.
                        let height = Math.abs(elBase - elY);
                        let isTiny = height < 18;

                        // Caso especial: % A Realizar usa geometria do realizado; se o realizado for minúsculo,
                        // volta a usar o próprio segmento cinza para garantir que o texto apareça.
                        if (role === 'rest' && usingRealGeometryForRest && isTiny) {
                            elementUse = element;
                            usingRealGeometryForRest = false;
                            const y2 = elementUse?.y;
                            const b2 = elementUse?.base;
                            if (!isFinite(y2) || !isFinite(b2)) return;
                            height = Math.abs(b2 - y2);
                            isTiny = height < 18;
                        }

                        const x = elementUse.x;
                        let y = (elY + elBase) / 2;
                        const text = (perc * 100).toFixed(0) + '%';

                        // Para projeção (barra contorno), não desenha percentual
                        if (role === 'proj') {
                            return;
                        }

                        if (role === 'real') {
                            // % Realizado será desenhado abaixo (fora do stack)
                            return;
                        }

                        if (role === 'rest' && !showRestBelow) {
                            const topY = Math.min(elY, elBase);
                            // % A Realizar acima da barra (onde estava a projeção)
                            y = topY - 12;
                        }

                        if (role === 'rest' && showRestBelow) {
                            // Quando o restante for ao rodapé, não desenhar dentro do stack.
                            return;
                        }

                        if (role === 'rest') {
                            ctx.fillStyle = 'rgba(17,24,39,0.75)';
                        } else if (role === 'proj') {
                            ctx.fillStyle = 'rgba(245,158,11,0.95)';
                        } else {
                            // % Realizado: usar sempre cor escura (pedido do usuário).
                            ctx.fillStyle = 'rgba(17,24,39,0.85)';
                        }

                        ctx.fillText(text, x, y);
                    });
                });

                // Percentuais abaixo das barras (fora do stack)
                if (showRealBelow || (showRestBelow && showRest)) {
                    const chartArea = chart.chartArea;
                    const yBottom = Math.min(chart.height - 8, (chartArea?.bottom ?? (chart.height - 20)) - 6);
                    const yRealBelow = yBottom - 14;
                    // Mesmo tamanho do percentual da projeção
                    ctx.font = '800 14px system-ui, -apple-system, Segoe UI, Roboto, Arial, sans-serif';
                    ctx.fillStyle = 'rgba(17,24,39,0.85)';

                    // % Realizado abaixo das barras
                    if (showRealBelow) {
                        const idxReal = chart.data.datasets.findIndex(d => d && d._role === 'real');
                        if (idxReal >= 0) {
                            const metaReal = chart.getDatasetMeta(idxReal);
                            metaReal?.data?.forEach((element, index) => {
                                const base = Number(totalOrc[index] || 0);
                                if (!isFinite(base) || base <= 0) return;
                                const realVal = Number(chart.data.datasets[idxReal].data?.[index]);
                                if (!isFinite(realVal) || realVal < 0) return;
                                const realPerc = realVal / base;
                                if (!isFinite(realPerc)) return;
                                const text = (realPerc * 100).toFixed(0) + '%';
                                const x = element?.x;
                                if (!isFinite(x)) return;
                                ctx.fillText(text, x, yRealBelow);
                            });
                        }
                    }

                    // % A Realizar no rodapé (quando explicitamente habilitado)
                    if (showRestBelow && showRest) {
                        const idxRest = chart.data.datasets.findIndex(d => d && d._role === 'rest');
                        if (idxRest >= 0) {
                            const metaRest = chart.getDatasetMeta(idxRest);
                            metaRest?.data?.forEach((element, index) => {
                                const base = Number(totalOrc[index] || 0);
                                if (!isFinite(base) || base <= 0) return;
                                const restVal = Number(chart.data.datasets[idxRest].data?.[index]);
                                if (!isFinite(restVal) || restVal < 0) return;
                                const restPerc = restVal / base;
                                if (!isFinite(restPerc)) return;
                                const text = (restPerc * 100).toFixed(0) + '%';
                                const x = element?.x;
                                if (!isFinite(x)) return;
                                ctx.fillText(text, x, yBottom);
                            });
                        }
                    }
                }

                ctx.restore();
            }
        };

        function destroyModeloChart(modelo) {
            if (chartsModelos[modelo]) {
                chartsModelos[modelo].destroy();
                delete chartsModelos[modelo];
            }
        }

        function destroyOrcamentoCharts() {
            if (chartsOrcamento.bar) {
                chartsOrcamento.bar.destroy();
                chartsOrcamento.bar = null;
            }
            if (chartsOrcamento.donut) {
                chartsOrcamento.donut.destroy();
                chartsOrcamento.donut = null;
            }
        }

        function renderOrcamentoTermometro(periodo) {
            const card = document.querySelector('#dashboardConsolidadoComparativo [data-modelo="orcamento"]');
            if (!card) return;
            const d = (dashboardOrcamentoTermometro && dashboardOrcamentoTermometro[periodo]) ? dashboardOrcamentoTermometro[periodo] : null;
            if (!d) return;

            const orc = Number(d.orc || 0);
            const real = Number(d.real || 0);
            const saldo = Math.max(0, Number(d.saldo || (orc - real)));
            const proj = (d.proj === null || d.proj === undefined) ? null : Number(d.proj);
            const consumoPerc = Number(d.consumoPerc || 0);
            const projPerc = (d.projPerc === null || d.projPerc === undefined) ? null : Number(d.projPerc);

            const statusPerc = (projPerc !== null) ? projPerc : consumoPerc;
            const colReal = toneColorByModelo('orcamento', statusPerc);

            const elReal = card.querySelector('[data-role="orc-total-real"]');
            const elOrc = card.querySelector('[data-role="orc-total-orc"]');
            const elSaldo = card.querySelector('[data-role="orc-total-saldo"]');
            const elProj = card.querySelector('[data-role="orc-total-proj"]');
            const wrapProj = card.querySelector('[data-role-wrap="orc-total-proj"]');
            const elConsPerc = card.querySelector('[data-role="orc-consumo-perc"]');
            const elMaior = card.querySelector('[data-role="orc-ranking-maior"]');
            const elMenor = card.querySelector('[data-role="orc-ranking-menor"]');

            const elEmpMelhor = card.querySelector('[data-role="orc-emp-melhor"]');
            const elEmpPior = card.querySelector('[data-role="orc-emp-pior"]');
            const elEmpCriticos = card.querySelector('[data-role="orc-emp-criticos"]');

            if (elReal) elReal.textContent = formatValor(real);
            if (elOrc) elOrc.textContent = formatValor(orc);
            if (elSaldo) elSaldo.textContent = formatValor(saldo);
            if (wrapProj) {
                const hasProj = (proj !== null && isFinite(proj));
                wrapProj.style.display = hasProj ? '' : 'none';
                if (hasProj && elProj) elProj.textContent = formatValor(proj);
            }
            if (elConsPerc) elConsPerc.textContent = formatPercent(consumoPerc);

            const maior = d.ranking && d.ranking.maior ? d.ranking.maior : null;
            const menor = d.ranking && d.ranking.menor ? d.ranking.menor : null;
            if (elMaior) elMaior.textContent = maior ? `${maior.nome} (${formatPercent(Number(maior.perc || 0))})` : '-';
            if (elMenor) elMenor.textContent = menor ? `${menor.nome} (${formatPercent(Number(menor.perc || 0))})` : '-';

            // Ranking por EMPRESA (multi-empresa): usa o bucket comparativo já existente
            const bucketEmpresas = (dashboardConsolidadoComparativo && dashboardConsolidadoComparativo.orcamento && dashboardConsolidadoComparativo.orcamento[periodo])
                ? (dashboardConsolidadoComparativo.orcamento[periodo].empresas || [])
                : [];

            if (Array.isArray(bucketEmpresas) && bucketEmpresas.length) {
                const empresasOrdenadas = [...bucketEmpresas].sort((a, b) => {
                    const pa = (a.proj_perc !== null && a.proj_perc !== undefined) ? Number(a.proj_perc || 0) : Number(a.perc_total || 0);
                    const pb = (b.proj_perc !== null && b.proj_perc !== undefined) ? Number(b.proj_perc || 0) : Number(b.perc_total || 0);
                    // Orçamento: menor consumo é melhor
                    return pa - pb;
                });
                const melhorEmp = empresasOrdenadas[0] || null;
                const piorEmp = empresasOrdenadas[empresasOrdenadas.length - 1] || null;

                const pm = melhorEmp ? ((melhorEmp.proj_perc !== null && melhorEmp.proj_perc !== undefined) ? Number(melhorEmp.proj_perc || 0) : Number(melhorEmp.perc_total || 0)) : 0;
                const pp = piorEmp ? ((piorEmp.proj_perc !== null && piorEmp.proj_perc !== undefined) ? Number(piorEmp.proj_perc || 0) : Number(piorEmp.perc_total || 0)) : 0;

                if (elEmpMelhor) elEmpMelhor.textContent = melhorEmp ? `${melhorEmp.dsempresa} (${formatPercent(pm)})` : '-';
                if (elEmpPior) elEmpPior.textContent = piorEmp ? `${piorEmp.dsempresa} (${formatPercent(pp)})` : '-';

                const criticosLista = bucketEmpresas
                    .map((e) => {
                        const p = (e.proj_perc !== null && e.proj_perc !== undefined) ? Number(e.proj_perc || 0) : Number(e.perc_total || 0);
                        return {
                            nome: String(e.dsempresa || ''),
                            perc: p,
                            isCritico: (p > 0.90)
                        };
                    })
                    .filter(x => x.isCritico)
                    .sort((a, b) => (b.perc - a.perc));

                const criticosQtd = criticosLista.length;
                if (elEmpCriticos) {
                    elEmpCriticos.textContent = String(criticosQtd);

                    const instancia = (window.bootstrap && bootstrap.Popover) ? bootstrap.Popover.getInstance(elEmpCriticos) : null;
                    if (instancia) instancia.dispose();

                    if (criticosQtd > 0 && window.bootstrap && bootstrap.Popover) {
                        const conteudo = criticosLista
                            .map(x => `<div style="margin-bottom: 4px;">${escapeHtml(x.nome)}: <strong>${escapeHtml(formatPercent(Number(x.perc || 0)))}</strong></div>`)
                            .join('');

                        elEmpCriticos.setAttribute('data-bs-toggle', 'popover');
                        elEmpCriticos.setAttribute('data-bs-trigger', 'hover focus');
                        elEmpCriticos.setAttribute('data-bs-placement', 'top');
                        elEmpCriticos.setAttribute('data-bs-html', 'true');
                        elEmpCriticos.setAttribute('data-bs-title', 'Empresas acima de 90%');
                        elEmpCriticos.setAttribute('data-bs-content', conteudo);

                        new bootstrap.Popover(elEmpCriticos, {
                            html: true,
                            sanitize: false,
                            customClass: 'popover-criticos'
                        });
                    } else {
                        elEmpCriticos.removeAttribute('data-bs-toggle');
                        elEmpCriticos.removeAttribute('data-bs-trigger');
                        elEmpCriticos.removeAttribute('data-bs-placement');
                        elEmpCriticos.removeAttribute('data-bs-html');
                        elEmpCriticos.removeAttribute('data-bs-title');
                        elEmpCriticos.removeAttribute('data-bs-content');
                    }
                }
            } else {
                if (elEmpMelhor) elEmpMelhor.textContent = '-';
                if (elEmpPior) elEmpPior.textContent = '-';
                if (elEmpCriticos) {
                    elEmpCriticos.textContent = '-';
                    const instancia = (window.bootstrap && bootstrap.Popover) ? bootstrap.Popover.getInstance(elEmpCriticos) : null;
                    if (instancia) instancia.dispose();
                    elEmpCriticos.removeAttribute('data-bs-toggle');
                    elEmpCriticos.removeAttribute('data-bs-trigger');
                    elEmpCriticos.removeAttribute('data-bs-placement');
                    elEmpCriticos.removeAttribute('data-bs-html');
                    elEmpCriticos.removeAttribute('data-bs-title');
                    elEmpCriticos.removeAttribute('data-bs-content');
                }
            }

            // Bar chart: Orçamento × Gasto (empilhado)
            const canvasBar = card.querySelector('#chart-orcamento-termometro');
            if (canvasBar && window.Chart) {
                const datasets = [
                    {
                        label: 'Gasto realizado',
                        data: [real],
                        backgroundColor: hexToRgba(colReal, 0.78),
                        borderWidth: 0,
                        stack: 'stack-1'
                    },
                    {
                        label: 'Saldo disponível',
                        data: [saldo],
                        backgroundColor: 'rgba(226,232,240,0.95)',
                        borderWidth: 0,
                        stack: 'stack-1'
                    }
                ];

                const hasProj = (proj !== null && isFinite(proj));
                if (hasProj) {
                    datasets.push({
                        label: 'Projeção de gasto',
                        data: [proj],
                        type: 'bar',
                        grouped: false,
                        backgroundColor: 'rgba(0,0,0,0)',
                        borderColor: [colReal],
                        borderWidth: 3,
                        borderSkipped: false,
                        order: 99,
                        stack: 'stack-proj'
                    });
                }

                if (!chartsOrcamento.bar) {
                    const ctx = canvasBar.getContext('2d');
                    chartsOrcamento.bar = new Chart(ctx, {
                        type: 'bar',
                        data: {
                            labels: ['Consolidado'],
                            datasets
                        },
                        options: {
                            maintainAspectRatio: false,
                            responsive: true,
                            scales: {
                                x: { stacked: true },
                                y: {
                                    stacked: true,
                                    ticks: {
                                        callback: function(value) {
                                            return formatValor(Number(value || 0));
                                        }
                                    }
                                }
                            },
                            plugins: {
                                legend: { position: 'bottom' },
                                tooltip: {
                                    enabled: false,
                                    external: externalTooltipHandler,
                                    callbacks: {
                                        label: function(ctx) {
                                            const label = ctx.dataset.label || '';
                                            const v = Number(ctx.raw || 0);
                                            return label + ': ' + formatValor(v);
                                        }
                                    }
                                }
                            }
                        }
                    });
                } else {
                    chartsOrcamento.bar.data.datasets = datasets;
                    chartsOrcamento.bar.update();
                }
            }

            // Donut: % consumido
            const canvasDonut = card.querySelector('#chart-orcamento-consumo');
            if (canvasDonut && window.Chart) {
                const donutData = {
                    labels: ['Consumido', 'Saldo'],
                    datasets: [
                        {
                            data: [real, saldo],
                            backgroundColor: [colReal, 'rgba(226,232,240,0.95)'],
                            borderWidth: 0,
                            hoverOffset: 3,
                            cutout: '72%'
                        }
                    ]
                };

                if (!chartsOrcamento.donut) {
                    const ctx2 = canvasDonut.getContext('2d');
                    chartsOrcamento.donut = new Chart(ctx2, {
                        type: 'doughnut',
                        data: donutData,
                        options: {
                            plugins: {
                                legend: { display: false },
                                tooltip: {
                                    enabled: false,
                                    external: externalTooltipHandler,
                                    callbacks: {
                                        label: function(ctx) {
                                            const label = ctx.label || '';
                                            const v = Number(ctx.raw || 0);
                                            const perc = (orc !== 0) ? (v / orc) : 0;
                                            const percTxt = (perc * 100).toFixed(1).replace('.', ',') + '%';
                                            return label + ': ' + formatValor(v) + ' (' + percTxt + ')';
                                        }
                                    }
                                }
                            }
                        }
                    });
                } else {
                    chartsOrcamento.donut.data = donutData;
                    chartsOrcamento.donut.update();
                }
            }
        }

        function renderModeloComparativo(modelo, periodo) {
            const container = document.querySelector(`#dashboardConsolidadoComparativo [data-modelo="${modelo}"]`);
            if (!container) return;

            const data = (dashboardConsolidadoComparativo?.[modelo]?.[periodo]) || null;
            const empresas = Array.isArray(data?.empresas) ? data.empresas : [];
            if (!empresas.length) return;

            const labels = getModeloLabels(modelo);

            const totalReal = empresas.reduce((s, e) => s + Number(e.total_real || 0), 0);
            const totalOrcSum = empresas.reduce((s, e) => s + Number(e.total_orc || 0), 0);
            const percTotal = totalOrcSum !== 0 ? (totalReal / totalOrcSum) : 0;

            const totalProjSum = empresas.reduce((s, e) => {
                const pv = e.proj_total;
                if (pv === null || pv === undefined) return s;
                const n = Number(pv);
                return isFinite(n) ? (s + n) : s;
            }, 0);

            const totalRealEl = container.querySelector('[data-role="total-real"]');
            const totalOrcEl = container.querySelector('[data-role="total-orc"]');
            const percTotalEl = container.querySelector('[data-role="perc-total"]');
            const totalProjEl = container.querySelector('[data-role="total-proj"]');
            const totalProjWrap = container.querySelector('[data-role-wrap="total-proj"]');
            const melhorEl = container.querySelector('[data-role="melhor"]');
            const piorEl = container.querySelector('[data-role="pior"]');
            const criticosEl = container.querySelector('[data-role="criticos"]');

            if (totalRealEl) totalRealEl.textContent = formatValor(totalReal);
            if (totalOrcEl) totalOrcEl.textContent = formatValor(totalOrcSum);
            if (percTotalEl) percTotalEl.textContent = formatPercent(percTotal);

            if (totalProjWrap) {
                const hasProjInBucket = empresas.some(e => e.proj_total !== null && e.proj_total !== undefined);
                totalProjWrap.style.display = hasProjInBucket ? '' : 'none';
                if (hasProjInBucket && totalProjEl) {
                    totalProjEl.textContent = formatValor(totalProjSum);
                }
            }

            const empresasOrdenadas = [...empresas].sort((a, b) => {
                const pa = (a.proj_perc !== null && a.proj_perc !== undefined) ? Number(a.proj_perc || 0) : Number(a.perc_total || 0);
                const pb = (b.proj_perc !== null && b.proj_perc !== undefined) ? Number(b.proj_perc || 0) : Number(b.perc_total || 0);
                // Meta: maior é melhor | Orçamento: menor é melhor
                return (modelo === 'orcamento') ? (pa - pb) : (pb - pa);
            });
            const melhor = empresasOrdenadas[0] || null;
            const pior = empresasOrdenadas[empresasOrdenadas.length - 1] || null;
            if (melhorEl) {
                const pm = melhor ? ((melhor.proj_perc !== null && melhor.proj_perc !== undefined) ? Number(melhor.proj_perc || 0) : Number(melhor.perc_total || 0)) : 0;
                melhorEl.textContent = melhor ? `${melhor.dsempresa} (${formatPercent(pm)})` : '-';
            }
            if (piorEl) {
                const pp = pior ? ((pior.proj_perc !== null && pior.proj_perc !== undefined) ? Number(pior.proj_perc || 0) : Number(pior.perc_total || 0)) : 0;
                piorEl.textContent = pior ? `${pior.dsempresa} (${formatPercent(pp)})` : '-';
            }

            const criticosLista = empresas
                .map((e) => {
                    const p = (e.proj_perc !== null && e.proj_perc !== undefined) ? Number(e.proj_perc || 0) : Number(e.perc_total || 0);
                    const isCritico = (modelo === 'orcamento') ? (p > 0.90) : (p < 0.90);
                    return {
                        nome: String(e.dsempresa || ''),
                        perc: p,
                        isCritico
                    };
                })
                .filter(x => x.isCritico)
                .sort((a, b) => (modelo === 'orcamento') ? (b.perc - a.perc) : (a.perc - b.perc));

            const criticosQtd = criticosLista.length;
            if (criticosEl) {
                criticosEl.textContent = String(criticosQtd);

                const instancia = (window.bootstrap && bootstrap.Popover) ? bootstrap.Popover.getInstance(criticosEl) : null;
                if (instancia) instancia.dispose();

                if (criticosQtd > 0 && window.bootstrap && bootstrap.Popover) {
                    const conteudo = criticosLista
                        .map(x => `<div style="margin-bottom: 4px;">${escapeHtml(x.nome)}: <strong>${escapeHtml(formatPercent(Number(x.perc || 0)))}</strong></div>`)
                        .join('');

                    criticosEl.setAttribute('data-bs-toggle', 'popover');
                    criticosEl.setAttribute('data-bs-trigger', 'hover focus');
                    criticosEl.setAttribute('data-bs-placement', 'top');
                    criticosEl.setAttribute('data-bs-html', 'true');
                    criticosEl.setAttribute('data-bs-title', (modelo === 'orcamento') ? 'Empresas acima de 90%' : 'Empresas abaixo de 90% na (Projeção)');
                    criticosEl.setAttribute('data-bs-content', conteudo);

                    new bootstrap.Popover(criticosEl, {
                        html: true,
                        sanitize: false,
                        customClass: 'popover-criticos'
                    });
                } else {
                    // limpa atributos quando não há críticos
                    criticosEl.removeAttribute('data-bs-toggle');
                    criticosEl.removeAttribute('data-bs-trigger');
                    criticosEl.removeAttribute('data-bs-placement');
                    criticosEl.removeAttribute('data-bs-html');
                    criticosEl.removeAttribute('data-bs-title');
                    criticosEl.removeAttribute('data-bs-content');
                }
            }

            const canvas = container.querySelector(`#chart-modelo-${modelo}`);
            if (!canvas || !window.Chart) return;

            const nomes = empresas.map(e => String(e.dsempresa || ''));
            const realizado = empresas.map(e => Number(e.total_real || 0));
            const restante = empresas.map(e => Math.max(0, Number(e.total_orc || 0) - Number(e.total_real || 0)));
            const totalOrcArr = empresas.map(e => Number(e.total_orc || 0));

            // Cor por empresa baseada na PROJEÇÃO (preferencial) ou no atingimento atual
            const statusPerc = empresas.map(e => {
                const pProj = e.proj_perc;
                if (pProj !== null && pProj !== undefined) return Number(pProj) || 0;
                return Number(e.perc_total || 0);
            });
            const statusHex = statusPerc.map(p => toneColorByModelo(modelo, Number(p || 0)));
            const corReal = statusHex.map(h => hexToRgba(h, 0.78));

            const hasProj = empresas.some(e => e.proj_total !== null && e.proj_total !== undefined);
            const projTotal = empresas.map(e => {
                const pv = e.proj_total;
                if (pv === null || pv === undefined) return null;
                return Number(pv);
            });

            destroyModeloChart(modelo);

            const baseDatasets = [
                {
                    label: labels.realizado,
                    data: realizado,
                    backgroundColor: corReal,
                    borderWidth: 0,
                    stack: 'stack-1'
                },
                {
                    label: labels.restante,
                    data: restante,
                    backgroundColor: 'rgba(226,232,240,0.95)',
                    borderWidth: 0,
                    stack: 'stack-1'
                }
            ];

            if (hasProj) {
                baseDatasets.push({
                    label: labels.projecao,
                    data: projTotal,
                    // Barra de projeção TOTAL sobreposta (não soma no stack)
                    type: 'bar',
                    grouped: false,
                    // Contorno para leitura (evita "misturar" com o realizado)
                    backgroundColor: 'rgba(0,0,0,0)',
                    borderColor: statusHex,
                    borderWidth: 3,
                    borderSkipped: false,
                    order: 99,
                    stack: 'stack-proj',
                    _role: 'proj'
                });
            }

            // Marca roles para o plugin de percentuais
            baseDatasets[0]._role = 'real';
            baseDatasets[1]._role = 'rest';

            const ctx = canvas.getContext('2d');
            chartsModelos[modelo] = new Chart(ctx, {
                type: 'bar',
                data: {
                    labels: nomes,
                    datasets: baseDatasets
                },
                options: {
                    indexAxis: 'x',
                    maintainAspectRatio: false,
                    responsive: true,
                    interaction: {
                        mode: 'index',
                        intersect: false
                    },
                    layout: {
                        padding: {
                            bottom: 10
                        }
                    },
                    scales: {
                        x: {
                            stacked: true,
                            ticks: {
                                callback: function(value) {
                                    const lblRaw = (this && typeof this.getLabelForValue === 'function')
                                        ? this.getLabelForValue(value)
                                        : value;
                                    const lbl = String(lblRaw ?? '');
                                    return lbl.length > 14 ? (lbl.slice(0, 14) + '…') : lbl;
                                },
                                autoSkip: true,
                                maxRotation: 30,
                                minRotation: 0
                            }
                        },
                        y: {
                            stacked: true,
                            ticks: {
                                callback: function(value) {
                                    return formatValor(Number(value || 0));
                                }
                            }
                        }
                    },
                    plugins: {
                        legend: {
                            position: 'bottom'
                        },
                        tooltip: {
                            enabled: false,
                            external: externalTooltipHandler,
                            mode: 'index',
                            intersect: false,
                            callbacks: {
                                title: function(items) {
                                    const it = items?.[0];
                                    return it ? String(it.label || '') : '';
                                },
                                label: function(ctx) {
                                    const idx = Number(ctx.dataIndex || 0);
                                    const base = Number(totalOrcArr[idx] || 0);
                                    const role = ctx?.dataset?._role;
                                    const raw = ctx.raw;

                                    if (!isFinite(base) || base <= 0) {
                                        const label = String(ctx.dataset.label || '');
                                        const v = Number(raw || 0);
                                        return label + ': ' + formatValor(isFinite(v) ? v : 0);
                                    }

                                    if (role === 'proj') {
                                        if (raw === null || raw === undefined) return null;
                                        const v = Number(raw);
                                        if (!isFinite(v)) return null;
                                        const p = v / base;
                                        return 'Projeção: ' + formatValor(v) + ' (' + formatPercent(p) + ')';
                                    }

                                    if (role === 'real') {
                                        const v = Number(raw || 0);
                                        const p = (isFinite(v) ? (v / base) : 0);
                                        return (modelo === 'orcamento' ? 'Realizado' : 'Realizado') + ': ' + formatValor(isFinite(v) ? v : 0) + ' (' + formatPercent(p) + ')';
                                    }

                                    if (role === 'rest') {
                                        const v = Number(raw || 0);
                                        const p = (isFinite(v) ? (v / base) : 0);
                                        return (modelo === 'orcamento' ? 'Saldo' : 'A realizar') + ': ' + formatValor(isFinite(v) ? v : 0) + ' (' + formatPercent(p) + ')';
                                    }

                                    const label = String(ctx.dataset.label || '');
                                    const v = Number(raw || 0);
                                    return label + ': ' + formatValor(isFinite(v) ? v : 0);
                                }
                            }
                        }
                    }
                },
                plugins: [percentInBarsPlugin],
            });

            // Atualiza opções do plugin (por chart) após criação
            chartsModelos[modelo].options.plugins.percentInBars = {
                totalOrc: totalOrcArr,
                showProj: hasProj,
                // Mostra % A Realizar acima e % Realizado abaixo
                showReal: false,
                showRealBelow: true,
                showRest: false,
                showRestBelow: false
            };
            chartsModelos[modelo].update();
        }

        function initVisaoConsolidadaComparativo() {
            const root = document.getElementById('dashboardConsolidadoComparativo');
            if (!root) return;

            root.querySelectorAll('[data-modelo]').forEach((card) => {
                const modelo = card.getAttribute('data-modelo');
                if (!modelo) return;

                if (modelo === 'orcamento' && dashboardOrcamentoTermometro && dashboardOrcamentoTermometro.mes) {
                    destroyOrcamentoCharts();
                    renderOrcamentoTermometro('mes');
                } else {
                    renderModeloComparativo(modelo, 'mes');
                }

                const toggle = card.querySelectorAll('[data-modelo-periodo]');
                toggle.forEach((btn) => {
                    btn.addEventListener('click', (e) => {
                        e.preventDefault();
                        toggle.forEach(b => b.classList.remove('active'));
                        btn.classList.add('active');
                        const periodo = btn.getAttribute('data-modelo-periodo');

                        if (modelo === 'orcamento' && dashboardOrcamentoTermometro && dashboardOrcamentoTermometro[periodo]) {
                            renderOrcamentoTermometro(periodo);
                        } else {
                            renderModeloComparativo(modelo, periodo);
                        }
                    });
                });
            });
        }
        
        function createDonutChart(ctx, m) {
            const orcAno = Number(m.orcAno || 0);
            const realAno = Number(m.realAno || 0);
            const restAno = Math.max(0, orcAno - realAno);
            const orcMes = Number(m.orcMes || 0);
            const realMes = Number(m.realMes || 0);
            const restMes = Math.max(0, orcMes - realMes);

            // Usar PROJEÇÃO, não percentual atingido
            const projAnoPerc = Number(m.projAnoPerc || 0);
            const projMesPerc = Number(m.projMesPerc || 0);
            const modeloVar = String(m.modelo || 'meta');
            const colAno  = toneColorByModelo(modeloVar, projAnoPerc);
            const colMes  = toneColorByModelo(modeloVar, projMesPerc);

            new Chart(ctx, {
                type: 'doughnut',
                data: {
                    labels: [dashboardLinguagem.realizado, dashboardLinguagem.restante],
                    datasets: [
                        {
                            // Anel externo: Ano
                            data: [realAno, restAno],
                            backgroundColor: [ colAno, 'rgba(226, 232, 240, 0.95)' ],
                            borderWidth: 0,
                            hoverOffset: 4,
                            cutout: '60%',
                            radius: '100%'
                        },
                        {
                            // Anel interno: Mês
                            data: [realMes, restMes],
                            backgroundColor: [ colMes, 'rgba(234, 238, 243, 0.95)' ],
                            borderWidth: 0,
                            hoverOffset: 4,
                            cutout: '0%',
                            radius: '60%'
                        }
                    ]
                },
                options: {
                    plugins: {
                        legend: { display: false },
                        tooltip: {
                            enabled: false, // ✅ desliga o tooltip "no canvas"
                            external: externalTooltipHandler, // ✅ tooltip HTML externo (não corta)
                            callbacks: {
                                label: function(ctx) {
                                    const label = ctx.label || '';
                                    const v = Number(ctx.raw || 0);
                                    const base = (ctx.datasetIndex === 0) ? orcAno : orcMes;
                                    const perc = base !== 0 ? (v / base) : 0;
                                    const percTxt = (perc * 100).toFixed(1).replace('.', ',') + '%';
                                    return label + ': ' + formatValor(v) + ' (' + percTxt + ')';
                                }
                            }
                        }
                    }
                }
            });
        }

        function wireFeriadosToggle() {
            document.querySelectorAll('.feriados-toggle').forEach((el) => {
                el.addEventListener('click', (e) => {
                    e.preventDefault();
                    const id = el.getAttribute('data-feriados');
                    const list = document.getElementById('feriados-list-' + String(id));
                    if (!list) return;
                    list.classList.toggle('d-none');
                });
            });
        }
        

        const btnCharts = document.getElementById('btnViewCharts');
        const btnCards  = document.getElementById('btnViewCards');
        const contCharts= document.getElementById('dashboardChartsContainer');
        const contCards = document.getElementById('dashboardCardsContainer');

        if (btnCharts && btnCards && contCharts && contCards) {
            function mostrarGraficos() {
                contCharts.classList.remove('d-none');
                contCharts.style.display = 'block';
                contCards.classList.add('d-none');
                contCards.style.display = 'none';
                btnCharts.classList.add('btn-primary');
                btnCharts.classList.remove('btn-outline-secondary');
                btnCards.classList.remove('btn-primary');
                btnCards.classList.add('btn-outline-secondary');
            }

            function mostrarPlanilha() {
                contCharts.classList.add('d-none');
                contCharts.style.display = 'none';
                contCards.classList.remove('d-none');
                contCards.style.display = 'flex';
                btnCards.classList.add('btn-primary');
                btnCards.classList.remove('btn-outline-secondary');
                btnCharts.classList.remove('btn-primary');
                btnCharts.classList.add('btn-outline-secondary');
            }

            mostrarGraficos();

            btnCharts.addEventListener('click', function (e) {
                e.preventDefault();
                mostrarGraficos();
            });

            btnCards.addEventListener('click', function (e) {
                e.preventDefault();
                mostrarPlanilha();
            });
        }

        try {
            if (dashboardVisao !== 'modelo') {
                buildKpiDonuts();
            } else {
                initVisaoConsolidadaComparativo();
            }
        } catch (e) {
            console.error('Erro ao inicializar gráficos do dashboard:', e);
        }

        try { wireFeriadosToggle(); } catch (e) { console.error('Erro wireFeriadosToggle:', e); }
        try { initKpiToggle(); } catch (e) { console.error('Erro initKpiToggle:', e); }

        // Sincronização automática de período
        const modalSyncAuto = new bootstrap.Modal(document.getElementById('modalSyncAuto'));

        function setSyncStage(stage) {
            const $bar = document.querySelector('#syncProgresso .progress-bar');
            const steps = ['preparar', 'sincronizar', 'consolidar', 'atualizar'];
            let idx = steps.indexOf(stage);
            if (idx === -1) idx = 0;

            document.querySelectorAll('#syncEtapas li').forEach(li => {
                li.classList.remove('fw-bold', 'text-success');
            });
            
            steps.forEach((s, i) => {
                const $li = document.querySelector(`#syncEtapas li[data-step="${s}"]`);
                if (i < idx) {
                    $li.classList.add('text-success', 'fw-bold');
                } else if (i === idx) {
                    $li.classList.add('fw-bold');
                }
            });

            let width = 0;
            if (stage === 'preparar') width = 15;
            else if (stage === 'sincronizar') width = 50;
            else if (stage === 'consolidar') width = 80;
            else if (stage === 'atualizar') width = 100;
            $bar.style.width = width + '%';
        }

        window.abrirSyncModal = function(e) {
            e.preventDefault();
            document.getElementById('syncResultado').innerHTML = '';
            document.getElementById('syncProgresso').style.display = 'none';
            document.querySelectorAll('#syncEtapas li').forEach(li => {
                li.classList.remove('fw-bold', 'text-success');
            });
            document.querySelector('#syncProgresso .progress-bar').style.width = '0%';
            document.getElementById('btnFecharSync').disabled = false;
            document.getElementById('btnFecharSyncFooter').disabled = false;
            
            modalSyncAuto.show();
            executarSyncAutomatico();
        };

        async function executarSyncAutomatico() {
            document.getElementById('syncProgresso').style.display = 'block';
            setSyncStage('preparar');
            document.body.style.cursor = 'wait';

            document.getElementById('syncResultado').innerHTML = `
                <div class="text-center py-3">
                    <div class="spinner-border text-warning" role="status">
                        <span class="visually-hidden">Sincronizando...</span>
                    </div>
                    <p class="mt-2 mb-0">Sincronizando dados do período automático, aguarde...</p>
                </div>
            `;

            try {
                setSyncStage('sincronizar');
                const resp = await fetch('?m=home_actions&ajax=sincronizar_periodo_automatico', {
                    method: 'POST',
                    headers: { 'Content-Type': 'application/json;charset=UTF-8' },
                    body: JSON.stringify({})
                });

                let json, texto;
                try {
                    texto = await resp.text();
                    if (!texto) {
                        throw new Error('Resposta vazia do servidor');
                    }
                    json = JSON.parse(texto);
                } catch (parseErr) {
                    console.error('Erro ao parsear JSON:', parseErr, 'Resposta:', texto);
                    document.getElementById('syncResultado').innerHTML = `<div class="alert alert-danger mt-2">Erro ao processar resposta do servidor (${resp.status})</div>`;
                    document.getElementById('btnFecharSync').disabled = false;
                    document.getElementById('btnFecharSyncFooter').disabled = false;
                    document.body.style.cursor = '';
                    return;
                }

                if (!json.ok) {
                    document.getElementById('syncResultado').innerHTML = `<div class="alert alert-warning mt-2">${json.msg || 'Erro na sincronização'}</div>`;
                    document.getElementById('btnFecharSync').disabled = false;
                    document.getElementById('btnFecharSyncFooter').disabled = false;
                    document.body.style.cursor = '';
                    return;
                }

                // Validar se houve sincronização efetiva
                if (!json || json === null || (json.total === null || json.total === undefined)) {
                    document.getElementById('syncResultado').innerHTML = `
                        <div class="alert alert-danger mt-2">
                            <i class="bi bi-exclamation-circle"></i>
                            <strong>Sincronização nunca foi efetuada!</strong><br>
                            <small>Nenhuma integração está configurada ou ativa para esta empresa. Por favor, contate o administrador do sistema.</small>
                        </div>
                    `;
                    document.getElementById('btnFecharSync').disabled = false;
                    document.getElementById('btnFecharSyncFooter').disabled = false;
                    document.body.style.cursor = '';
                    return;
                }

                setSyncStage('consolidar');

                let htmlResumo = `
                    <div class="mt-2">
                        <h6 class="mb-2"><i class="bi bi-check-circle"></i> Sincronização concluída</h6>
                        <div class="alert alert-success py-2 px-2 small">${json.msg}</div>
                        <div class="alert alert-info py-2 px-2 small mb-0">
                            <strong>Totais:</strong> ${json.total || 0} inseridos | ${json.ignorados || 0} ignorados | ${json.erros || 0} erros
                        </div>
                `;

                if (json.ignorados_motivos) {
                    const m = json.ignorados_motivos;
                    const itens = [];
                    if (m.empresa_origem_sem_mapeamento) itens.push(`<li>${m.empresa_origem_sem_mapeamento} com empresa de origem sem mapeamento em back.empresa.cdintegracao</li>`);
                    if (m.empresa_nao_vinculada_integracao) itens.push(`<li>${m.empresa_nao_vinculada_integracao} de empresas não vinculadas à integração (back.integracao_empresa)</li>`);
                    if (m.dtmovimento_vazio) itens.push(`<li>${m.dtmovimento_vazio} sem dtmovimento na query de origem</li>`);
                    if (m.dtmovimento_invalido) itens.push(`<li>${m.dtmovimento_invalido} com dtmovimento em formato inválido</li>`);
                    if (m.exercicio_nao_criado) itens.push(`<li>${m.exercicio_nao_criado} sem exercício válido para empresa/ano</li>`);

                    if (itens.length) {
                        htmlResumo += `
                            <div class="alert alert-warning py-2 px-2 small mt-2 mb-0">
                                <strong>Motivos dos ignorados:</strong>
                                <ul class="mb-0">${itens.join('')}</ul>
                            </div>
                        `;
                    }
                }

                htmlResumo += '</div>';
                document.getElementById('syncResultado').innerHTML = htmlResumo;
                setSyncStage('atualizar');

                // Deixa o usuário ver o resultado antes de recarregar
                // Para recarregar manualmente, o usuário clica no fechar

            } catch (e) {
                console.error(e);
                document.getElementById('syncResultado').innerHTML = `<div class="alert alert-danger mt-2">${e.message || 'Erro inesperado na sincronização.'}</div>`;
            } finally {
                document.getElementById('btnFecharSync').disabled = false;
                document.getElementById('btnFecharSyncFooter').disabled = false;
                document.body.style.cursor = '';
            }
        }

        // Recarregar página quando usuário fecha o modal
        document.getElementById('btnFecharSync').addEventListener('click', function() {
            location.reload();
        });
        document.getElementById('btnFecharSyncFooter').addEventListener('click', function() {
            location.reload();
        });
    });

    // ========== Scripts dos Filtros ==========
    
    function atualizarLabelEmpresas() {
        const checkboxesDesktop = document.querySelectorAll('#filtrosFormDesktop input.empresa-checkbox:checked');
        const labelDesktop = document.getElementById('empresasLabelDesktop');
        
        if (checkboxesDesktop.length === 0) {
            labelDesktop.textContent = 'Nenhuma selecionada';
        } else if (checkboxesDesktop.length === 1) {
            const empresa = checkboxesDesktop[0].parentElement.parentElement.querySelector('label small').textContent;
            labelDesktop.textContent = empresa;
        } else {
            labelDesktop.textContent = `${checkboxesDesktop.length} selecionadas`;
        }
    }

    function atualizarLabelMeses() {
        const mesesDesktop = document.querySelectorAll('#filtrosFormDesktop input.mes-checkbox:checked');
        const labelDesktop = document.getElementById('mesesLabelDesktop');
        if (!labelDesktop) return;

        if (mesesDesktop.length === 0) {
            labelDesktop.textContent = 'Nenhum selecionado';
        } else if (mesesDesktop.length === 1) {
            const nome = mesesDesktop[0].parentElement.parentElement.querySelector('label small')?.textContent;
            labelDesktop.textContent = nome || '1 selecionado';
        } else {
            labelDesktop.textContent = `${mesesDesktop.length} selecionados`;
        }
    }

    function mesesDoTrimestre(tri) {
        const t = Number(tri || 0);
        if (t < 1 || t > 4) return [];
        const start = (t - 1) * 3 + 1;
        return [start, start + 1, start + 2];
    }

    function sincronizarMesesComTrimestre(tri) {
        const meses = mesesDoTrimestre(tri);
        if (meses.length === 0) return;

        // Flag para não disparar o comportamento inverso (meses -> trimestre)
        window.__syncMesesFromTrimestre = true;

        // Ajusta meses em ambos formulários (desktop + mobile)
        ['#filtrosForm', '#filtrosFormDesktop'].forEach(formSel => {
            const form = document.querySelector(formSel);
            if (!form) return;
            form.querySelectorAll('input.mes-checkbox').forEach(cb => {
                const m = Number(cb.value);
                cb.checked = meses.includes(m);
            });
        });

        // "Selecionar todos" deve ficar desmarcado (apenas 3 meses)
        const allMesesMobile = document.getElementById('selecionarTodosMeses');
        const allMesesDesktop = document.getElementById('selecionarTodosMesesDesktop');
        if (allMesesMobile) allMesesMobile.checked = false;
        if (allMesesDesktop) allMesesDesktop.checked = false;

        atualizarLabelMeses();

        window.__syncMesesFromTrimestre = false;
    }

    function sincronizarSelectTrimestre(valor) {
        const v = String(valor ?? '0');
        const tDesk = document.getElementById('filtroTrimestreDesktop');
        const tMob  = document.getElementById('filtroTrimestre');
        if (tDesk && String(tDesk.value) !== v) tDesk.value = v;
        if (tMob && String(tMob.value) !== v) tMob.value = v;
    }
    
    function aplicarFiltros() {
        const formMobile = document.getElementById('filtrosForm');
        const formDesktop = document.getElementById('filtrosFormDesktop');

        // Definir qual layout está ativo de forma estável (mesmo com collapse/dropdown)
        const isDesktop = window.matchMedia('(min-width: 768px)').matches;
        const formAtivo = isDesktop ? formDesktop : formMobile;

        if (!formAtivo) {
            console.warn('Nenhum formulário de filtros encontrado');
            return;
        }

        // Coletar valores dos filtros
        const params = new URLSearchParams();
        
        // Ano
        const anoInput = formAtivo.querySelector('select[name="ano"]');
        if (anoInput && anoInput.value !== undefined) params.append('ano', anoInput.value);

        // Trimestre (precisa vir antes do mês para forçar meses do trimestre, se aplicável)
        const trimestreInput = formAtivo.querySelector('select[name="trimestre"]');
        const trimestreVal = trimestreInput && trimestreInput.value !== undefined ? Number(trimestreInput.value || 0) : 0;

        // Mês (múltiplos checkboxes)
        let mesesCheckedUnique = [];
        if (trimestreVal > 0) {
            // Regra: ao aplicar trimestre, seleciona automaticamente todos os meses do trimestre
            mesesCheckedUnique = mesesDoTrimestre(trimestreVal).map(String);
        } else {
            const mesesChecked = Array.from(formAtivo.querySelectorAll('input.mes-checkbox:checked'))
                .map(cb => cb.value)
                .filter(v => v !== null && v !== undefined && String(v).trim() !== '');
            mesesCheckedUnique = Array.from(new Set(mesesChecked));
        }

        if (mesesCheckedUnique.length > 0) {
            mesesCheckedUnique.forEach(m => params.append('mes[]', m));
        }
        
        // País
        const paisInput = formAtivo.querySelector('select[name="cdpais"]');
        if (paisInput && paisInput.value !== undefined) params.append('cdpais', paisInput.value);

        // Se o usuário interagiu com o campo de país nesta tela, sinalizar para o backend
        // aplicar o comportamento "selecionar todas as empresas do país" mesmo se o valor não mudou.
        if (window.__paisTouched === true) {
            params.append('pais_explicit', '1');
        }

        // Moeda
        const moedaInput = formAtivo.querySelector('select[name="cdmoeda"]');
        if (moedaInput && moedaInput.value !== undefined) params.append('cdmoeda', moedaInput.value);

        if (window.__moedaTouched === true) {
            params.append('moeda_explicit', '1');
        }
        
        // Empresas (múltiplos checkboxes)
        // IMPORTANTE: existem checkboxes duplicados (mobile + desktop).
        // Coletar SOMENTE do form ativo para não agregar empresa marcada no form escondido.
        const empresasChecked = Array.from(formAtivo.querySelectorAll('input.empresa-checkbox:checked'))
            .map(cb => cb.value)
            .filter(v => v !== null && v !== undefined && String(v).trim() !== '');
        const empresasCheckedUnique = Array.from(new Set(empresasChecked));
        
        // DEBUG detalhado
        const allCheckboxes = formAtivo.querySelectorAll('input.empresa-checkbox');
        console.log('[aplicarFiltros] Form ativo:', formAtivo.id, '| isDesktop=', isDesktop);
        console.log('[aplicarFiltros] Total de checkboxes no form ativo:', allCheckboxes.length);
        console.log('[aplicarFiltros] Checkboxes checked (raw):', empresasChecked);
        console.log('[aplicarFiltros] Checkboxes checked (unique):', empresasCheckedUnique);
        console.log('[aplicarFiltros] Quantidade (unique):', empresasCheckedUnique.length);
        
        // IMPORTANTE: Se não há empresas selecionadas, NÃO enviar parâmetro cdempresa
        // Isto faz PHP usar SESSION (mantém seleção anterior)
        if (empresasCheckedUnique.length > 0) {
            empresasCheckedUnique.forEach(emp => {
                params.append('cdempresa[]', emp);
                console.log('[aplicarFiltros] Adicionando cdempresa[]=' + emp);
            });
        } else {
            console.log('[aplicarFiltros] Nenhuma empresa selecionada, não enviando cdempresa (usará SESSION)');
        }
        
        // Centro de Custo
        const centroCustoInput = formAtivo.querySelector('select[name="cdcentrocusto"]');
        if (centroCustoInput && centroCustoInput.value !== undefined) params.append('cdcentrocusto', centroCustoInput.value);
        
        // Trimestre
        if (trimestreInput && trimestreInput.value !== undefined) params.append('trimestre', String(trimestreVal));
        
        // Log de debug
        const urlCompleta = '?' + params.toString();
        console.log('[aplicarFiltros] URL completa:', urlCompleta);
        console.log('[aplicarFiltros] Parâmetros:', Object.fromEntries(params));
        
        // Debug: mostrar o que está sendo enviado
        let debugMsg = 'Filtros aplicados:\n';
        debugMsg += 'Ano: ' + (anoInput?.value || 'N/A') + '\n';
        debugMsg += 'Meses: ' + (mesesCheckedUnique.length > 0 ? mesesCheckedUnique.join(', ') : 'Nenhum') + '\n';
        debugMsg += 'País: ' + (paisInput?.value || 'Todos') + '\n';
        debugMsg += 'Moeda: ' + (moedaInput?.value || 'N/A') + '\n';
        debugMsg += 'Empresas: ' + (empresasCheckedUnique.length > 0 ? empresasCheckedUnique.join(', ') : 'Nenhuma') + '\n';
        debugMsg += 'Centro: ' + (centroCustoInput?.value || 'Todos') + '\n';
        debugMsg += 'Trimestre: ' + (trimestreInput?.value || 'N/A') + '\n\n';
        debugMsg += 'URL:\n' + urlCompleta;
        console.log(debugMsg);
        
        // Redirecionar com todos os parâmetros
        window.location.href = urlCompleta;
    }
    
    function limparFiltros() {
        // Limpar todos os checkboxes de empresa
        document.querySelectorAll('input.empresa-checkbox').forEach(cb => cb.checked = false);
        document.getElementById('selecionarTodas').checked = false;
        document.getElementById('selecionarTodasDesktop').checked = false;

        // Limpar meses
        document.querySelectorAll('input.mes-checkbox').forEach(cb => cb.checked = false);
        const allMesesMobile = document.getElementById('selecionarTodosMeses');
        const allMesesDesktop = document.getElementById('selecionarTodosMesesDesktop');
        if (allMesesMobile) allMesesMobile.checked = false;
        if (allMesesDesktop) allMesesDesktop.checked = false;
        
        // Atualizar labels
        atualizarLabelEmpresas();
        atualizarLabelMeses();
        
        // Redirecionar para home com parâmetro de limpeza
        window.location.href = '?limpar_filtros=1';
    }

    function toggleTodasEmpresas() {
        const checkboxMobile = document.getElementById('selecionarTodas');
        const checkboxDesktop = document.getElementById('selecionarTodasDesktop');
        
        const empresasCheckboxesMobile = document.querySelectorAll('#filtrosForm input.empresa-checkbox');
        const empresasCheckboxesDesktop = document.querySelectorAll('#filtrosFormDesktop input.empresa-checkbox');
        
        const isChecked = checkboxMobile?.checked || checkboxDesktop?.checked;
        
        empresasCheckboxesMobile.forEach(cb => cb.checked = isChecked);
        empresasCheckboxesDesktop.forEach(cb => cb.checked = isChecked);
        
        // Sincronizar checkbox "Selecionar Todas" entre mobile e desktop
        if (checkboxMobile) checkboxMobile.checked = isChecked;
        if (checkboxDesktop) checkboxDesktop.checked = isChecked;
        
        // Atualizar label
        atualizarLabelEmpresas();
    }

    function toggleTodosMeses() {
        const checkboxMobile = document.getElementById('selecionarTodosMeses');
        const checkboxDesktop = document.getElementById('selecionarTodosMesesDesktop');

        const mesesCheckboxesMobile = document.querySelectorAll('#filtrosForm input.mes-checkbox');
        const mesesCheckboxesDesktop = document.querySelectorAll('#filtrosFormDesktop input.mes-checkbox');

        const isChecked = checkboxMobile?.checked || checkboxDesktop?.checked;

        mesesCheckboxesMobile.forEach(cb => cb.checked = isChecked);
        mesesCheckboxesDesktop.forEach(cb => cb.checked = isChecked);

        if (checkboxMobile) checkboxMobile.checked = isChecked;
        if (checkboxDesktop) checkboxDesktop.checked = isChecked;

        atualizarLabelMeses();
    }
    
    // Inicializar labels ao carregar página
    document.addEventListener('DOMContentLoaded', function() {
        atualizarLabelEmpresas();
        atualizarLabelMeses();
        
        // Inicializar tooltips do Bootstrap
        const tooltipTriggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tooltip"]'));
        tooltipTriggerList.map(function (tooltipTriggerEl) {
            return new bootstrap.Tooltip(tooltipTriggerEl);
        });

        // Se trimestre estiver selecionado, sincroniza meses automaticamente (desktop e mobile)
        const triDesk = document.getElementById('filtroTrimestreDesktop');
        const triMob  = document.getElementById('filtroTrimestre');
        const triInicial = Number(triDesk?.value || triMob?.value || 0);
        if (triInicial > 0) {
            sincronizarSelectTrimestre(triInicial);
            sincronizarMesesComTrimestre(triInicial);
        }

        // Ao mudar trimestre, forçar meses do trimestre e manter selects sincronizados
        [triDesk, triMob].forEach(el => {
            if (!el) return;
            el.addEventListener('change', () => {
                const tri = Number(el.value || 0);
                sincronizarSelectTrimestre(tri);
                if (tri > 0) {
                    sincronizarMesesComTrimestre(tri);
                }
            });
        });

        // Inverso: ao mudar meses manualmente, limpar trimestre (para não ficar incoerente)
        const attachMesChangeHandler = (formSel) => {
            const form = document.querySelector(formSel);
            if (!form) return;
            form.querySelectorAll('input.mes-checkbox').forEach(cb => {
                cb.addEventListener('change', () => {
                    if (window.__syncMesesFromTrimestre === true) return;
                    const triDesk2 = document.getElementById('filtroTrimestreDesktop');
                    const triMob2  = document.getElementById('filtroTrimestre');
                    const triAtual = Number(triDesk2?.value || triMob2?.value || 0);
                    if (triAtual > 0) {
                        sincronizarSelectTrimestre(0);
                    }
                    atualizarLabelMeses();
                });
            });
        };

        attachMesChangeHandler('#filtrosForm');
        attachMesChangeHandler('#filtrosFormDesktop');

        // Marcar interação explícita com o filtro de País (desktop e mobile)
        // (select não dispara 'change' quando re-seleciona o mesmo valor; por isso usamos interação)
        window.__paisTouched = false;
        window.__moedaTouched = false;
        ['#filtroPaisDesktop', '#filtroPais'].forEach(sel => {
            const el = document.querySelector(sel);
            if (!el) return;
            el.addEventListener('mousedown', () => { window.__paisTouched = true; }, { passive: true });
            el.addEventListener('focus', () => { window.__paisTouched = true; }, { passive: true });
        });

        ['#filtroMoedaDesktop', '#filtroMoeda'].forEach(sel => {
            const el = document.querySelector(sel);
            if (!el) return;
            el.addEventListener('mousedown', () => { window.__moedaTouched = true; }, { passive: true });
            el.addEventListener('focus', () => { window.__moedaTouched = true; }, { passive: true });
        });

        // Evitar que o dropdown feche ao clicar dentro (checkbox/label)
        document.querySelectorAll('#filtrosFormDesktop .dropdown-menu').forEach(menu => {
            menu.addEventListener('click', function(e) {
                e.stopPropagation();
            });
        });
        
        // DEBUG: Log do estado dos checkboxes ao carregar
        const checkboxesDesktop = document.querySelectorAll('#filtrosFormDesktop input.empresa-checkbox:checked');
        const checkboxesMobile = document.querySelectorAll('#filtrosForm input.empresa-checkbox:checked');
        console.log('[DOMContentLoaded] Checkboxes marcadas no Desktop:', Array.from(checkboxesDesktop).map(cb => cb.value));
        console.log('[DOMContentLoaded] Checkboxes marcadas no Mobile:', Array.from(checkboxesMobile).map(cb => cb.value));
        
        // Sincronizar estado do "Selecionar Todas"
        const totalCheckboxes = document.querySelectorAll('#filtrosFormDesktop input.empresa-checkbox').length;
        const checkedDesktop = document.querySelectorAll('#filtrosFormDesktop input.empresa-checkbox:checked').length;
        const checkedMobile = document.querySelectorAll('#filtrosForm input.empresa-checkbox:checked').length;
        
        const selecionarTodasDesktop = document.getElementById('selecionarTodasDesktop');
        const selecionarTodasMobile = document.getElementById('selecionarTodas');
        
        // Se todos estão marcados, marcar "Selecionar Todas"
        if (selecionarTodasDesktop && checkedDesktop === totalCheckboxes && totalCheckboxes > 0) {
            selecionarTodasDesktop.checked = true;
            console.log('[DOMContentLoaded] Todos selecionados (Desktop) - marcando checkbox "Selecionar Todas"');
        }
        if (selecionarTodasMobile && checkedMobile === totalCheckboxes && totalCheckboxes > 0) {
            selecionarTodasMobile.checked = true;
            console.log('[DOMContentLoaded] Todos selecionados (Mobile) - marcando checkbox "Selecionar Todas"');
        }
    });
</script>
