<?php
require_once(dirname(__DIR__) . '/config/db.php');
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);

$cdempresa = $_SESSION['cdempresa'] ?? 1;

// Exercícios disponíveis
$stmt = $pdo->prepare("
  SELECT cdexercicio, anoref
    FROM back.exercicio
   WHERE cdempresa = :emp AND flativo = 0
   ORDER BY anoref ASC
");
$stmt->execute([':emp' => $cdempresa]);
$exercicios = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Centros de custo
$stmt = $pdo->prepare("
  SELECT cdcentrocusto, dscentro
    FROM back.centro_custo
   WHERE flativo = 0 AND cdcentropai IS NOT NULL
   ORDER BY dscentro
");
$stmt->execute();
$centros = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Moeda da empresa
$stmt = $pdo->prepare("
  SELECT m.simbolo, m.formato
    FROM back.empresa e
    LEFT JOIN back.moeda m ON m.cdmoeda = e.cdmoeda
   WHERE e.cdempresa = :emp
");
$stmt->execute([':emp' => $cdempresa]);
$moeda = $stmt->fetch(PDO::FETCH_ASSOC) ?? ['simbolo' => 'R$', 'formato' => 'decimal'];

// Variáveis disponíveis (tipo Relatório)
$stmt = $pdo->prepare("
  SELECT DISTINCT v.cdvariavel, v.nome, v.tipo, v.modelo
    FROM back.variavel v
    JOIN back.variavel_empresa ve ON ve.cdvariavel = v.cdvariavel AND ve.cdempresa = :emp
   WHERE v.flativo = 0
     AND v.tipo = 'Relatorio'
   ORDER BY v.nome
");
$stmt->execute([':emp' => $cdempresa]);
$variaveis = $stmt->fetchAll(PDO::FETCH_ASSOC);

// Indicadores disponíveis (se tabela existir)
$indicadores = [];
$gruposIndicadores = [];
try {
  $stmt = $pdo->prepare("
    SELECT i.cdindicador, i.nome, i.cdgrupo
      FROM back.indicador i
      JOIN back.indicador_empresa ie ON ie.cdindicador = i.cdindicador AND ie.cdempresa = :emp
     WHERE i.flativo = 0
     ORDER BY i.ordem NULLS LAST, i.nome
  ");
  $stmt->execute([':emp' => $cdempresa]);
  $indicadores = $stmt->fetchAll(PDO::FETCH_ASSOC);

  $gruposIndicadores = $pdo->query("SELECT cdgrupo, dsgrupo FROM back.grupo_indicador WHERE flativo = 0 ORDER BY ordem NULLS LAST, dsgrupo")->fetchAll(PDO::FETCH_ASSOC);
} catch (Exception $e) {
  // Tabela ainda não criada
}

$anoAtual = (int)date('Y');
$mesAtual = (int)date('n');
$triAtual = (int)ceil($mesAtual / 3);
$triAnterior = $triAtual > 1 ? $triAtual - 1 : 4;
$semAtual = $mesAtual <= 6 ? 1 : 2;
$mesesCurto = ['','Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];
?>

<h4 class="mb-3"><i class="bi bi-arrow-left-right"></i> Análise Comparativa</h4>
<hr>

<div class="d-flex flex-column gap-3">

  <!-- Filtros -->
  <div class="card border-0 shadow-sm">
    <div class="card-body py-3">

      <!-- Análise + Granularidade na mesma linha -->
      <div class="d-flex align-items-center gap-4 mb-3 flex-wrap">
        <div class="d-flex align-items-center gap-2">
          <span class="fw-semibold text-secondary" style="font-size:0.9rem;">Análise:</span>
          <div class="btn-group" role="group">
            <input type="radio" class="btn-check" name="tipoAnalise" id="tipoRealizado" value="realizado" checked>
            <label class="btn btn-outline-dark" for="tipoRealizado" style="font-size:0.9rem;"><i class="bi bi-receipt"></i> Realizado</label>
            <input type="radio" class="btn-check" name="tipoAnalise" id="tipoOrcReal" value="orcreal">
            <label class="btn btn-outline-dark" for="tipoOrcReal" style="font-size:0.9rem;"><i class="bi bi-file-earmark-bar-graph"></i> Orçado x Realizado</label>
            <input type="radio" class="btn-check" name="tipoAnalise" id="tipoVariaveis" value="variaveis">
            <label class="btn btn-outline-dark" for="tipoVariaveis" style="font-size:0.9rem;"><i class="bi bi-calculator"></i> Variáveis</label>
            <input type="radio" class="btn-check" name="tipoAnalise" id="tipoIndicadores" value="indicadores">
            <label class="btn btn-outline-dark" for="tipoIndicadores" style="font-size:0.9rem;"><i class="bi bi-clipboard-data"></i> Indicadores</label>
          </div>
        </div>
        <div class="d-flex align-items-center gap-2">
          <span class="fw-semibold text-secondary" style="font-size:0.9rem;">Granularidade:</span>
          <div class="btn-group" role="group">
            <input type="radio" class="btn-check" name="granularidade" id="granMes" value="mes">
            <label class="btn btn-outline-primary" for="granMes" style="font-size:0.9rem;">Mês</label>
            <input type="radio" class="btn-check" name="granularidade" id="granTri" value="trimestre" checked>
            <label class="btn btn-outline-primary" for="granTri" style="font-size:0.9rem;">Trimestre</label>
            <input type="radio" class="btn-check" name="granularidade" id="granSem" value="semestre">
            <label class="btn btn-outline-primary" for="granSem" style="font-size:0.9rem;">Semestre</label>
            <input type="radio" class="btn-check" name="granularidade" id="granAno" value="ano">
            <label class="btn btn-outline-primary" for="granAno" style="font-size:0.9rem;">Ano</label>
          </div>
        </div>
      </div>

      <!-- Períodos A / VS+Botões / B -->
      <div class="row g-3">
        <!-- Período A -->
        <div class="col-md-5">
          <div class="card bg-light border-0">
            <div class="card-body py-2 px-3">
              <div class="fw-semibold text-primary mb-2" style="font-size:0.9rem;"><i class="bi bi-calendar3"></i> Período A</div>
              <div class="row g-2">
                <div class="col">
                  <label class="small">Ano</label>
                  <select class="form-select form-select-sm" id="anoA">
                    <?php foreach ($exercicios as $ex): ?>
                      <option value="<?= (int)$ex['anoref'] ?>" <?= (int)$ex['anoref'] === ($anoAtual - 1) ? 'selected' : '' ?>>
                        <?= htmlspecialchars($ex['anoref']) ?>
                      </option>
                    <?php endforeach; ?>
                  </select>
                </div>
                <div class="col-12 filtro-mes" style="display:none;">
                  <label class="small d-block mb-1">Meses</label>
                  <div class="d-flex flex-wrap gap-1">
                    <?php for ($i = 1; $i <= 12; $i++): ?>
                    <div>
                      <input type="checkbox" class="btn-check mesA-check" value="<?= $i ?>" id="mesA<?= $i ?>" <?= $i === $mesAtual ? 'checked' : '' ?> autocomplete="off">
                      <label class="btn btn-outline-primary btn-sm py-0 px-2" for="mesA<?= $i ?>"><?= $mesesCurto[$i] ?></label>
                    </div>
                    <?php endfor; ?>
                  </div>
                </div>
                <div class="col filtro-tri">
                  <label class="small">Trimestre</label>
                  <select class="form-select form-select-sm" id="triA">
                    <option value="1" <?= $triAnterior === 1 ? 'selected' : '' ?>>T1 (Jan-Mar)</option>
                    <option value="2" <?= $triAnterior === 2 ? 'selected' : '' ?>>T2 (Abr-Jun)</option>
                    <option value="3" <?= $triAnterior === 3 ? 'selected' : '' ?>>T3 (Jul-Set)</option>
                    <option value="4" <?= $triAnterior === 4 ? 'selected' : '' ?>>T4 (Out-Dez)</option>
                  </select>
                </div>
                <div class="col filtro-sem" style="display:none;">
                  <label class="small">Semestre</label>
                  <select class="form-select form-select-sm" id="semA">
                    <option value="1" <?= $semAtual === 1 ? 'selected' : '' ?>>S1 (Jan-Jun)</option>
                    <option value="2" <?= $semAtual === 2 ? 'selected' : '' ?>>S2 (Jul-Dez)</option>
                  </select>
                </div>
              </div>
            </div>
          </div>
        </div>

        <!-- VS + Ações centralizadas -->
        <div class="col-md-2 d-flex flex-column align-items-center justify-content-center gap-2">
          <span class="badge bg-secondary fs-6 px-3 py-2">VS</span>
          <button class="btn btn-primary btn-sm w-100" id="btnComparar" style="font-size:0.9rem;">
            <i class="bi bi-arrow-left-right"></i> Comparar
          </button>
          <button class="btn btn-outline-secondary btn-sm w-100" id="btnExportCSV" disabled style="font-size:0.85rem;">
            <i class="bi bi-download"></i> Exportar CSV
          </button>
        </div>

        <!-- Período B -->
        <div class="col-md-5">
          <div class="card bg-light border-0">
            <div class="card-body py-2 px-3">
              <div class="fw-semibold text-info mb-2" style="font-size:0.9rem;"><i class="bi bi-calendar3"></i> Período B</div>
              <div class="row g-2">
                <div class="col">
                  <label class="small">Ano</label>
                  <select class="form-select form-select-sm" id="anoB">
                    <?php foreach ($exercicios as $ex): ?>
                      <option value="<?= (int)$ex['anoref'] ?>" <?= (int)$ex['anoref'] === $anoAtual ? 'selected' : '' ?>>
                        <?= htmlspecialchars($ex['anoref']) ?>
                      </option>
                    <?php endforeach; ?>
                  </select>
                </div>
                <div class="col-12 filtro-mes" style="display:none;">
                  <label class="small d-block mb-1">Meses</label>
                  <div class="d-flex flex-wrap gap-1">
                    <?php for ($i = 1; $i <= 12; $i++): ?>
                    <div>
                      <input type="checkbox" class="btn-check mesB-check" value="<?= $i ?>" id="mesB<?= $i ?>" <?= $i === $mesAtual ? 'checked' : '' ?> autocomplete="off">
                      <label class="btn btn-outline-info btn-sm py-0 px-2" for="mesB<?= $i ?>"><?= $mesesCurto[$i] ?></label>
                    </div>
                    <?php endfor; ?>
                  </div>
                </div>
                <div class="col filtro-tri">
                  <label class="small">Trimestre</label>
                  <select class="form-select form-select-sm" id="triB">
                    <option value="1" <?= $triAnterior === 1 ? 'selected' : '' ?>>T1 (Jan-Mar)</option>
                    <option value="2" <?= $triAnterior === 2 ? 'selected' : '' ?>>T2 (Abr-Jun)</option>
                    <option value="3" <?= $triAnterior === 3 ? 'selected' : '' ?>>T3 (Jul-Set)</option>
                    <option value="4" <?= $triAnterior === 4 ? 'selected' : '' ?>>T4 (Out-Dez)</option>
                  </select>
                </div>
                <div class="col filtro-sem" style="display:none;">
                  <label class="small">Semestre</label>
                  <select class="form-select form-select-sm" id="semB">
                    <option value="1" <?= $semAtual === 1 ? 'selected' : '' ?>>S1 (Jan-Jun)</option>
                    <option value="2" <?= $semAtual === 2 ? 'selected' : '' ?>>S2 (Jul-Dez)</option>
                  </select>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>

      <!-- Filtros adicionais + Atalhos -->
      <div class="row g-2 mt-2 align-items-end">
        <div class="col-md-2 filtro-conta-wrap">
          <label class="small">Centro de Custo</label>
          <select class="form-select form-select-sm" id="filtroCentro">
            <option value="">Todos</option>
            <?php foreach ($centros as $c): ?>
              <option value="<?= (int)$c['cdcentrocusto'] ?>"><?= htmlspecialchars($c['dscentro']) ?></option>
            <?php endforeach; ?>
          </select>
        </div>

        <div class="col-md-2 filtro-conta-wrap">
          <label class="small">Tipo Movimento</label>
          <select class="form-select form-select-sm" id="filtroTpMov">
            <option value="">Todos (C-D)</option>
            <option value="C">Crédito (C)</option>
            <option value="D">Débito (D)</option>
          </select>
        </div>

        <div class="col-md-2 filtro-conta-wrap">
          <label class="small">Pesquisar conta</label>
          <input type="text" class="form-control form-control-sm" id="filtroConta" placeholder="Nome ou código..." disabled>
        </div>

        <!-- Filtro variável (aparece quando tipo=variaveis) -->
        <div class="col-md-4 filtro-variavel-wrap" style="display:none;">
          <label class="small d-block mb-1">Variável</label>
          <div class="d-flex flex-wrap gap-1">
            <?php foreach ($variaveis as $v): ?>
            <div>
              <input type="checkbox" class="btn-check varCheck" value="<?= (int)$v['cdvariavel'] ?>" id="varCk<?= (int)$v['cdvariavel'] ?>" autocomplete="off" checked>
              <label class="btn btn-outline-primary btn-sm py-0 px-2" for="varCk<?= (int)$v['cdvariavel'] ?>"><?= htmlspecialchars($v['nome']) ?></label>
            </div>
            <?php endforeach; ?>
          </div>
        </div>

        <!-- Sub-modo variável -->
        <div class="col-md-3 filtro-variavel-wrap" style="display:none;">
          <label class="small">Modo comparação</label>
          <select class="form-select form-select-sm" id="filtroVarModo">
            <option value="periodo">Período A vs Período B</option>
            <option value="orcreal">Orçado vs Realizado</option>
          </select>
        </div>

        <!-- Filtro grupo indicador (aparece quando tipo=indicadores) -->
        <div class="col-md-2 filtro-indicador-wrap" style="display:none;">
          <label class="small">Grupo</label>
          <select class="form-select form-select-sm" id="filtroGrupoIndicador">
            <option value="">Todos</option>
            <?php foreach ($gruposIndicadores as $gi): ?>
              <option value="<?= (int)$gi['cdgrupo'] ?>"><?= htmlspecialchars($gi['dsgrupo']) ?></option>
            <?php endforeach; ?>
          </select>
        </div>

        <!-- Filtro indicador (aparece quando tipo=indicadores) -->
        <div class="col-md-3 filtro-indicador-wrap" style="display:none;">
          <label class="small">Indicador</label>
          <select class="form-select form-select-sm" id="filtroIndicador">
            <option value="">Todos</option>
            <?php foreach ($indicadores as $ind): ?>
              <option value="<?= (int)$ind['cdindicador'] ?>" data-cdgrupo="<?= (int)($ind['cdgrupo'] ?? 0) ?>"><?= htmlspecialchars($ind['nome']) ?></option>
            <?php endforeach; ?>
          </select>
        </div>

        <!-- Toggle direção desvio (aparece quando tipo=orcreal) -->
        <div class="col-md-2 filtro-orcreal-wrap" style="display:none;">
          <label class="small">Desvio</label>
          <select class="form-select form-select-sm" id="filtroDesvioDir">
            <option value="real-orc">Real − Orç</option>
            <option value="orc-real">Orç − Real</option>
          </select>
        </div>

        <!-- Atalhos sempre na mesma linha após filtros -->
        <div class="col d-flex gap-2 align-items-end">
          <div class="vr mx-1 d-none d-md-block"></div>
          <span class="small text-muted text-nowrap">Atalhos:</span>
          <button class="btn btn-outline-info btn-sm text-nowrap" data-atalho="mes-anterior" title="Mesmo mês, ano anterior" style="font-size:0.85rem;">
            <i class="bi bi-skip-backward"></i> Mês ant.
          </button>
          <button class="btn btn-outline-info btn-sm text-nowrap" data-atalho="tri-anterior" title="Mesmo trimestre, ano anterior" style="font-size:0.85rem;">
            <i class="bi bi-skip-backward-fill"></i> Tri ant.
          </button>
          <button class="btn btn-outline-info btn-sm text-nowrap" data-atalho="ytd" title="Acumulado do ano vs ano anterior" style="font-size:0.85rem;">
            <i class="bi bi-calendar-range"></i> YTD
          </button>
        </div>
      </div>

    </div>
  </div>

  <!-- KPIs (genérico – conteúdo renderizado via JS conforme tipo) -->
  <div class="row g-3" id="kpiContainer" style="display:none;">
    <div id="kpiContent" class="col-12">
      <!-- Preenchido dinamicamente -->
    </div>
  </div>

  <!-- Ordenação + Visualização -->
  <div class="d-flex gap-2 align-items-center flex-wrap" id="ordenacaoContainer" style="display:none;">
    <span class="ordenacao-conta-wrap">
    <span class="small text-muted">Ordenar:</span>
    <div class="btn-group btn-group-sm">
      <button class="btn btn-outline-secondary active" data-sort="conta">
        <i class="bi bi-sort-alpha-down"></i> Conta
      </button>
      <button class="btn btn-outline-success" data-sort="melhor">
        <i class="bi bi-graph-up-arrow"></i> Melhor Desempenho
      </button>
      <button class="btn btn-outline-danger" data-sort="pior">
        <i class="bi bi-graph-down-arrow"></i> Pior Desempenho
      </button>
      <button class="btn btn-outline-primary" data-sort="maior-valor">
        <i class="bi bi-currency-dollar"></i> Maior Valor
      </button>
    </div>
    <div class="vr mx-1 d-none d-md-block"></div>
    </span>
    <span class="visao-conta-wrap">
    <span class="small text-muted">Visão:</span>
    <div class="btn-group btn-group-sm">
      <input type="radio" class="btn-check" name="viewMode" id="viewArvore" value="arvore" checked>
      <label class="btn btn-outline-secondary" for="viewArvore"><i class="bi bi-diagram-3"></i> Árvore</label>
      <input type="radio" class="btn-check" name="viewMode" id="viewLista" value="lista">
      <label class="btn btn-outline-secondary" for="viewLista"><i class="bi bi-list-ul"></i> Lista</label>
    </div>
    <div class="vr mx-1 d-none d-md-block"></div>
    </span>
    <span class="small text-muted">Valores:</span>
    <div class="d-flex gap-1">
      <button type="button" class="comp-numerico-btn active" data-exibicao="compacta" title="Valores compactos (K, M)">$</button>
      <button type="button" class="comp-numerico-btn" data-exibicao="completa" title="Valores completos">$$</button>
    </div>
  </div>

  <!-- Tabela comparativa -->
  <div class="card border-0 shadow-sm" id="tabelaContainer" style="display:none;">
    <div class="card-body p-0">
      <div style="overflow-x: auto;">
        <table class="table table-hover align-middle mb-0" style="font-size: 1rem; white-space: nowrap;" id="tabelaComparativo">
          <thead id="tabelaHead" style="position: sticky; top: 0; background: #f8f9fa; z-index: 10; border-bottom: 2px solid #dee2e6;">
          </thead>
          <tbody id="tabelaBody">
          </tbody>
          <tfoot id="tabelaFoot" style="font-weight: 700; background: #f0f4f8; border-top: 2px solid #dee2e6;">
          </tfoot>
        </table>
      </div>
    </div>
  </div>

  <!-- Mensagem vazia -->
  <div class="text-center text-muted py-5" id="msgVazio">
    <i class="bi bi-arrow-left-right" style="font-size: 2.5rem; opacity: 0.3;"></i>
    <p class="mt-2">Selecione dois períodos e clique em <strong>Comparar</strong> para visualizar a análise.</p>
  </div>

</div>

<!-- Modal Detalhe Lançamentos -->
<div class="modal fade" id="modalDetalheComp" tabindex="-1" style="z-index: 1065;">
  <div class="modal-dialog modal-lg" style="max-width: 90vw;">
    <div class="modal-content" style="max-height: 90vh;">
      <div class="modal-header bg-white py-3" style="border-bottom: 1px solid #dee2e6;">
        <h5 class="modal-title text-dark"><i class="bi bi-list-ul me-2"></i> Detalhe dos Lançamentos</h5>
        <button type="button" class="btn-close" data-bs-dismiss="modal"></button>
      </div>
      <div class="modal-body p-0" style="flex:1; overflow:hidden; display:flex; flex-direction:column;">
        <div class="p-3 border-bottom" style="background:#f8f9fa;">
          <div class="small text-muted mb-2" id="detalheCompContaInfo"></div>
          <div class="row g-2 align-items-end">
            <div class="col-md-3">
              <label class="small fw-semibold">Data Inicial</label>
              <input type="date" class="form-control form-control-sm" id="detalheCompDataIni">
            </div>
            <div class="col-md-3">
              <label class="small fw-semibold">Data Final</label>
              <input type="date" class="form-control form-control-sm" id="detalheCompDataFim">
            </div>
            <div class="col-md-2">
              <button class="btn btn-primary btn-sm" id="btnFiltrarDetalheComp"><i class="bi bi-search"></i> Filtrar</button>
            </div>
          </div>
        </div>
        <div class="p-2 border-bottom" style="background:#ffffff;">
          <div class="small" id="detalheCompTotaisResumo"></div>
        </div>
        <div style="flex:1; overflow-y:auto;">
          <table class="table table-hover align-middle mb-0" style="font-size:0.95rem;">
            <thead style="position:sticky; top:0; background:#f8f9fa; z-index:100;">
              <tr>
                <th>Conta</th>
                <th style="width:120px;">Data</th>
                <th>Descrição</th>
                <th style="width:90px;" class="text-center">Tipo</th>
                <th style="width:140px;" class="text-end">Valor</th>
              </tr>
            </thead>
            <tbody id="tbDetalheComp"></tbody>
            <tfoot style="background:#f8f9fa; position:sticky; bottom:0;">
              <tr>
                <th colspan="4" class="text-end">Total</th>
                <th class="text-end" id="detalheCompTotalValor">0,00</th>
              </tr>
            </tfoot>
          </table>
        </div>
      </div>
      <div class="modal-footer py-2">
        <button class="btn btn-secondary btn-sm" data-bs-dismiss="modal">Fechar</button>
      </div>
    </div>
  </div>
</div>

<style>
.comp-numerico-btn {
    padding: 5px 12px;
    border-radius: 20px;
    font-size: 0.9rem;
    font-weight: 700;
    border: 1px solid #cbd5e1;
    cursor: pointer;
    transition: all 0.2s ease;
    color: #475569;
    background: #fff;
    white-space: nowrap;
    min-width: 36px;
    text-align: center;
    font-family: monospace;
}
.comp-numerico-btn:hover {
    background: #f1f5f9;
    border-color: #94a3b8;
}
.comp-numerico-btn.active {
    background: #2563eb;
    color: #ffffff;
    border-color: #2563eb;
}
</style>
<script>
(function() {
  const SIMBOLO = <?= json_encode($moeda['simbolo']) ?>;
  const MOEDA_FORMATO = <?= json_encode($moeda['formato'] ?? 'decimal') ?>;
  const MESES_NOME = ['','Janeiro','Fevereiro','Março','Abril','Maio','Junho','Julho','Agosto','Setembro','Outubro','Novembro','Dezembro'];
  const TRI_MESES = {1:[1,2,3], 2:[4,5,6], 3:[7,8,9], 4:[10,11,12]};
  const TRI_NOME = {1:'T1 (Jan-Mar)', 2:'T2 (Abr-Jun)', 3:'T3 (Jul-Set)', 4:'T4 (Out-Dez)'};
  const SEM_MESES = {1:[1,2,3,4,5,6], 2:[7,8,9,10,11,12]};
  const SEM_NOME = {1:'S1 (Jan-Jun)', 2:'S2 (Jul-Dez)'};
  const MESES_NOME_CURTO = ['','Jan','Fev','Mar','Abr','Mai','Jun','Jul','Ago','Set','Out','Nov','Dez'];

  let dadosAtuais = null;
  let sortCol = 'conta';
  let sortAsc = true;
  let expandedNodes = new Set();
  let viewMode = 'arvore'; // 'arvore' ou 'lista'
  let detalheCompAtual = null;
  let modalDetalheComp = null;
  let exibicaoValor = 'compacta'; // 'compacta' ou 'completa'
  let tipoAnalise = 'realizado'; // 'realizado', 'orcreal', 'variaveis', 'indicadores'

  // ============================
  // TIPO DE ANÁLISE
  // ============================
  document.querySelectorAll('input[name="tipoAnalise"]').forEach(radio => {
    radio.addEventListener('change', function() {
      tipoAnalise = this.value;
      // Show/hide filtros específicos
      document.querySelectorAll('.filtro-conta-wrap').forEach(el => el.style.display = (tipoAnalise === 'realizado' || tipoAnalise === 'orcreal') ? '' : 'none');
      document.querySelectorAll('.filtro-variavel-wrap').forEach(el => el.style.display = tipoAnalise === 'variaveis' ? '' : 'none');
      document.querySelectorAll('.filtro-indicador-wrap').forEach(el => el.style.display = tipoAnalise === 'indicadores' ? '' : 'none');
      document.querySelectorAll('.filtro-orcreal-wrap').forEach(el => el.style.display = tipoAnalise === 'orcreal' ? '' : 'none');
      // Sort/View controls only for conta-based tipos
      const contaTipos = (tipoAnalise === 'realizado' || tipoAnalise === 'orcreal');
      document.querySelectorAll('.ordenacao-conta-wrap').forEach(el => el.style.display = contaTipos ? '' : 'none');
      document.querySelectorAll('.visao-conta-wrap').forEach(el => el.style.display = contaTipos ? '' : 'none');
      // Indicadores: default valores completos ($$)
      if (tipoAnalise === 'indicadores') {
        exibicaoValor = 'completa';
        document.querySelectorAll('.comp-numerico-btn').forEach(b => {
          b.classList.toggle('active', b.dataset.exibicao === 'completa');
        });
      }
      // Reset display
      dadosAtuais = null;
      document.getElementById('kpiContainer').style.display = 'none';
      document.getElementById('ordenacaoContainer').style.display = 'none';
      document.getElementById('tabelaContainer').style.display = 'none';
      document.getElementById('msgVazio').style.display = '';
    });
  });

  // ============================
  // AJUSTE ANO PARA TRIMESTRE ANTERIOR (quando T1 → T4 do ano anterior)
  // ============================
  <?php if ($triAnterior === 4 && $triAtual === 1): ?>
  document.getElementById('anoB').value = <?= $anoAtual - 1 ?>;
  document.getElementById('anoA').value = <?= $anoAtual - 2 ?>;
  <?php endif; ?>

  // ============================
  // GRANULARIDADE
  // ============================
  document.querySelectorAll('input[name="granularidade"]').forEach(radio => {
    radio.addEventListener('change', function() {
      const v = this.value;
      document.querySelectorAll('.filtro-mes').forEach(el => el.style.display = v === 'mes' ? '' : 'none');
      document.querySelectorAll('.filtro-tri').forEach(el => el.style.display = v === 'trimestre' ? '' : 'none');
      document.querySelectorAll('.filtro-sem').forEach(el => el.style.display = v === 'semestre' ? '' : 'none');
    });
  });

  // ============================
  // ATALHOS
  // ============================
  document.querySelectorAll('[data-atalho]').forEach(btn => {
    btn.addEventListener('click', function() {
      const tipo = this.dataset.atalho;
      const anoAtual = <?= $anoAtual ?>;
      const mesAtual = <?= $mesAtual ?>;

      if (tipo === 'mes-anterior') {
        document.getElementById('granMes').checked = true;
        document.getElementById('granMes').dispatchEvent(new Event('change'));
        document.getElementById('anoA').value = anoAtual - 1;
        document.querySelectorAll('.mesA-check').forEach(cb => cb.checked = (parseInt(cb.value) === mesAtual));
        document.getElementById('anoB').value = anoAtual;
        document.querySelectorAll('.mesB-check').forEach(cb => cb.checked = (parseInt(cb.value) === mesAtual));
      } else if (tipo === 'tri-anterior') {
        const triAtual = Math.ceil(mesAtual / 3);
        document.getElementById('granTri').checked = true;
        document.getElementById('granTri').dispatchEvent(new Event('change'));
        document.getElementById('anoA').value = anoAtual - 1;
        document.getElementById('triA').value = triAtual;
        document.getElementById('anoB').value = anoAtual;
        document.getElementById('triB').value = triAtual;
      } else if (tipo === 'ytd') {
        // YTD: meses 1 até mesAtual de cada ano
        document.getElementById('granMes').checked = true;
        document.getElementById('granMes').dispatchEvent(new Event('change'));
        document.getElementById('anoA').value = anoAtual - 1;
        document.getElementById('anoB').value = anoAtual;
        document.querySelectorAll('.mesA-check').forEach(cb => cb.checked = (parseInt(cb.value) <= mesAtual));
        document.querySelectorAll('.mesB-check').forEach(cb => cb.checked = (parseInt(cb.value) <= mesAtual));
      }

      executarComparacao(tipo === 'ytd' ? 'ytd' : null);
    });
  });

  // ============================
  // COMPARAR
  // ============================
  document.getElementById('btnComparar').addEventListener('click', () => executarComparacao());

  function getMesesSelecionados(modoOverride) {
    const gran = document.querySelector('input[name="granularidade"]:checked').value;

    if (modoOverride === 'ytd') {
      const mesAtual = <?= $mesAtual ?>;
      const meses = [];
      for (let i = 1; i <= mesAtual; i++) meses.push(i);
      return { mesesA: meses, mesesB: [...meses] };
    }

    if (gran === 'mes') {
      return {
        mesesA: [...document.querySelectorAll('.mesA-check:checked')].map(cb => parseInt(cb.value)),
        mesesB: [...document.querySelectorAll('.mesB-check:checked')].map(cb => parseInt(cb.value)),
      };
    } else if (gran === 'trimestre') {
      return {
        mesesA: TRI_MESES[parseInt(document.getElementById('triA').value)],
        mesesB: TRI_MESES[parseInt(document.getElementById('triB').value)],
      };
    } else if (gran === 'semestre') {
      return {
        mesesA: SEM_MESES[parseInt(document.getElementById('semA').value)],
        mesesB: SEM_MESES[parseInt(document.getElementById('semB').value)],
      };
    } else { // ano
      return {
        mesesA: [1,2,3,4,5,6,7,8,9,10,11,12],
        mesesB: [1,2,3,4,5,6,7,8,9,10,11,12],
      };
    }
  }

  function getLabelPeriodo(ano, meses) {
    if (meses.length === 12) return `Ano ${ano}`;
    if (meses.length === 6) {
      const sem = Object.entries(SEM_MESES).find(([k, v]) => JSON.stringify(v) === JSON.stringify(meses));
      if (sem) return `${SEM_NOME[sem[0]]} ${ano}`;
    }
    if (meses.length === 3) {
      const tri = Object.entries(TRI_MESES).find(([k, v]) => JSON.stringify(v) === JSON.stringify(meses));
      if (tri) return `${TRI_NOME[tri[0]]} ${ano}`;
    }
    if (meses.length === 1) return `${MESES_NOME[meses[0]]}/${ano}`;
    // Multi-meses (YTD ou custom)
    return `${MESES_NOME[meses[0]]}-${MESES_NOME[meses[meses.length-1]]}/${ano}`;
  }

  async function executarComparacao(modoOverride) {
    const anoA = document.getElementById('anoA').value;
    const anoB = document.getElementById('anoB').value;
    const { mesesA, mesesB } = getMesesSelecionados(modoOverride || null);
    const cc = document.getElementById('filtroCentro').value;
    const tpmov = document.getElementById('filtroTpMov').value;

    // Dispatch por tipo de análise
    const backendMap = {
      realizado: 'comparativo_realizado_actions',
      orcreal: 'comparativo_orcreal_actions',
      variaveis: 'comparativo_variaveis_actions',
      indicadores: 'comparativo_indicadores_actions',
    };

    const params = new URLSearchParams();
    params.set('m', backendMap[tipoAnalise] || backendMap.realizado);
    params.set('ajax', 'comparar_periodos');
    params.set('ano_a', anoA);
    params.set('ano_b', anoB);
    mesesA.forEach(m => params.append('meses_a[]', m));
    mesesB.forEach(m => params.append('meses_b[]', m));
    if ((tipoAnalise === 'realizado' || tipoAnalise === 'orcreal') && cc) params.set('cdcentrocusto', cc);
    if ((tipoAnalise === 'realizado' || tipoAnalise === 'orcreal') && tpmov) params.set('tpmovimento', tpmov);
    if (tipoAnalise === 'orcreal') params.set('desvio_dir', document.getElementById('filtroDesvioDir').value);
    if (tipoAnalise === 'variaveis') {
      document.querySelectorAll('.varCheck:checked').forEach(cb => params.append('cdvariavel[]', cb.value));
      params.set('modo', document.getElementById('filtroVarModo').value);
    }
    if (tipoAnalise === 'indicadores') {
      params.set('cdindicador', document.getElementById('filtroIndicador').value);
      params.set('cdgrupo', document.getElementById('filtroGrupoIndicador').value);
    }

    document.getElementById('btnComparar').disabled = true;
    document.getElementById('btnComparar').innerHTML = '<span class="spinner-border spinner-border-sm"></span> Comparando...';

    try {
      const resp = await fetch('?' + params.toString());
      const data = await resp.json();

      if (!data.ok) {
        alert(data.msg || 'Erro ao comparar períodos.');
        return;
      }

      // Labels
      const labelA = getLabelPeriodo(anoA, mesesA);
      const labelB = getLabelPeriodo(anoB, mesesB);

      dadosAtuais = { ...data, labelA, labelB, anoA, anoB, mesesA, mesesB, tipoAnalise };
      expandedNodes = new Set();
      sortCol = 'conta';
      sortAsc = true;

      // Dispatch rendering por tipo
      if (tipoAnalise === 'orcreal') {
        renderKPIsOrcReal(data.totais, labelA, labelB);
        renderTabelaOrcReal(data.dados, data.totais, labelA, labelB);
      } else if (tipoAnalise === 'variaveis') {
        renderKPIsVariaveis(dadosAtuais);
        renderTabelaVariaveis(dadosAtuais, labelA, labelB);
      } else if (tipoAnalise === 'indicadores') {
        renderKPIsIndicadores(dadosAtuais);
        renderTabelaIndicadores(dadosAtuais, labelA, labelB);
      } else {
        renderKPIs(data.totais, labelA, labelB);
        renderTabela(data.dados, data.totais, labelA, labelB);
      }

      document.getElementById('kpiContainer').style.display = '';
      document.getElementById('ordenacaoContainer').style.display = '';
      document.getElementById('tabelaContainer').style.display = '';
      document.getElementById('msgVazio').style.display = 'none';
      document.getElementById('btnExportCSV').disabled = false;
      document.getElementById('filtroConta').disabled = false;

    } catch (e) {
      alert('Erro de comunicação: ' + e.message);
    } finally {
      document.getElementById('btnComparar').disabled = false;
      document.getElementById('btnComparar').innerHTML = '<i class="bi bi-arrow-left-right"></i> Comparar';
    }
  }

  // ============================
  // FORMATAÇÃO
  // ============================
  function fmtNumCompleto(abs) {
    return abs.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
  }

  function fmtNumCompacto(abs) {
    const isInteiro = (MOEDA_FORMATO === 'inteiro');
    if (abs >= 1e9) return (abs / 1e9).toFixed(3).replace('.', ',') + (isInteiro ? 'MM' : 'B');
    if (abs >= 1e6) return (abs / 1e6).toFixed(3).replace('.', ',') + 'M';
    if (abs >= 1e3) return (abs / 1e3).toFixed(2).replace('.', ',') + 'K';
    return abs.toFixed(isInteiro ? 0 : 2).replace('.', ',');
  }

  function fmtNum(abs) {
    return exibicaoValor === 'compacta' ? fmtNumCompacto(abs) : fmtNumCompleto(abs);
  }

  function fmtValor(v) {
    const abs = Math.abs(v);
    const tipo = v >= 0 ? 'C' : 'D';
    return `${SIMBOLO} ${fmtNum(abs)} (${tipo})`;
  }

  function fmtValorComCor(v) {
    const texto = fmtValor(v);
    const cor = v >= 0 ? 'var(--bs-success, #10b981)' : 'var(--bs-danger, #ef4444)';
    return `<span style="color:${cor}">${texto}</span>`;
  }

  function fmtPct(v) {
    return v.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '%';
  }

  // nat='D' inverte sinal/cor para despesas: aumento = (+) vermelho, redução = (-) verde
  function varDisplay(v, nat) {
    return (nat === 'D') ? -v : v;
  }

  function fmtVariacao(v, nat) {
    const d = varDisplay(v, nat);
    const sinal = d > 0 ? '+' : '';
    const abs = Math.abs(d);
    return `${sinal}${SIMBOLO} ${fmtNum(abs)}`;
  }

  function fmtVariacaoPct(v, nat) {
    const d = varDisplay(v, nat);
    const sinal = d > 0 ? '+' : '';
    const icon = d > 0 ? '↑' : d < 0 ? '↓' : '';
    return `${sinal}${d.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}% ${icon}`;
  }

  function corVariacao(v, nat) {
    const d = varDisplay(v, nat);
    if (nat === 'D') {
      // Despesa: diminuição (-) = verde, aumento (+) = vermelho
      if (d > 0) return 'var(--bs-danger, #ef4444)';
      if (d < 0) return 'var(--bs-success, #10b981)';
    } else {
      if (d > 0) return 'var(--bs-success, #10b981)';
      if (d < 0) return 'var(--bs-danger, #ef4444)';
    }
    return 'var(--bs-secondary, #64748b)';
  }

  // ============================
  // KPIs
  // ============================
  function badgeResultado(v) {
    if (v >= 0) return ' <span class="badge bg-success" style="font-size:0.7rem; vertical-align:middle;">Lucro</span>';
    return ' <span class="badge bg-danger" style="font-size:0.7rem; vertical-align:middle;">Prejuízo</span>';
  }

  function renderKPIs(totais, labelA, labelB) {
    const container = document.getElementById('kpiContent');
    const kpiMargemA = calcMargemPct(totais.total_a, totais.rec_a || 0);
    const kpiMargemB = calcMargemPct(totais.total_b, totais.rec_b || 0);
    container.innerHTML = `
      <div class="row g-3">
        <div class="col-md-4">
          <div class="card border-0 shadow-sm"><div class="card-body py-3 text-center">
            <div class="small text-muted mb-1">${escHtml(labelA)}</div>
            <div class="fs-5 fw-bold">${fmtValorComCor(totais.total_a)}${badgeResultado(totais.total_a)}</div>
            <div class="text-muted fw-bold" style="font-size:1rem;">${fmtPct(kpiMargemA)} do faturamento</div>
          </div></div>
        </div>
        <div class="col-md-4">
          <div class="card border-0 shadow-sm"><div class="card-body py-3 text-center">
            <div class="small text-muted mb-1">${escHtml(labelB)}</div>
            <div class="fs-5 fw-bold">${fmtValorComCor(totais.total_b)}${badgeResultado(totais.total_b)}</div>
            <div class="text-muted fw-bold" style="font-size:1rem;">${fmtPct(kpiMargemB)} do faturamento</div>
          </div></div>
        </div>
        <div class="col-md-4">
          <div class="card border-0 shadow-sm"><div class="card-body py-3 text-center">
            <div class="small text-muted mb-1">Variação de Resultado <i class="bi bi-info-circle" style="font-size:0.75rem;cursor:help;opacity:0.6;" title="Resultado do realizado de ${escHtml(labelA)} menos ${escHtml(labelB)}"></i></div>
            <div class="fs-5 fw-bold">
              <span style="color:${corVariacao(totais.variacao_abs)}">${fmtVariacao(totais.variacao_abs)}</span>
              <span class="small" style="color:${corVariacao(totais.variacao_pct)}">${fmtVariacaoPct(totais.variacao_pct)}</span>
            </div>
          </div></div>
        </div>
      </div>
    `;
  }

  // ============================
  // TABELA
  // ============================
  function buildTree(dados) {
    const map = {};
    const roots = [];

    // Index por cdconta
    dados.forEach(d => { map[d.cdconta] = { ...d, children: [] }; });

    // Montar árvore
    dados.forEach(d => {
      const node = map[d.cdconta];
      if (d.cdcontapai && map[d.cdcontapai]) {
        map[d.cdcontapai].children.push(node);
      } else {
        roots.push(node);
      }
    });

    return { roots, map };
  }

  function flattenTree(nodes, level, filtro) {
    let result = [];
    for (const node of nodes) {
      const matchFiltro = !filtro ||
        node.cdconta.toLowerCase().includes(filtro) ||
        node.dsconta.toLowerCase().includes(filtro);

      const childrenFlat = node.children.length > 0
        ? flattenTree(node.children, level + 1, filtro)
        : [];

      // Mostrar se match ou se algum filho faz match
      if (matchFiltro || childrenFlat.length > 0) {
        const expanded = expandedNodes.has(node.cdconta);
        result.push({ ...node, level, hasChildren: node.children.length > 0, expanded });
        if (expanded || filtro) {
          result = result.concat(childrenFlat);
        }
      }
    }
    return result;
  }

  function sortDados(dados) {
    const sorted = [...dados];
    const dir = sortAsc ? 1 : -1;

    sorted.sort((a, b) => {
      switch (sortCol) {
        case 'conta':       return dir * a.cdconta.localeCompare(b.cdconta);
        case 'valor_a':     return dir * (a.valor_a - b.valor_a);
        case 'valor_b':     return dir * (a.valor_b - b.valor_b);
        case 'pct_a':       return dir * (a.pct_a - b.pct_a);
        case 'pct_b':       return dir * (a.pct_b - b.pct_b);
        case 'variacao_abs':return dir * (a.variacao_abs - b.variacao_abs);
        case 'variacao_pct':return dir * (a.variacao_pct - b.variacao_pct);
        default:            return 0;
      }
    });
    return sorted;
  }

  // Helper: soma meses selecionados de um objeto {mesref: valor}
  function sumMeses(mesesObj, months) {
    if (!mesesObj) return 0;
    return months.reduce((acc, m) => acc + (parseFloat(mesesObj[m]) || 0), 0);
  }

  // Avaliador de fórmula (Shunting-yard → RPN) respeitando parênteses
  // Equivalente JS de calcularFormulaDashboardInterno() do PHP
  const _rpnCache = {};
  function calcFormula(formula, valores) {
    if (!formula) return 0;
    const prec = {'+':1,'-':1,'*':2,'/':2};
    if (!_rpnCache[formula]) {
      const tokens = formula.match(/\d+|[\+\-\*\/\(\)]/g) || [];
      const output = [], ops = [];
      for (const t of tokens) {
        if (/^\d+$/.test(t)) { output.push(t); }
        else if (prec[t] !== undefined) {
          while (ops.length) {
            const top = ops[ops.length-1];
            if (top === '(' || (prec[top]||0) < prec[t]) break;
            output.push(ops.pop());
          }
          ops.push(t);
        } else if (t === '(') { ops.push(t); }
        else if (t === ')') {
          while (ops.length && ops[ops.length-1] !== '(') output.push(ops.pop());
          ops.pop();
        }
      }
      while (ops.length) output.push(ops.pop());
      _rpnCache[formula] = output;
    }
    const stack = [];
    for (const t of _rpnCache[formula]) {
      if (/^\d+$/.test(t)) { stack.push(valores[parseInt(t)] || 0); }
      else {
        const b = stack.pop() || 0, a = stack.pop() || 0;
        switch(t) {
          case '+': stack.push(a+b); break;
          case '-': stack.push(a-b); break;
          case '*': stack.push(a*b); break;
          case '/': stack.push(b===0 ? 0 : a/b); break;
        }
      }
    }
    return stack[0] || 0;
  }

  // Reagrupa contas brutas por grupo de meses, aplica fórmula, retorna resultado
  // (respeita ordem matemática: soma contas primeiro, depois calcula fórmula)
  function calcFormulaGrupo(formula, contasMeses, months, isPct) {
    if (!contasMeses || !formula) return 0;
    // Somar valor de cada conta no grupo de meses
    const map = {};
    for (const [cid, mesesObj] of Object.entries(contasMeses)) {
      map[parseInt(cid)] = months.reduce((s, m) => s + (parseFloat(mesesObj[m]) || 0), 0);
    }
    let val = calcFormula(formula, map);
    if (isPct) val *= 100;
    return val;
  }

  function calcVarPct(va, vb) {
    if (va !== 0) return ((vb - va) / Math.abs(va)) * 100;
    return vb !== 0 ? 100 : 0;
  }

  function calcMargemPct(resultado, receita) {
    return receita !== 0 ? (resultado / Math.abs(receita)) * 100 : 0;
  }

  // Retorna sub-períodos para detalhamento (trimestre → meses, ano → trimestres)
  function getColumnGroups() {
    if (!dadosAtuais) return [];
    const gran = document.querySelector('input[name="granularidade"]:checked').value;
    if (gran === 'mes') return [];
    if (gran === 'trimestre') {
      return dadosAtuais.mesesA.map(m => ({ label: MESES_NOME_CURTO[m], meses: [m] }));
    }
    // ano: trimestres
    return [
      { label: 'T1 (Jan-Mar)', meses: [1,2,3] },
      { label: 'T2 (Abr-Jun)', meses: [4,5,6] },
      { label: 'T3 (Jul-Set)', meses: [7,8,9] },
      { label: 'T4 (Out-Dez)', meses: [10,11,12] },
    ];
  }

  function renderTabela(dados, totais, labelA, labelB) {
    const filtro = document.getElementById('filtroConta').value.toLowerCase().trim();
    const sorted = sortDados(dados);
    const groups = getColumnGroups();
    const isDetalhado = groups.length > 0;

    // --- Flat rows ---
    let flat;
    if (viewMode === 'lista') {
      // Modo lista: apenas contas analíticas (fltipo='A'), flat, sem hierarquia
      flat = sorted.filter(row => {
        if (row.fltipo !== 'A') return false;
        if (!filtro) return true;
        return row.cdconta.toLowerCase().includes(filtro) || row.dsconta.toLowerCase().includes(filtro);
      }).map(row => ({ ...row, level: 0, hasChildren: false, expanded: false }));
    } else {
      const { roots } = buildTree(sorted);
      flat = flattenTree(roots, 0, filtro);
    }

    // --- Recalcular totais a partir dos itens filtrados ---
    let useTotais = totais;
    if (filtro) {
      // Somar apenas as contas analíticas presentes no flat
      const filteredLeafs = flat.filter(r => r.fltipo === 'A');
      let ft_a = 0, ft_b = 0, fr_a = 0, fr_b = 0;
      const ft_meses_a = {}, ft_meses_b = {}, fr_meses_a = {}, fr_meses_b = {};
      filteredLeafs.forEach(r => {
        ft_a += r.valor_a;
        ft_b += r.valor_b;
        if (r.meses_a) Object.entries(r.meses_a).forEach(([m, v]) => { ft_meses_a[m] = (ft_meses_a[m] || 0) + (parseFloat(v) || 0); });
        if (r.meses_b) Object.entries(r.meses_b).forEach(([m, v]) => { ft_meses_b[m] = (ft_meses_b[m] || 0) + (parseFloat(v) || 0); });
        if (r.flnatureza === 'C') {
          fr_a += r.valor_a;
          fr_b += r.valor_b;
          if (r.meses_a) Object.entries(r.meses_a).forEach(([m, v]) => { fr_meses_a[m] = (fr_meses_a[m] || 0) + (parseFloat(v) || 0); });
          if (r.meses_b) Object.entries(r.meses_b).forEach(([m, v]) => { fr_meses_b[m] = (fr_meses_b[m] || 0) + (parseFloat(v) || 0); });
        }
      });
      const ft_var_abs = ft_b - ft_a;
      const ft_var_pct = ft_a !== 0 ? ((ft_b - ft_a) / Math.abs(ft_a)) * 100 : (ft_b !== 0 ? 100 : 0);
      useTotais = {
        total_a: ft_a, total_b: ft_b,
        rec_a: fr_a, rec_b: fr_b,
        variacao_abs: ft_var_abs, variacao_pct: ft_var_pct,
        meses_a: ft_meses_a, meses_b: ft_meses_b,
        rec_meses_a: fr_meses_a, rec_meses_b: fr_meses_b
      };
    }

    // Atualizar KPIs com totais (filtrados ou originais)
    renderKPIs(useTotais, labelA, labelB);

    // --- Headers ---
    const thead = document.getElementById('tabelaHead');
    thead.innerHTML = '';

    if (isDetalhado) {
      // Duas linhas: grupo + detalhe
      const tr1 = document.createElement('tr');
      tr1.innerHTML = '<th rowspan="2" style="padding:10px 14px; min-width:250px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#f8f9fa; z-index:11;">Conta</th>';
      groups.forEach(g => {
        tr1.innerHTML += `<th colspan="3" class="text-center" style="padding:8px 4px; font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(g.label)}</th>`;
      });
      tr1.innerHTML += '<th colspan="3" class="text-center" style="padding:8px 4px; font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e9ecef;">Total</th>';
      thead.appendChild(tr1);

      const tr2 = document.createElement('tr');
      for (let i = 0; i <= groups.length; i++) {
        const isTotal = i === groups.length;
        const bl = isTotal ? 'border-left:2px solid #495057;' : 'border-left:2px solid #dee2e6;';
        const bgH = isTotal ? ' background:#e9ecef;' : '';
        tr2.innerHTML += `<th class="text-end" style="padding:6px 6px; min-width:110px; font-size:0.92rem; font-weight:600; ${bl}${bgH}">${escHtml(labelA)}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:6px 6px; min-width:110px; font-size:0.92rem; font-weight:600;${bgH}">${escHtml(labelB)}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:6px 6px; min-width:80px; font-size:0.92rem; font-weight:600;${bgH}">Δ%</th>`;
      }
      thead.appendChild(tr2);
    } else {
      // Cabeçalho simples (mês)
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <th style="padding:12px 14px; min-width:250px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="conta">Conta <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:130px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="valor_a">${escHtml(labelA)} <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:80px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="pct_a">% <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:130px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="valor_b">${escHtml(labelB)} <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:80px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="pct_b">% <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:130px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="variacao_abs">Variação (${SIMBOLO}) <i class="bi bi-chevron-expand text-muted"></i></th>
        <th class="text-end" style="padding:12px 10px; min-width:100px; font-size:1.05rem; font-weight:700; cursor:pointer;" data-col="variacao_pct">Variação (%) <i class="bi bi-chevron-expand text-muted"></i></th>
      `;
      thead.appendChild(tr);
      // Bind header click sorting (simples)
      tr.querySelectorAll('th[data-col]').forEach(th => {
        th.addEventListener('click', function() {
          const col = this.dataset.col;
          if (sortCol === col) { sortAsc = !sortAsc; } else { sortCol = col; sortAsc = col === 'conta'; }
          updateSortButtons();
          if (dadosAtuais) renderTabela(dadosAtuais.dados, dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
        });
      });
    }

    // --- Body ---
    const tbody = document.getElementById('tabelaBody');
    tbody.innerHTML = '';
    const colCount = isDetalhado ? 1 + (groups.length + 1) * 3 : 7;

    if (flat.length === 0) {
      tbody.innerHTML = `<tr><td colspan="${colCount}" class="text-center py-4 text-muted">Nenhuma conta encontrada.</td></tr>`;
      document.getElementById('tabelaFoot').innerHTML = '';
      return;
    }

    flat.forEach(row => {
      const tr = document.createElement('tr');
      const isSintetica = row.fltipo === 'S';
      const indent = row.level * 20;
      const fw = isSintetica ? 'fw-semibold' : '';
      const bg = isSintetica && row.level === 0 ? 'background:#f8fafc;' : '';

      const dscontaAttr = (row.dsconta || '').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
      const lupaHtml = `<span class="ms-1 text-primary detalhe-comp-btn" data-cdconta="${row.cdconta}" data-cdcontacontabil="${row.cdcontacontabil || ''}" data-dsconta="${dscontaAttr}" data-fltipo="${row.fltipo}" style="cursor:pointer;" title="Ver lançamentos"><i class="bi bi-search" style="font-size:0.8rem;"></i></span>`;

      let contaHtml = '';
      if (row.hasChildren) {
        const icon = row.expanded ? 'bi-dash-square' : 'bi-plus-square';
        contaHtml = `<span style="margin-left:${indent}px;"><a href="#" class="text-decoration-none toggle-conta" data-cdconta="${row.cdconta}"><i class="bi ${icon}"></i></a> <span class="${isSintetica ? 'fw-bold' : ''}">${escHtml(row.dsconta)} (${escHtml(row.cdconta)})</span>${lupaHtml}</span>`;
      } else {
        contaHtml = `<span style="margin-left:${indent + 20}px;" class="${isSintetica ? 'fw-bold' : ''}">${escHtml(row.dsconta)} (${escHtml(row.cdconta)})${lupaHtml}</span>`;
      }

      tr.style.cssText = bg;

      if (isDetalhado) {
        let cells = `<td style="padding:10px 14px; white-space:nowrap; position:sticky; left:0; background:${bg || '#fff'}; z-index:1;">${contaHtml}</td>`;
        const nat = row.flnatureza;
        groups.forEach(g => {
          const va = sumMeses(row.meses_a, g.meses);
          const vb = sumMeses(row.meses_b, g.meses);
          const vp = calcVarPct(va, vb);
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtValorComCor(va)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem;">${fmtValorComCor(vb)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; color:${corVariacao(vp, nat)}">${fmtVariacaoPct(vp, nat)}</td>`;
        });
        // Total
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #495057; background:#f0f4f8;">${fmtValorComCor(row.valor_a)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8;">${fmtValorComCor(row.valor_b)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8; color:${corVariacao(row.variacao_pct, nat)}">${fmtVariacaoPct(row.variacao_pct, nat)}</td>`;
        tr.innerHTML = cells;
      } else {
        tr.innerHTML = `
          <td style="padding:10px 14px;">${contaHtml}</td>
          <td class="text-end ${fw}" style="padding:10px;">${fmtValorComCor(row.valor_a)}</td>
          <td class="text-end text-muted" style="padding:10px; font-size:0.92rem;">${fmtPct(row.pct_a)}</td>
          <td class="text-end ${fw}" style="padding:10px;">${fmtValorComCor(row.valor_b)}</td>
          <td class="text-end text-muted" style="padding:10px; font-size:0.92rem;">${fmtPct(row.pct_b)}</td>
          <td class="text-end ${fw}" style="padding:10px; color:${corVariacao(row.variacao_abs, row.flnatureza)}">${fmtVariacao(row.variacao_abs, row.flnatureza)}</td>
          <td class="text-end ${fw}" style="padding:10px; color:${corVariacao(row.variacao_pct, row.flnatureza)}">${fmtVariacaoPct(row.variacao_pct, row.flnatureza)}</td>
        `;
      }
      tbody.appendChild(tr);
    });

    // --- Footer ---
    const tfoot = document.getElementById('tabelaFoot');
    const margemPctA = calcMargemPct(useTotais.total_a, useTotais.rec_a || 0);
    const margemPctB = calcMargemPct(useTotais.total_b, useTotais.rec_b || 0);
    if (isDetalhado) {
      let cells = '<td style="padding:12px 14px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#e2e6ea; z-index:1;">RESULTADO</td>';
      groups.forEach(g => {
        const va = sumMeses(useTotais.meses_a, g.meses);
        const vb = sumMeses(useTotais.meses_b, g.meses);
        const recA = sumMeses(useTotais.rec_meses_a, g.meses);
        const recB = sumMeses(useTotais.rec_meses_b, g.meses);
        const mgA = calcMargemPct(va, recA);
        const mgB = calcMargemPct(vb, recB);
        const vp = calcVarPct(va, vb);
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #dee2e6; background:#e2e6ea;">${fmtValorComCor(va)} <small class="text-muted">${fmtPct(mgA)}</small></td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea;">${fmtValorComCor(vb)} <small class="text-muted">${fmtPct(mgB)}</small></td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea; color:${corVariacao(vp)}">${fmtVariacaoPct(vp)}</td>`;
      });
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #495057; background:#d5dae0;">${fmtValorComCor(useTotais.total_a)} <small class="text-muted">${fmtPct(margemPctA)}</small></td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0;">${fmtValorComCor(useTotais.total_b)} <small class="text-muted">${fmtPct(margemPctB)}</small></td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0; color:${corVariacao(useTotais.variacao_pct)}">${fmtVariacaoPct(useTotais.variacao_pct)}</td>`;
      tfoot.innerHTML = `<tr>${cells}</tr>`;
    } else {
      tfoot.innerHTML = `
        <tr>
          <td style="padding:12px 14px; font-size:1.05rem; font-weight:700;">RESULTADO</td>
          <td class="text-end" style="padding:12px 10px; font-size:1rem; font-weight:600;">${fmtValorComCor(useTotais.total_a)}</td>
          <td class="text-end text-muted" style="padding:12px 10px; font-size:0.92rem;">${fmtPct(margemPctA)}</td>
          <td class="text-end" style="padding:12px 10px; font-size:1rem; font-weight:600;">${fmtValorComCor(useTotais.total_b)}</td>
          <td class="text-end text-muted" style="padding:12px 10px; font-size:0.92rem;">${fmtPct(margemPctB)}</td>
          <td class="text-end" style="padding:12px 10px; font-size:1rem; font-weight:600; color:${corVariacao(useTotais.variacao_abs)}">${fmtVariacao(useTotais.variacao_abs)}</td>
          <td class="text-end" style="padding:12px 10px; font-size:1rem; font-weight:600; color:${corVariacao(useTotais.variacao_pct)}">${fmtVariacaoPct(useTotais.variacao_pct)}</td>
        </tr>
      `;
    }

    // Bind toggle
    tbody.querySelectorAll('.toggle-conta').forEach(a => {
      a.addEventListener('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
        const cd = this.dataset.cdconta;
        if (expandedNodes.has(cd)) expandedNodes.delete(cd);
        else expandedNodes.add(cd);
        renderTabela(dadosAtuais.dados, dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
      });
    });

    // Bind detalhe (lupa)
    tbody.querySelectorAll('.detalhe-comp-btn').forEach(btn => {
      btn.addEventListener('click', function(e) {
        e.preventDefault();
        e.stopPropagation();
        abrirDetalheComp(
          this.dataset.cdconta,
          this.dataset.cdcontacontabil,
          this.dataset.dsconta,
          this.dataset.fltipo === 'S'
        );
      });
    });
  }

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

  // Botões de ordenação rápida
  document.querySelectorAll('[data-sort]').forEach(btn => {
    btn.addEventListener('click', function() {
      const tipo = this.dataset.sort;
      if (tipo === 'conta')       { sortCol = 'conta'; sortAsc = true; }
      else if (tipo === 'melhor') { sortCol = 'variacao_pct'; sortAsc = false; }
      else if (tipo === 'pior')   { sortCol = 'variacao_pct'; sortAsc = true; }
      else if (tipo === 'maior-valor') { sortCol = 'valor_a'; sortAsc = false; }

      // Auto-switch para lista ao ordenar por desempenho/valor
      if (tipo !== 'conta' && viewMode === 'arvore') {
        viewMode = 'lista';
        document.getElementById('viewLista').checked = true;
      }

      updateSortButtons();
      if (dadosAtuais) reRenderAtual();
    });
  });

  // Toggle de modo de visualização (Árvore / Lista)
  document.querySelectorAll('input[name="viewMode"]').forEach(radio => {
    radio.addEventListener('change', function() {
      viewMode = this.value;
      if (dadosAtuais) reRenderAtual();
    });
  });

  function updateSortButtons() {
    document.querySelectorAll('[data-sort]').forEach(b => b.classList.remove('active'));
    const active = {
      'conta': 'conta',
      'variacao_pct': sortAsc ? 'pior' : 'melhor',
      'valor_a': 'maior-valor',
    }[sortCol];
    if (active) {
      const btn = document.querySelector(`[data-sort="${active}"]`);
      if (btn) btn.classList.add('active');
    }
  }

  let viewModeBeforeSearch = 'arvore'; // guarda modo antes da pesquisa

  // ============================
  // FILTRO DE CONTA (tempo real)
  // ============================
  let filtroTimeout;
  document.getElementById('filtroConta').addEventListener('input', function() {
    clearTimeout(filtroTimeout);
    const val = this.value.trim();
    filtroTimeout = setTimeout(() => {
      if (!dadosAtuais) return;
      if (val.length > 0 && viewMode === 'arvore') {
        viewModeBeforeSearch = 'arvore';
        viewMode = 'lista';
        document.getElementById('viewLista').checked = true;
      } else if (val.length === 0 && viewModeBeforeSearch === 'arvore') {
        viewMode = 'arvore';
        document.getElementById('viewArvore').checked = true;
      }
      reRenderAtual();
    }, 300);
  });

  // ============================
  // DESVIO DIRECTION (Orç x Real)
  // ============================
  document.getElementById('filtroDesvioDir').addEventListener('change', function() {
    if (dadosAtuais && (dadosAtuais.tipoAnalise || 'realizado') === 'orcreal') reRenderAtual();
  });

  // ============================
  // FILTRO GRUPO INDICADOR
  // ============================
  document.getElementById('filtroGrupoIndicador').addEventListener('change', function() {
    const grp = this.value;
    const selInd = document.getElementById('filtroIndicador');
    // Show/hide options based on grupo
    Array.from(selInd.options).forEach(opt => {
      if (!opt.value) { opt.style.display = ''; return; } // "Todos"
      const optGrp = opt.getAttribute('data-cdgrupo') || '0';
      opt.style.display = (!grp || optGrp === grp) ? '' : 'none';
    });
    // Reset indicator selection if current is hidden
    if (selInd.selectedOptions[0] && selInd.selectedOptions[0].style.display === 'none') {
      selInd.value = '';
    }
  });

  // ============================
  // EXPORT CSV
  // ============================
  document.getElementById('btnExportCSV').addEventListener('click', function() {
    if (!dadosAtuais) return;

    const params = new URLSearchParams();
    params.set('m', 'comparativo_realizado_actions');
    params.set('ajax', 'export_comparativo_csv');
    params.set('ano_a', dadosAtuais.anoA);
    params.set('ano_b', dadosAtuais.anoB);
    dadosAtuais.mesesA.forEach(m => params.append('meses_a[]', m));
    dadosAtuais.mesesB.forEach(m => params.append('meses_b[]', m));
    params.set('label_a', dadosAtuais.labelA);
    params.set('label_b', dadosAtuais.labelB);

    const cc = document.getElementById('filtroCentro').value;
    if (cc) params.set('cdcentrocusto', cc);

    const tpmov = document.getElementById('filtroTpMov').value;
    if (tpmov) params.set('tpmovimento', tpmov);

    window.location.href = '?' + params.toString();
  });

  // ============================
  // DETALHE DE LANÇAMENTOS (drill-down)
  // ============================
  function getModalDetalheComp() {
    if (!modalDetalheComp) {
      modalDetalheComp = new bootstrap.Modal(document.getElementById('modalDetalheComp'));
    }
    return modalDetalheComp;
  }

  document.getElementById('btnFiltrarDetalheComp').addEventListener('click', () => carregarDetalheComp());

  function abrirDetalheComp(cdconta, cdcontacontabil, dsconta, ehSintetica) {
    if (!dadosAtuais) return;
    detalheCompAtual = { cdconta, cdcontacontabil, dsconta, ehSintetica };

    // Período default: apenas período B da granularidade selecionada
    const anoB = parseInt(dadosAtuais.anoB);
    const mesesB = dadosAtuais.mesesB.sort((a,b) => a-b);
    const minMesB = mesesB[0];
    const maxMesB = mesesB[mesesB.length - 1];

    const dtIni = `${anoB}-${String(minMesB).padStart(2,'0')}-01`;
    const lastDay = new Date(anoB, maxMesB, 0).getDate();
    const dtFim = `${anoB}-${String(maxMesB).padStart(2,'0')}-${String(lastDay).padStart(2,'0')}`;

    document.getElementById('detalheCompDataIni').value = dtIni;
    document.getElementById('detalheCompDataFim').value = dtFim;
    document.getElementById('detalheCompContaInfo').innerHTML =
      `<strong>Conta:</strong> ${escHtml(cdconta)} - ${escHtml(dsconta)}`;
    document.getElementById('tbDetalheComp').innerHTML =
      '<tr><td colspan="5" class="text-center py-3 text-muted">Carregando...</td></tr>';
    document.getElementById('detalheCompTotalValor').textContent = '0,00';
    document.getElementById('detalheCompTotaisResumo').innerHTML = '';

    getModalDetalheComp().show();
    carregarDetalheComp();
  }

  async function carregarDetalheComp() {
    if (!detalheCompAtual) return;
    const { cdconta, cdcontacontabil, ehSintetica } = detalheCompAtual;
    const dtIni = document.getElementById('detalheCompDataIni').value;
    const dtFim = document.getElementById('detalheCompDataFim').value;

    const params = new URLSearchParams();
    params.set('m', 'comparativo_realizado_actions');
    params.set('ajax', 'detalhe_lancamentos');
    params.set('cdconta', cdconta);
    if (cdcontacontabil && !ehSintetica) params.set('cdcontacontabil', cdcontacontabil);
    if (dtIni) params.set('dtinicio', dtIni);
    if (dtFim) params.set('dtfim', dtFim);

    const cc = document.getElementById('filtroCentro').value;
    if (cc) params.set('cdcentrocusto', cc);
    const tpmov = document.getElementById('filtroTpMov').value;
    if (tpmov) params.set('tpmovimento', tpmov);

    try {
      const resp = await fetch('?' + params.toString());
      const data = await resp.json();
      if (!data.ok) {
        document.getElementById('tbDetalheComp').innerHTML =
          `<tr><td colspan="5" class="text-center py-3 text-danger">${escHtml(data.msg || 'Erro')}</td></tr>`;
        return;
      }
      renderDetalheComp(data.lancamentos, ehSintetica, data.truncado);
    } catch (e) {
      document.getElementById('tbDetalheComp').innerHTML =
        `<tr><td colspan="5" class="text-center py-3 text-danger">Erro de comunicação: ${escHtml(e.message)}</td></tr>`;
    }
  }

  function renderDetalheComp(lancamentos, ehSintetica, truncado) {
    const tbody = document.getElementById('tbDetalheComp');
    tbody.innerHTML = '';

    if (truncado) {
      const trW = document.createElement('tr');
      trW.innerHTML = '<td colspan="5" class="text-center py-2 text-warning small" style="background:#fff3cd;"><i class="bi bi-exclamation-triangle me-1"></i>Exibindo os primeiros 5.000 lançamentos. Use o filtro de datas para refinar.</td>';
      tbody.appendChild(trW);
    }

    if (!lancamentos || lancamentos.length === 0) {
      tbody.innerHTML = '<tr><td colspan="5" class="text-center py-3 text-muted">Nenhum lançamento encontrado no período.</td></tr>';
      document.getElementById('detalheCompTotalValor').textContent = '0,00';
      document.getElementById('detalheCompTotaisResumo').innerHTML = '';
      return;
    }

    let totalDeb = 0, totalCred = 0;

    if (ehSintetica) {
      // Agrupar por conta filha (padrão realizado)
      const contasMap = {};
      lancamentos.forEach(l => {
        const chave = l.cdplanocontabil || l.cdconta || 'sem_conta';
        if (!contasMap[chave]) {
          contasMap[chave] = {
            cdplanocontabil: l.cdplanocontabil,
            cdconta: l.cdconta,
            dsconta: l.dsconta,
            lancamentos: [],
            totalDeb: 0,
            totalCred: 0
          };
        }
        contasMap[chave].lancamentos.push(l);
        const valor = Number(l.valor || 0);
        if (l.tpmovimento === 'C') {
          contasMap[chave].totalCred += valor;
          totalCred += valor;
        } else if (l.tpmovimento === 'D') {
          contasMap[chave].totalDeb += valor;
          totalDeb += valor;
        }
      });

      const contas = Object.values(contasMap).sort((a, b) => {
        return (a.cdconta || '').localeCompare(b.cdconta || '');
      });

      contas.forEach((conta, idx) => {
        const saldoConta = conta.totalCred - conta.totalDeb;
        const absSaldoConta = Math.abs(saldoConta);
        const naturezaConta = saldoConta === 0 ? '' : (saldoConta > 0 ? ' (C)' : ' (D)');
        const idConta = 'comp_conta_' + (conta.cdplanocontabil || idx);

        // Cabeçalho da conta filha (colapsado por padrão)
        const trCab = document.createElement('tr');
        trCab.style.cssText = 'background: #f8f9fa; font-weight: 600; border-left: 3px solid #6c757d; cursor: pointer;';
        trCab.classList.add('grupo-header');
        trCab.innerHTML = `
          <td colspan="5" style="padding: 12px 16px;">
            <i class="bi bi-plus-square me-2 icone-expandir" style="color: #6c757d;"></i>
            <strong style="color: #212529;">${escHtml(conta.cdconta)}</strong>
            <span style="color: #6c757d;">- ${escHtml(conta.dsconta || '')}</span>
            <span class="float-end">
              <small class="text-muted me-3">D: ${SIMBOLO} ${fmtValorSimples(conta.totalDeb)} | C: ${SIMBOLO} ${fmtValorSimples(conta.totalCred)}</small>
              <span class="${saldoConta > 0 ? 'badge bg-success' : (saldoConta < 0 ? 'badge bg-danger' : 'badge bg-secondary')}">
                ${SIMBOLO} ${fmtValorSimples(absSaldoConta)}${naturezaConta}
              </span>
            </span>
          </td>`;
        trCab.addEventListener('click', function() {
          const icone = this.querySelector('.icone-expandir');
          const expandido = icone.classList.contains('bi-dash-square');
          if (expandido) {
            icone.classList.replace('bi-dash-square', 'bi-plus-square');
            document.querySelectorAll('.' + idConta).forEach(r => r.style.display = 'none');
          } else {
            icone.classList.replace('bi-plus-square', 'bi-dash-square');
            document.querySelectorAll('.' + idConta).forEach(r => r.style.display = '');
          }
        });
        tbody.appendChild(trCab);

        // Lançamentos individuais (ocultos por padrão)
        conta.lancamentos.sort((a, b) => (a.dtmovimento || '').localeCompare(b.dtmovimento || ''));
        conta.lancamentos.forEach(l => {
          const valor = Number(l.valor || 0);
          const classeValor = l.tpmovimento === 'D' ? 'text-danger' : 'text-success';
          const tr = document.createElement('tr');
          tr.className = idConta;
          tr.style.cssText = 'background: #ffffff; display: none; border-bottom: 1px solid #f0f0f0;';
          tr.innerHTML = `
            <td style="padding-left: 40px; color: #6c757d; font-size: 0.9rem;">
              <i class="bi bi-arrow-return-right me-1" style="font-size: 0.75rem; color: #adb5bd;"></i>
              ${escHtml(conta.cdconta)}
            </td>
            <td style="font-size: 0.9rem; color: #495057;">${fmtData(l.dtmovimento)}</td>
            <td style="font-size: 0.9rem; color: #495057;">${escHtml(l.dscomplemento || '')}</td>
            <td class="text-center" style="font-size: 0.9rem;">
              <span class="badge ${l.tpmovimento === 'D' ? 'bg-danger' : 'bg-success'} badge-sm">${l.tpmovimento}</span>
            </td>
            <td class="text-end ${classeValor}" style="font-size: 0.9rem; font-weight: 500;">${fmtValorSimples(valor)}</td>
          `;
          tbody.appendChild(tr);
        });

        // Subtotal da conta (oculto por padrão)
        const trSub = document.createElement('tr');
        trSub.className = idConta;
        trSub.style.cssText = 'background: #f8f9fa; font-weight: 600; border-bottom: 1px solid #dee2e6; border-top: 1px solid #dee2e6; display: none;';
        trSub.innerHTML = `
          <td colspan="4" class="text-end" style="padding: 8px 16px; font-size: 0.9rem; color: #495057;">
            <i class="bi bi-calculator me-1"></i> Subtotal ${escHtml(conta.dsconta || conta.cdconta)}
          </td>
          <td class="text-end ${saldoConta > 0 ? 'text-success' : (saldoConta < 0 ? 'text-danger' : 'text-muted')}" style="padding: 8px 16px; font-size: 0.95rem; font-weight: 600;">
            ${SIMBOLO} ${fmtValorSimples(absSaldoConta)}${naturezaConta}
          </td>`;
        tbody.appendChild(trSub);

        // Espaçamento entre grupos
        if (idx < contas.length - 1) {
          const trSpace = document.createElement('tr');
          trSpace.style.cssText = 'height: 16px; background: #fff;';
          trSpace.innerHTML = '<td colspan="5"></td>';
          tbody.appendChild(trSpace);
        }
      });

    } else {
      // Flat (conta analítica)
      lancamentos.forEach(l => {
        const valor = Number(l.valor || 0);
        if (l.tpmovimento === 'C') totalCred += valor;
        else if (l.tpmovimento === 'D') totalDeb += valor;

        const contaInfo = l.dsconta ? `${escHtml(l.cdconta)} - ${escHtml(l.dsconta)}` : escHtml(l.cdconta || '');
        const tr = document.createElement('tr');
        tr.innerHTML = `
          <td>${contaInfo}</td>
          <td>${fmtData(l.dtmovimento)}</td>
          <td>${escHtml(l.dscomplemento || '')}</td>
          <td class="text-center"><span class="badge ${l.tpmovimento === 'D' ? 'bg-danger' : 'bg-success'}">${l.tpmovimento === 'D' ? 'D' : (l.tpmovimento === 'C' ? 'C' : '')}</span></td>
          <td class="text-end">${fmtValorSimples(valor)}</td>
        `;
        tbody.appendChild(tr);
      });
    }

    const saldo = totalCred - totalDeb;
    const absSaldo = Math.abs(saldo);
    const natureza = saldo === 0 ? '' : (saldo > 0 ? ' (C)' : ' (D)');
    document.getElementById('detalheCompTotalValor').innerHTML =
      `<span style="color:${saldo >= 0 ? 'var(--bs-success)' : 'var(--bs-danger)'}">${SIMBOLO} ${fmtValorSimples(absSaldo)}${natureza}</span>`;
    document.getElementById('detalheCompTotaisResumo').innerHTML =
      `<strong>Débito:</strong> ${SIMBOLO} ${fmtValorSimples(totalDeb)} (D) &nbsp;|&nbsp; ` +
      `<strong>Crédito:</strong> ${SIMBOLO} ${fmtValorSimples(totalCred)} (C) &nbsp;|&nbsp; ` +
      `<strong>Saldo (Crédito − Débito):</strong> ${SIMBOLO} ${fmtValorSimples(absSaldo)}${natureza}`;
  }

  function fmtData(dt) {
    if (!dt) return '-';
    const parts = dt.split('-');
    if (parts.length === 3) return `${parts[2]}/${parts[1]}/${parts[0]}`;
    return dt;
  }

  function fmtValorSimples(v) {
    return fmtNum(Math.abs(v));
  }

  // ============================
  // RE-RENDER DISPATCH
  // ============================
  function reRenderAtual() {
    if (!dadosAtuais) return;
    const tipo = dadosAtuais.tipoAnalise || 'realizado';
    if (tipo === 'orcreal') {
      renderKPIsOrcReal(dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
      renderTabelaOrcReal(dadosAtuais.dados, dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
    } else if (tipo === 'variaveis') {
      renderKPIsVariaveis(dadosAtuais);
      renderTabelaVariaveis(dadosAtuais, dadosAtuais.labelA, dadosAtuais.labelB);
    } else if (tipo === 'indicadores') {
      renderKPIsIndicadores(dadosAtuais);
      renderTabelaIndicadores(dadosAtuais, dadosAtuais.labelA, dadosAtuais.labelB);
    } else {
      renderKPIs(dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
      renderTabela(dadosAtuais.dados, dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
    }
  }

  // ============================
  // ORÇADO x REALIZADO — KPIs
  // ============================
  function renderKPIsOrcReal(totais, labelA, labelB) {
    const container = document.getElementById('kpiContent');
    const desvioDir = document.getElementById('filtroDesvioDir').value;
    const dLabel = desvioDir === 'real-orc' ? 'R−O' : 'O−R';

    // Calcular totais por natureza (Receita C / Despesa D) a partir das contas raiz
    const dados = dadosAtuais?.dados || [];
    let recOrcA = 0, recRealA = 0, recOrcB = 0, recRealB = 0;
    let despOrcA = 0, despRealA = 0, despOrcB = 0, despRealB = 0;
    dados.filter(r => !r.cdcontapai).forEach(r => {
      if (r.flnatureza === 'C') {
        recOrcA += r.orc_a || 0; recRealA += r.real_a || 0;
        recOrcB += r.orc_b || 0; recRealB += r.real_b || 0;
      } else {
        despOrcA += Math.abs(r.orc_a || 0); despRealA += Math.abs(r.real_a || 0);
        despOrcB += Math.abs(r.orc_b || 0); despRealB += Math.abs(r.real_b || 0);
      }
    });

    function devCalc(orc, real) {
      const dev = desvioDir === 'real-orc' ? real - orc : orc - real;
      const pct = orc !== 0 ? (dev / Math.abs(orc)) * 100 : (dev !== 0 ? 100 : 0);
      return { dev, pct };
    }
    function devHtml(d) {
      const cor = d.dev >= 0 ? 'var(--bs-success)' : 'var(--bs-danger)';
      return `<span style="color:${cor}">${fmtVariacao(d.dev)} ${fmtVariacaoPct(d.pct)}</span>`;
    }
    function varCalc(a, b) {
      const abs = b - a;
      const pct = a !== 0 ? ((b - a) / Math.abs(a)) * 100 : (b !== 0 ? 100 : 0);
      return { abs, pct };
    }
    function varHtml(v) {
      return `<span style="color:${corVariacao(v.abs)}">${fmtVariacao(v.abs)} ${fmtVariacaoPct(v.pct)}</span>`;
    }

    const drA = devCalc(recOrcA, recRealA);
    const drB = devCalc(recOrcB, recRealB);
    const ddA = devCalc(despOrcA, despRealA);
    const ddB = devCalc(despOrcB, despRealB);

    // Variações por natureza
    const vOrcRec  = varCalc(recOrcA, recOrcB);
    const vOrcDesp = varCalc(despOrcA, despOrcB);
    const vRealRec  = varCalc(recRealA, recRealB);
    const vRealDesp = varCalc(despRealA, despRealB);

    // Resultado (net)
    const resOrcA = recOrcA - despOrcA;
    const resOrcB = recOrcB - despOrcB;
    const resA = recRealA - despRealA;
    const resB = recRealB - despRealB;
    const vOrcRes  = varCalc(resOrcA, resOrcB);
    const vRealRes = varCalc(resA, resB);

    const tblStyle = 'font-size:1.15rem; white-space:nowrap; border-collapse:collapse;';

    container.innerHTML = `
      <div class="d-flex gap-2 flex-nowrap align-items-stretch" style="overflow-x:auto;">
        <div style="flex:1 1 0; min-width:0;">
          <div class="card border-0 shadow-sm h-100"><div class="card-body py-2 px-2" style="overflow:hidden;">
            <div class="text-muted mb-2 text-center" style="font-size:1.2rem; font-weight:700;">${escHtml(labelA)}</div>
            <table style="${tblStyle}">
              <tr><td></td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 4px;">Orçado</td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 4px;">Realizado</td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 2px;">${dLabel}</td></tr>
              <tr><td class="fw-bold" style="padding:3px 4px 3px 0;">Receita</td><td class="text-end" style="padding:3px 4px;">${fmtValor(recOrcA)}</td><td class="text-end" style="padding:3px 4px;">${fmtValor(recRealA)}</td><td class="text-end" style="padding:3px 2px;">${devHtml(drA)}</td></tr>
              <tr><td class="fw-bold" style="padding:3px 4px 3px 0;">Despesa</td><td class="text-end" style="padding:3px 4px;">${fmtValor(despOrcA)}</td><td class="text-end" style="padding:3px 4px;">${fmtValor(despRealA)}</td><td class="text-end" style="padding:3px 2px;">${devHtml(ddA)}</td></tr>
            </table>
            <div class="mt-2 pt-2 border-top text-center" style="font-size:1.2rem;"><strong>Resultado:</strong> ${fmtValorComCor(resA)} ${badgeResultado(resA)}</div>
          </div></div>
        </div>
        <div style="flex:1 1 0; min-width:0;">
          <div class="card border-0 shadow-sm h-100"><div class="card-body py-2 px-2" style="overflow:hidden;">
            <div class="text-muted mb-2 text-center" style="font-size:1.2rem; font-weight:700;">${escHtml(labelB)}</div>
            <table style="${tblStyle}">
              <tr><td></td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 4px;">Orçado</td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 4px;">Realizado</td><td class="text-end fw-bold" style="color:#6c757d; font-size:1.05rem; padding:2px 2px;">${dLabel}</td></tr>
              <tr><td class="fw-bold" style="padding:3px 4px 3px 0;">Receita</td><td class="text-end" style="padding:3px 4px;">${fmtValor(recOrcB)}</td><td class="text-end" style="padding:3px 4px;">${fmtValor(recRealB)}</td><td class="text-end" style="padding:3px 2px;">${devHtml(drB)}</td></tr>
              <tr><td class="fw-bold" style="padding:3px 4px 3px 0;">Despesa</td><td class="text-end" style="padding:3px 4px;">${fmtValor(despOrcB)}</td><td class="text-end" style="padding:3px 4px;">${fmtValor(despRealB)}</td><td class="text-end" style="padding:3px 2px;">${devHtml(ddB)}</td></tr>
            </table>
            <div class="mt-2 pt-2 border-top text-center" style="font-size:1.2rem;"><strong>Resultado:</strong> ${fmtValorComCor(resB)} ${badgeResultado(resB)}</div>
          </div></div>
        </div>
        <div style="flex:0 0 auto;">
          <div class="card border-0 shadow-sm h-100"><div class="card-body py-2 px-3 d-flex flex-column justify-content-center" style="white-space:nowrap;">
            <div class="text-muted mb-2 text-center" style="font-size:1.3rem; font-weight:700;">Var. Orçado <i class="bi bi-info-circle" style="font-size:0.85rem;cursor:help;opacity:0.6;" title="Valor orçado de ${escHtml(labelA)} menos ${escHtml(labelB)}"></i></div>
            <div style="font-size:1.25rem;" class="mb-1"><strong>Rec:</strong> ${varHtml(vOrcRec)}</div>
            <div style="font-size:1.25rem;" class="mb-1"><strong>Desp:</strong> <span style="color:${corVariacao(-vOrcDesp.abs)}">${fmtVariacao(vOrcDesp.abs)} ${fmtVariacaoPct(vOrcDesp.pct)}</span></div>
            <div class="mt-auto pt-2 border-top" style="font-size:1.3rem;"><strong>Res:</strong> ${varHtml(vOrcRes)}</div>
          </div></div>
        </div>
        <div style="flex:0 0 auto;">
          <div class="card border-0 shadow-sm h-100"><div class="card-body py-2 px-3 d-flex flex-column justify-content-center" style="white-space:nowrap;">
            <div class="text-muted mb-2 text-center" style="font-size:1.3rem; font-weight:700;">Var. Realizado <i class="bi bi-info-circle" style="font-size:0.85rem;cursor:help;opacity:0.6;" title="Valor realizado de ${escHtml(labelA)} menos ${escHtml(labelB)}"></i></div>
            <div style="font-size:1.25rem;" class="mb-1"><strong>Rec:</strong> ${varHtml(vRealRec)}</div>
            <div style="font-size:1.25rem;" class="mb-1"><strong>Desp:</strong> <span style="color:${corVariacao(-vRealDesp.abs)}">${fmtVariacao(vRealDesp.abs)} ${fmtVariacaoPct(vRealDesp.pct)}</span></div>
            <div class="mt-auto pt-2 border-top" style="font-size:1.3rem;"><strong>Res:</strong> ${varHtml(vRealRes)}</div>
          </div></div>
        </div>
      </div>
    `;
  }

  // ============================
  // ORÇADO x REALIZADO — TABELA
  // ============================
  function renderTabelaOrcReal(dados, totais, labelA, labelB) {
    const filtro = document.getElementById('filtroConta').value.toLowerCase().trim();
    const sorted = sortDados(dados);
    const desvioDir = document.getElementById('filtroDesvioDir').value;
    const dLabel = desvioDir === 'real-orc' ? 'R−O' : 'O−R';
    const groups = getColumnGroups();
    const isDetalhado = groups.length > 0;

    let flat;
    if (viewMode === 'lista') {
      flat = sorted.filter(row => {
        if (row.fltipo !== 'A') return false;
        if (!filtro) return true;
        return row.cdconta.toLowerCase().includes(filtro) || row.dsconta.toLowerCase().includes(filtro);
      }).map(row => ({ ...row, level: 0, hasChildren: false, expanded: false }));
    } else {
      const { roots } = buildTree(sorted);
      flat = flattenTree(roots, 0, filtro);
    }

    // Recalcular totais se filtrado
    let useTotais = totais;
    if (filtro) {
      const leaves = flat.filter(r => r.fltipo === 'A');
      let oa = 0, ra = 0, ob = 0, rb = 0;
      const ftOrcMesA = {}, ftRealMesA = {}, ftOrcMesB = {}, ftRealMesB = {};
      leaves.forEach(r => {
        oa += r.orc_a || 0; ra += r.real_a || 0; ob += r.orc_b || 0; rb += r.real_b || 0;
        if (r.orc_meses_a) Object.entries(r.orc_meses_a).forEach(([m, v]) => { ftOrcMesA[m] = (ftOrcMesA[m] || 0) + (parseFloat(v) || 0); });
        if (r.real_meses_a) Object.entries(r.real_meses_a).forEach(([m, v]) => { ftRealMesA[m] = (ftRealMesA[m] || 0) + (parseFloat(v) || 0); });
        if (r.orc_meses_b) Object.entries(r.orc_meses_b).forEach(([m, v]) => { ftOrcMesB[m] = (ftOrcMesB[m] || 0) + (parseFloat(v) || 0); });
        if (r.real_meses_b) Object.entries(r.real_meses_b).forEach(([m, v]) => { ftRealMesB[m] = (ftRealMesB[m] || 0) + (parseFloat(v) || 0); });
      });
      useTotais = { orc_a: oa, real_a: ra, orc_b: ob, real_b: rb,
        orc_meses_a: ftOrcMesA, real_meses_a: ftRealMesA,
        orc_meses_b: ftOrcMesB, real_meses_b: ftRealMesB,
        var_orc_abs: ob - oa, var_orc_pct: oa !== 0 ? ((ob - oa) / Math.abs(oa)) * 100 : 0,
        var_real_abs: rb - ra, var_real_pct: ra !== 0 ? ((rb - ra) / Math.abs(ra)) * 100 : 0
      };
    }
    renderKPIsOrcReal(useTotais, labelA, labelB);

    const thead = document.getElementById('tabelaHead');
    thead.innerHTML = '';

    // Helper desvio
    function calcDev(orc, real) {
      const dev = desvioDir === 'real-orc' ? real - orc : orc - real;
      const pct = orc !== 0 ? (dev / Math.abs(orc)) * 100 : (dev !== 0 ? 100 : 0);
      return { dev, pct };
    }

    if (isDetalhado) {
      // 3-row header: month groups → period labels → metric headers
      const tr1 = document.createElement('tr');
      tr1.innerHTML = '<th rowspan="3" style="padding:10px 14px; min-width:250px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#f8f9fa; z-index:11;">Conta</th>';
      groups.forEach(g => {
        tr1.innerHTML += `<th colspan="6" class="text-center" style="padding:8px 4px; font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(g.label)}</th>`;
      });
      tr1.innerHTML += `<th colspan="6" class="text-center" style="padding:8px 4px; font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e9ecef;">Total</th>`;
      tr1.innerHTML += `<th colspan="3" rowspan="2" class="text-center" style="padding:8px 4px; font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e2e6ea;">Var. Período</th>`;
      thead.appendChild(tr1);

      // Row 2: period labels (labelA / labelB)
      const tr2 = document.createElement('tr');
      for (let i = 0; i <= groups.length; i++) {
        const isTotal = i === groups.length;
        const bl = isTotal ? 'border-left:2px solid #495057;' : 'border-left:2px solid #dee2e6;';
        const bgH = isTotal ? ' background:#e9ecef;' : '';
        tr2.innerHTML += `<th colspan="3" class="text-center" style="padding:4px 4px; font-size:0.85rem; font-weight:600; ${bl}${bgH}">${escHtml(labelA)}</th>`;
        tr2.innerHTML += `<th colspan="3" class="text-center" style="padding:4px 4px; font-size:0.85rem; font-weight:600; border-left:1px solid #adb5bd;${bgH}">${escHtml(labelB)}</th>`;
      }
      // Var covered by rowspan
      thead.appendChild(tr2);

      // Row 3: metric sub-headers (Orç | Real | Dev%) × 2 per group + Var labels
      const tr3 = document.createElement('tr');
      for (let i = 0; i <= groups.length; i++) {
        const isTotal = i === groups.length;
        const bl = isTotal ? 'border-left:2px solid #495057;' : 'border-left:2px solid #dee2e6;';
        const bgH = isTotal ? ' background:#e9ecef;' : '';
        // Period A sub-cols
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:100px; font-size:0.82rem; font-weight:600; ${bl}${bgH}">Orçado</th>`;
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:100px; font-size:0.82rem; font-weight:600;${bgH}">Realizado</th>`;
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:70px; font-size:0.82rem; font-weight:600;${bgH}">${dLabel}%</th>`;
        // Period B sub-cols
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:100px; font-size:0.82rem; font-weight:600; border-left:1px solid #adb5bd;${bgH}">Orçado</th>`;
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:100px; font-size:0.82rem; font-weight:600;${bgH}">Realizado</th>`;
        tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:70px; font-size:0.82rem; font-weight:600;${bgH}">${dLabel}%</th>`;
      }
      // Var columns
      tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:70px; font-size:0.82rem; font-weight:600; border-left:2px solid #495057; background:#e2e6ea;">Δ Orç %</th>`;
      tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:70px; font-size:0.82rem; font-weight:600; background:#e2e6ea;">Δ Real %</th>`;
      tr3.innerHTML += `<th class="text-end" style="padding:4px 6px; min-width:70px; font-size:0.82rem; font-weight:600; background:#e2e6ea;">Δ Orç−Real</th>`;
      thead.appendChild(tr3);
    } else {
      // Simple header: Conta | Orç A | Real A | Desvio A% | Orç B | Real B | Desvio B% | Var Orç% | Var Real%
      const tr1 = document.createElement('tr');
      tr1.innerHTML = '<th rowspan="2" style="padding:10px 14px; min-width:250px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#f8f9fa; z-index:11;">Conta</th>';
      tr1.innerHTML += `<th colspan="3" class="text-center" style="font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(labelA)}</th>`;
      tr1.innerHTML += `<th colspan="3" class="text-center" style="font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(labelB)}</th>`;
      tr1.innerHTML += '<th colspan="3" class="text-center" style="font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e9ecef;">Variação</th>';
      thead.appendChild(tr1);
      const tr2 = document.createElement('tr');
      tr2.innerHTML = `
        <th class="text-end" style="font-size:0.92rem; font-weight:600; border-left:2px solid #dee2e6; min-width:110px;">Orçado</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; min-width:110px;">Realizado</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; min-width:90px;">${dLabel} %</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; border-left:2px solid #dee2e6; min-width:110px;">Orçado</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; min-width:110px;">Realizado</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; min-width:90px;">${dLabel} %</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; border-left:2px solid #495057; background:#e9ecef; min-width:90px;">Δ Orç %</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; background:#e9ecef; min-width:90px;">Δ Real %</th>
        <th class="text-end" style="font-size:0.92rem; font-weight:600; background:#e9ecef; min-width:90px;">Δ Orç−Real</th>
      `;
      thead.appendChild(tr2);
    }

    const tbody = document.getElementById('tabelaBody');
    tbody.innerHTML = '';
    const colCount = isDetalhado ? 1 + (groups.length + 1) * 6 + 3 : 10;

    if (flat.length === 0) {
      tbody.innerHTML = `<tr><td colspan="${colCount}" class="text-center py-4 text-muted">Nenhuma conta encontrada.</td></tr>`;
      document.getElementById('tabelaFoot').innerHTML = '';
      return;
    }

    flat.forEach(row => {
      const tr = document.createElement('tr');
      const isSintetica = row.fltipo === 'S';
      const indent = row.level * 20;
      const fw = isSintetica ? 'fw-semibold' : '';
      const bg = isSintetica && row.level === 0 ? 'background:#f8fafc;' : '';
      const nat = row.flnatureza;

      const dscontaAttr = (row.dsconta || '').replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
      const lupaHtml = `<span class="ms-1 text-primary detalhe-comp-btn" data-cdconta="${row.cdconta}" data-cdcontacontabil="${row.cdcontacontabil || ''}" data-dsconta="${dscontaAttr}" data-fltipo="${row.fltipo}" style="cursor:pointer;" title="Ver lançamentos"><i class="bi bi-search" style="font-size:0.8rem;"></i></span>`;

      let contaHtml = '';
      if (row.hasChildren) {
        const icon = row.expanded ? 'bi-dash-square' : 'bi-plus-square';
        contaHtml = `<span style="margin-left:${indent}px;"><a href="#" class="text-decoration-none toggle-conta" data-cdconta="${row.cdconta}"><i class="bi ${icon}"></i></a> <span class="${isSintetica ? 'fw-bold' : ''}">${escHtml(row.dsconta)} (${escHtml(row.cdconta)})</span>${lupaHtml}</span>`;
      } else {
        contaHtml = `<span style="margin-left:${indent + 20}px;" class="${isSintetica ? 'fw-bold' : ''}">${escHtml(row.dsconta)} (${escHtml(row.cdconta)})${lupaHtml}</span>`;
      }

      tr.style.cssText = bg;

      if (isDetalhado) {
        let cells = `<td style="padding:8px 14px; white-space:nowrap; position:sticky; left:0; background:${bg || '#fff'}; z-index:1;">${contaHtml}</td>`;
        groups.forEach(g => {
          // Period A
          const orcA = sumMeses(row.orc_meses_a, g.meses);
          const realA = sumMeses(row.real_meses_a, g.meses);
          const dA = calcDev(orcA, realA);
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtValorComCor(orcA)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem;">${fmtValorComCor(realA)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; color:${corVariacao(dA.pct, nat)}">${fmtVariacaoPct(dA.pct, nat)}</td>`;
          // Period B
          const orcB = sumMeses(row.orc_meses_b, g.meses);
          const realB = sumMeses(row.real_meses_b, g.meses);
          const dB = calcDev(orcB, realB);
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:1px solid #adb5bd;">${fmtValorComCor(orcB)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem;">${fmtValorComCor(realB)}</td>`;
          cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; color:${corVariacao(dB.pct, nat)}">${fmtVariacaoPct(dB.pct, nat)}</td>`;
        });
        // Total A
        const oa = row.orc_a || 0, ra = row.real_a || 0;
        const dtA = calcDev(oa, ra);
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #495057; background:#f0f4f8;">${fmtValorComCor(oa)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8;">${fmtValorComCor(ra)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8; color:${corVariacao(dtA.pct, nat)}">${fmtVariacaoPct(dtA.pct, nat)}</td>`;
        // Total B
        const ob = row.orc_b || 0, rb = row.real_b || 0;
        const dtB = calcDev(ob, rb);
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:1px solid #adb5bd; background:#f0f4f8;">${fmtValorComCor(ob)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8;">${fmtValorComCor(rb)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8; color:${corVariacao(dtB.pct, nat)}">${fmtVariacaoPct(dtB.pct, nat)}</td>`;
        // Var period
        const vop = row.var_orc_pct || 0;
        const vrp = row.var_real_pct || 0;
        const vDiff = vrp - vop;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #495057; background:#e8ecf0; color:${corVariacao(vop, nat)}">${fmtVariacaoPct(vop, nat)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#e8ecf0; color:${corVariacao(vrp, nat)}">${fmtVariacaoPct(vrp, nat)}</td>`;
        cells += `<td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#e8ecf0; color:${corVariacao(vDiff, nat)}">${fmtVariacaoPct(vDiff, nat)}</td>`;
        tr.innerHTML = cells;
      } else {
        const oa = row.orc_a || 0, ra = row.real_a || 0;
        const ob = row.orc_b || 0, rb = row.real_b || 0;
        const dA = calcDev(oa, ra);
        const dB = calcDev(ob, rb);
        const varOrcPct = row.var_orc_pct || 0;
        const varRealPct = row.var_real_pct || 0;
        const varDiff = varRealPct - varOrcPct;

        tr.innerHTML = `
          <td style="padding:8px 14px; white-space:nowrap; position:sticky; left:0; background:${bg || '#fff'}; z-index:1;">${contaHtml}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtValorComCor(oa)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem;">${fmtValorComCor(ra)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; color:${corVariacao(dA.pct, nat)}">${fmtVariacaoPct(dA.pct, nat)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtValorComCor(ob)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem;">${fmtValorComCor(rb)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; color:${corVariacao(dB.pct, nat)}">${fmtVariacaoPct(dB.pct, nat)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; border-left:2px solid #495057; background:#f0f4f8; color:${corVariacao(varOrcPct, nat)}">${fmtVariacaoPct(varOrcPct, nat)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8; color:${corVariacao(varRealPct, nat)}">${fmtVariacaoPct(varRealPct, nat)}</td>
          <td class="text-end ${fw}" style="padding:8px 6px; font-size:1rem; background:#f0f4f8; color:${corVariacao(varDiff, nat)}">${fmtVariacaoPct(varDiff, nat)}</td>
        `;
      }
      tbody.appendChild(tr);
    });

    // Footer
    const tfoot = document.getElementById('tabelaFoot');
    const t = useTotais;

    if (isDetalhado) {
      let cells = '<td style="padding:12px 14px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#e2e6ea; z-index:1;">RESULTADO</td>';
      groups.forEach(g => {
        // Period A
        const orcA = sumMeses(t.orc_meses_a, g.meses);
        const realA = sumMeses(t.real_meses_a, g.meses);
        const dA = calcDev(orcA, realA);
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #dee2e6; background:#e2e6ea;">${fmtValorComCor(orcA)}</td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea;">${fmtValorComCor(realA)}</td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea; color:${corVariacao(dA.pct)}">${fmtVariacaoPct(dA.pct)}</td>`;
        // Period B
        const orcB = sumMeses(t.orc_meses_b, g.meses);
        const realB = sumMeses(t.real_meses_b, g.meses);
        const dB = calcDev(orcB, realB);
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:1px solid #adb5bd; background:#e2e6ea;">${fmtValorComCor(orcB)}</td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea;">${fmtValorComCor(realB)}</td>`;
        cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea; color:${corVariacao(dB.pct)}">${fmtVariacaoPct(dB.pct)}</td>`;
      });
      // Total A
      const fTA = calcDev(t.orc_a, t.real_a);
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #495057; background:#d5dae0;">${fmtValorComCor(t.orc_a)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0;">${fmtValorComCor(t.real_a)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0; color:${corVariacao(fTA.pct)}">${fmtVariacaoPct(fTA.pct)}</td>`;
      // Total B
      const fTB = calcDev(t.orc_b, t.real_b);
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:1px solid #adb5bd; background:#d5dae0;">${fmtValorComCor(t.orc_b)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0;">${fmtValorComCor(t.real_b)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0; color:${corVariacao(fTB.pct)}">${fmtVariacaoPct(fTB.pct)}</td>`;
      // Var
      const fVarDiff = (t.var_real_pct || 0) - (t.var_orc_pct || 0);
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #495057; background:#cdd3d9; color:${corVariacao(t.var_orc_pct || 0)}">${fmtVariacaoPct(t.var_orc_pct || 0)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#cdd3d9; color:${corVariacao(t.var_real_pct || 0)}">${fmtVariacaoPct(t.var_real_pct || 0)}</td>`;
      cells += `<td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#cdd3d9; color:${corVariacao(fVarDiff)}">${fmtVariacaoPct(fVarDiff)}</td>`;
      tfoot.innerHTML = `<tr>${cells}</tr>`;
    } else {
      const tDevA = calcDev(t.orc_a, t.real_a);
      const tDevB = calcDev(t.orc_b, t.real_b);
      tfoot.innerHTML = `<tr>
        <td style="padding:12px 14px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#e2e6ea; z-index:1;">RESULTADO</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #dee2e6; background:#e2e6ea;">${fmtValorComCor(t.orc_a)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea;">${fmtValorComCor(t.real_a)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea; color:${corVariacao(tDevA.pct)}">${fmtVariacaoPct(tDevA.pct)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #dee2e6; background:#e2e6ea;">${fmtValorComCor(t.orc_b)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea;">${fmtValorComCor(t.real_b)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#e2e6ea; color:${corVariacao(tDevB.pct)}">${fmtVariacaoPct(tDevB.pct)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; border-left:2px solid #495057; background:#d5dae0; color:${corVariacao(t.var_orc_pct || 0)}">${fmtVariacaoPct(t.var_orc_pct || 0)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0; color:${corVariacao(t.var_real_pct || 0)}">${fmtVariacaoPct(t.var_real_pct || 0)}</td>
        <td class="text-end" style="padding:12px 6px; font-size:1rem; font-weight:600; background:#d5dae0; color:${corVariacao((t.var_real_pct || 0) - (t.var_orc_pct || 0))}">${fmtVariacaoPct((t.var_real_pct || 0) - (t.var_orc_pct || 0))}</td>
      </tr>`;
    }

    // Bind toggle + detalhe
    tbody.querySelectorAll('.toggle-conta').forEach(a => {
      a.addEventListener('click', function(e) {
        e.preventDefault(); e.stopPropagation();
        const cd = this.dataset.cdconta;
        if (expandedNodes.has(cd)) expandedNodes.delete(cd); else expandedNodes.add(cd);
        renderTabelaOrcReal(dadosAtuais.dados, dadosAtuais.totais, dadosAtuais.labelA, dadosAtuais.labelB);
      });
    });
    tbody.querySelectorAll('.detalhe-comp-btn').forEach(btn => {
      btn.addEventListener('click', function(e) {
        e.preventDefault(); e.stopPropagation();
        abrirDetalheComp(this.dataset.cdconta, this.dataset.cdcontacontabil, this.dataset.dsconta, this.dataset.fltipo === 'S');
      });
    });
  }

  // ============================
  // VARIÁVEIS — Formatação por máscara
  // Valores sempre positivos (sem C/D), variação: queda=verde, subida=vermelho
  // ============================
  function fmtVarValor(v, mascara) {
    const val = v || 0;
    if (mascara === 'percentual') return fmtPct(Math.abs(val));
    const abs = Math.abs(val);
    return `${SIMBOLO} ${fmtNum(abs)}`;
  }

  function fmtVarVariacao(v, mascara) {
    const val = v || 0;
    if (mascara === 'percentual') {
      const sinal = val > 0 ? '+' : '';
      return sinal + fmtPct(val);
    }
    const abs = Math.abs(val);
    const sinal = val > 0 ? '+' : val < 0 ? '-' : '';
    return `${sinal}${SIMBOLO} ${fmtNum(abs)}`;
  }

  // Cor invertida para variáveis: aumento (positivo) = vermelho, queda (negativo) = verde
  function corVariacaoVar(v) {
    if (v > 0) return 'var(--bs-danger, #ef4444)';
    if (v < 0) return 'var(--bs-success, #10b981)';
    return 'var(--bs-secondary, #64748b)';
  }

  // Para percentual: delta = diferença em pontos (variacao_abs), exibido como %
  // Para numérico: delta = variação percentual (variacao_pct), exibido como %
  function fmtVarDelta(variacao_abs, variacao_pct, mascara) {
    if (mascara === 'percentual') {
      const val = variacao_abs || 0;
      const sinal = val > 0 ? '+' : '';
      const icon = val > 0 ? '↑' : val < 0 ? '↓' : '';
      return sinal + val.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) + '% ' + icon;
    }
    const val = variacao_pct || 0;
    const sinal = val > 0 ? '+' : '';
    const icon = val > 0 ? '↑' : val < 0 ? '↓' : '';
    return `${sinal}${val.toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}% ${icon}`;
  }

  function varDeltaValue(variacao_abs, variacao_pct, mascara) {
    return mascara === 'percentual' ? (variacao_abs || 0) : (variacao_pct || 0);
  }

  // ============================
  // VARIÁVEIS — KPIs + TABELA
  // ============================
  function renderKPIsVariaveis(data) {
    const container = document.getElementById('kpiContent');
    if (!data.variaveis || data.variaveis.length === 0) {
      container.innerHTML = '<div class="text-muted text-center py-3">Nenhuma variável com dados.</div>';
      return;
    }
    const yrA = data.anoA || '';
    const yrB = data.anoB || '';
    let html = '<div class="row g-2">';
    data.variaveis.forEach(v => {
      const m = v.mascara || 'moeda';
      html += `
        <div class="col-md-4">
          <div class="card border-0 shadow-sm"><div class="card-body py-3 text-center">
            <div class="fw-semibold mb-2" style="font-size:1.05rem; color:#334155;">${escHtml(v.nome)}</div>
            <div class="mb-1" style="font-size:1rem;"><span class="text-muted">${yrA}:</span> <strong>${fmtVarValor(v.total_a, m)}</strong></div>
            <div class="mb-1" style="font-size:1rem;"><span class="text-muted">${yrB}:</span> <strong>${fmtVarValor(v.total_b, m)}</strong></div>
            <div style="font-size:1rem;">Var: <strong><span style="color:${corVariacaoVar(varDeltaValue(v.variacao_abs, v.variacao_pct, m))}">${fmtVarDelta(v.variacao_abs, v.variacao_pct, m)}</span></strong></div>
          </div></div>
        </div>
      `;
    });
    html += '</div>';
    container.innerHTML = html;
  }

  function renderTabelaVariaveis(data, labelA, labelB) {
    const thead = document.getElementById('tabelaHead');
    const tbody = document.getElementById('tabelaBody');
    const tfoot = document.getElementById('tabelaFoot');
    thead.innerHTML = '';
    tbody.innerHTML = '';
    tfoot.innerHTML = '';

    if (!data.variaveis || data.variaveis.length === 0) {
      tbody.innerHTML = '<tr><td colspan="6" class="text-center py-4 text-muted">Nenhuma variável com dados.</td></tr>';
      return;
    }

    const modo = data.modo || 'periodo';
    let colA, colB;
    if (modo === 'orcreal') {
      colA = 'Orçado'; colB = 'Realizado';
    } else {
      colA = escHtml(labelA); colB = escHtml(labelB);
    }

    const groups = getColumnGroups();
    const isDetalhado = groups.length > 0;

    // --- Headers ---
    if (isDetalhado) {
      const tr1 = document.createElement('tr');
      tr1.innerHTML = '<th rowspan="2" style="padding:12px 14px; min-width:200px; position:sticky; left:0; background:#f8f9fa; z-index:11; font-size:1.05rem; font-weight:700;">Variável / Seção</th>';
      groups.forEach(g => {
        tr1.innerHTML += `<th colspan="3" class="text-center" style="padding:10px 6px; font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(g.label)}</th>`;
      });
      tr1.innerHTML += '<th colspan="3" class="text-center" style="padding:10px 6px; font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e9ecef;">Total</th>';
      thead.appendChild(tr1);

      const tr2 = document.createElement('tr');
      for (let i = 0; i <= groups.length; i++) {
        const isTotal = i === groups.length;
        const bl = isTotal ? 'border-left:2px solid #495057;' : 'border-left:2px solid #dee2e6;';
        const bgH = isTotal ? ' background:#e9ecef;' : '';
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:120px; font-size:0.92rem; font-weight:600; ${bl}${bgH}">${colA}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:120px; font-size:0.92rem; font-weight:600;${bgH}">${colB}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:90px; font-size:0.92rem; font-weight:600;${bgH}">Δ%</th>`;
      }
      thead.appendChild(tr2);
    } else {
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <th style="padding:12px 14px; min-width:200px; font-size:1.05rem; font-weight:700;">Variável / Seção</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">${colA}</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">${colB}</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">Variação</th>
        <th class="text-end" style="padding:12px 10px; min-width:110px; font-size:1.05rem; font-weight:700;">Var %</th>
      `;
      thead.appendChild(tr);
    }

    // --- Body ---
    data.variaveis.forEach(v => {
      // Header da variável
      const trV = document.createElement('tr');
      trV.style.cssText = 'background:#edf2f7;';
      const mV = v.mascara || ((v.secoes && v.secoes[0]) ? v.secoes[0].mascara : 'moeda');
      if (isDetalhado) {
        const colCount = 1 + (groups.length + 1) * 3;
        trV.innerHTML = `<td colspan="${colCount}" style="padding:10px 14px; font-size:1rem; font-weight:700; position:sticky; left:0; background:#edf2f7; z-index:1;"><i class="bi bi-calculator me-1"></i>${escHtml(v.nome)}</td>`;
      } else {
        trV.innerHTML = `
          <td style="padding:10px 14px; font-size:1rem; font-weight:700;"><i class="bi bi-calculator me-1"></i>${escHtml(v.nome)}</td>
          <td class="text-end fw-bold" style="padding:10px; font-size:1rem;">${fmtVarValor(v.total_a, mV)}</td>
          <td class="text-end fw-bold" style="padding:10px; font-size:1rem;">${fmtVarValor(v.total_b, mV)}</td>
          <td class="text-end fw-bold" style="padding:10px; font-size:1rem; color:${corVariacaoVar(v.variacao_abs || 0)}">${fmtVarVariacao(v.variacao_abs, mV)}</td>
          <td class="text-end fw-bold" style="padding:10px; font-size:1rem; color:${corVariacaoVar(varDeltaValue(v.variacao_abs, v.variacao_pct, mV))}">${fmtVarDelta(v.variacao_abs, v.variacao_pct, mV)}</td>
        `;
      }
      tbody.appendChild(trV);

      // Seções
      (v.secoes || []).forEach(s => {
        const trS = document.createElement('tr');
        const m = s.mascara || 'moeda';
        const tituloHtml = `<span style="padding-left:20px;">${escHtml(s.titulo)} ${m === 'percentual' ? '<span class="badge bg-secondary" style="font-size:0.65rem;">%</span>' : ''}</span>`;

        if (isDetalhado) {
          let cells = `<td style="padding:10px 14px; white-space:nowrap; font-size:1rem; font-weight:600; position:sticky; left:0; background:#fff; z-index:1;">${tituloHtml}</td>`;
          const isPct = (m === 'percentual');
          const hasFormula = s.formula && s.contas_meses_a && s.contas_meses_b;
          groups.forEach(g => {
            // Reagrupar contas brutas e aplicar fórmula (respeita parênteses)
            const va = hasFormula ? calcFormulaGrupo(s.formula, s.contas_meses_a, g.meses, isPct)
                                  : sumMeses(s.meses_a, g.meses);
            const vb = hasFormula ? calcFormulaGrupo(s.formula, s.contas_meses_b, g.meses, isPct)
                                  : sumMeses(s.meses_b, g.meses);
            const absA = Math.abs(va), absB = Math.abs(vb);
            const vp = calcVarPct(absA, absB);
            cells += `<td class="text-end fw-semibold" style="padding:10px 8px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtVarValor(va, m)}</td>`;
            cells += `<td class="text-end fw-semibold" style="padding:10px 8px; font-size:1rem;">${fmtVarValor(vb, m)}</td>`;
            const dv = absB - absA;
            cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; color:${corVariacaoVar(m === 'percentual' ? dv : vp)}">${fmtVarDelta(dv, vp, m)}</td>`;
          });
          // Total
          cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; border-left:2px solid #495057; background:#f0f4f8;">${fmtVarValor(s.valor_a, m)}</td>`;
          cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; background:#f0f4f8;">${fmtVarValor(s.valor_b, m)}</td>`;
          cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; background:#f0f4f8; color:${corVariacaoVar(varDeltaValue(s.variacao_abs, s.variacao_pct, m))}">${fmtVarDelta(s.variacao_abs, s.variacao_pct, m)}</td>`;
          trS.innerHTML = cells;
        } else {
          trS.innerHTML = `
            <td style="padding:8px 14px; font-size:1rem; font-weight:600;">${tituloHtml}</td>
            <td class="text-end fw-semibold" style="padding:8px 10px; font-size:1rem;">${fmtVarValor(s.valor_a, m)}</td>
            <td class="text-end fw-semibold" style="padding:8px 10px; font-size:1rem;">${fmtVarValor(s.valor_b, m)}</td>
            <td class="text-end fw-bold" style="padding:8px 10px; font-size:1rem; color:${corVariacaoVar(s.variacao_abs || 0)}">${fmtVarVariacao(s.variacao_abs, m)}</td>
            <td class="text-end fw-bold" style="padding:8px 10px; font-size:1rem; color:${corVariacaoVar(varDeltaValue(s.variacao_abs, s.variacao_pct, m))}">${fmtVarDelta(s.variacao_abs, s.variacao_pct, m)}</td>
          `;
        }
        tbody.appendChild(trS);
      });
    });
  }

  // ============================
  // INDICADORES — Formatação por máscara
  // ============================
  function fmtIndValor(v, mascara) {
    const val = v || 0;
    if (mascara === 'percentual') return fmtPct(val);
    if (mascara === 'inteiro') return Math.round(val).toLocaleString('pt-BR');
    // moeda (default)
    return fmtValorComCor(val);
  }

  function fmtIndVariacao(v, mascara) {
    const val = v || 0;
    if (mascara === 'percentual') return fmtPct(val);
    if (mascara === 'inteiro') {
      const sinal = val > 0 ? '+' : '';
      return sinal + Math.round(val).toLocaleString('pt-BR');
    }
    return fmtVariacao(val);
  }

  // ============================
  // INDICADORES — KPIs + TABELA
  // ============================
  function renderKPIsIndicadores(data) {
    const container = document.getElementById('kpiContent');
    if (!data.indicadores || data.indicadores.length === 0) {
      container.innerHTML = '<div class="text-muted text-center py-3">Nenhum indicador com dados.</div>';
      return;
    }
    let html = '<div class="row g-2">';
    const yrA = data.anoA || '';
    const yrB = data.anoB || '';
    data.indicadores.slice(0, 4).forEach(ind => {
      const m = ind.mascara || 'moeda';
      const isCalc = ind.tipo === 'calculado';
      const prefixTotal = isCalc ? 'Méd' : 'Total';
      const fmtA = fmtIndValor(ind.valor_a, m);
      const fmtB = fmtIndValor(ind.valor_b, m);
      html += `
        <div class="col-md-3">
          <div class="card border-0 shadow-sm"><div class="card-body py-3 text-center">
            <div class="fw-semibold mb-2" style="font-size:1.05rem; color:#334155;">${escHtml(ind.nome)}</div>
            <div class="mb-1" style="font-size:1rem;"><span class="text-muted">${yrA}:</span> <strong>${fmtA}</strong>${isCalc ? ' <span class="badge bg-secondary" style="font-size:0.7rem;">méd</span>' : ''}</div>
            <div class="mb-1" style="font-size:1rem;"><span class="text-muted">${yrB}:</span> <strong>${fmtB}</strong>${isCalc ? ' <span class="badge bg-secondary" style="font-size:0.7rem;">méd</span>' : ''}</div>
            <div style="font-size:1rem;">Var: <strong><span style="color:${corVariacao(ind.variacao_pct || 0)}">${fmtVariacaoPct(ind.variacao_pct || 0)}</span></strong></div>
          </div></div>
        </div>
      `;
    });
    html += '</div>';
    container.innerHTML = html;
  }

  function renderTabelaIndicadores(data, labelA, labelB) {
    const thead = document.getElementById('tabelaHead');
    const tbody = document.getElementById('tabelaBody');
    const tfoot = document.getElementById('tabelaFoot');
    thead.innerHTML = '';
    tbody.innerHTML = '';
    tfoot.innerHTML = '';

    if (!data.indicadores || data.indicadores.length === 0) {
      tbody.innerHTML = '<tr><td colspan="5" class="text-center py-4 text-muted">Nenhum indicador com dados.</td></tr>';
      return;
    }

    const groups = getColumnGroups();
    const isDetalhado = groups.length > 0;

    // --- Headers ---
    if (isDetalhado) {
      const tr1 = document.createElement('tr');
      tr1.innerHTML = '<th rowspan="2" style="padding:12px 14px; min-width:260px; font-size:1.05rem; font-weight:700; position:sticky; left:0; background:#f8f9fa; z-index:11;">Indicador</th>';
      groups.forEach(g => {
        tr1.innerHTML += `<th colspan="3" class="text-center" style="padding:10px 6px; font-size:1.05rem; font-weight:700; border-left:2px solid #dee2e6;">${escHtml(g.label)}</th>`;
      });
      // Header Total: será atualizado por linha (Méd/Total) mas no header fica genérico
      tr1.innerHTML += '<th colspan="3" class="text-center" style="padding:10px 6px; font-size:1.05rem; font-weight:700; border-left:2px solid #495057; background:#e9ecef;">Total / Méd</th>';
      thead.appendChild(tr1);

      const tr2 = document.createElement('tr');
      for (let i = 0; i <= groups.length; i++) {
        const isTotal = i === groups.length;
        const bl = isTotal ? 'border-left:2px solid #495057;' : 'border-left:2px solid #dee2e6;';
        const bgH = isTotal ? ' background:#e9ecef;' : '';
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:120px; font-size:0.92rem; font-weight:600; ${bl}${bgH}">${escHtml(labelA)}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:120px; font-size:0.92rem; font-weight:600;${bgH}">${escHtml(labelB)}</th>`;
        tr2.innerHTML += `<th class="text-end" style="padding:8px 8px; min-width:90px; font-size:0.92rem; font-weight:600;${bgH}">Δ%</th>`;
      }
      thead.appendChild(tr2);
    } else {
      const tr = document.createElement('tr');
      tr.innerHTML = `
        <th style="padding:12px 14px; min-width:260px; font-size:1.05rem; font-weight:700;">Indicador</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">${escHtml(labelA)}</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">${escHtml(labelB)}</th>
        <th class="text-end" style="padding:12px 10px; min-width:140px; font-size:1.05rem; font-weight:700;">Variação</th>
        <th class="text-end" style="padding:12px 10px; min-width:110px; font-size:1.05rem; font-weight:700;">Var %</th>
      `;
      thead.appendChild(tr);
    }

    // --- Body ---
    const colCount = isDetalhado ? 1 + (groups.length + 1) * 3 : 5;

    data.indicadores.forEach(ind => {
      const trI = document.createElement('tr');
      const m = ind.mascara || 'moeda';
      const isCalc = ind.tipo === 'calculado';
      const totalLabel = isCalc ? 'Méd' : 'Total';
      const nomeHtml = `<i class="bi bi-clipboard-data me-1"></i><strong>${escHtml(ind.nome)}</strong>${ind.descricao ? ' <span class="text-muted" style="font-size:0.9rem;">(' + escHtml(ind.descricao) + ')</span>' : ''}`;

      if (isDetalhado) {
        let cells = `<td style="padding:12px 14px; white-space:nowrap; font-size:1rem; position:sticky; left:0; background:#fff; z-index:1;">${nomeHtml}</td>`;
        groups.forEach(g => {
          const va = sumMeses(ind.meses_a, g.meses);
          const vb = sumMeses(ind.meses_b, g.meses);
          const vp = calcVarPct(va, vb);
          cells += `<td class="text-end fw-semibold" style="padding:10px 8px; font-size:1rem; border-left:2px solid #dee2e6;">${fmtIndValor(va, m)}</td>`;
          cells += `<td class="text-end fw-semibold" style="padding:10px 8px; font-size:1rem;">${fmtIndValor(vb, m)}</td>`;
          cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; color:${corVariacao(vp)}">${fmtVariacaoPct(vp)}</td>`;
        });
        // Total (média para calculado, soma para estático)
        cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; border-left:2px solid #495057; background:#f0f4f8;">${fmtIndValor(ind.valor_a, m)}</td>`;
        cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; background:#f0f4f8;">${fmtIndValor(ind.valor_b, m)}</td>`;
        cells += `<td class="text-end fw-bold" style="padding:10px 8px; font-size:1rem; background:#f0f4f8; color:${corVariacao(ind.variacao_pct || 0)}">${fmtVariacaoPct(ind.variacao_pct || 0)}</td>`;
        trI.innerHTML = cells;
      } else {
        const fmtA = fmtIndValor(ind.valor_a, m);
        const fmtB = fmtIndValor(ind.valor_b, m);
        const fmtV = fmtIndVariacao(ind.variacao_abs, m);
        trI.innerHTML = `
          <td style="padding:12px 14px; font-size:1rem;">${nomeHtml}</td>
          <td class="text-end fw-semibold" style="padding:12px 10px; font-size:1rem;">${fmtA}</td>
          <td class="text-end fw-semibold" style="padding:12px 10px; font-size:1rem;">${fmtB}</td>
          <td class="text-end fw-bold" style="padding:12px 10px; font-size:1rem; color:${corVariacao(ind.variacao_abs || 0)}">${fmtV}</td>
          <td class="text-end fw-bold" style="padding:12px 10px; font-size:1rem; color:${corVariacao(ind.variacao_pct || 0)}">${fmtVariacaoPct(ind.variacao_pct || 0)}</td>
        `;
      }
      tbody.appendChild(trI);
    });
  }

  // ============================
  // TOGGLE EXIBIÇÃO VALORES
  // ============================
  document.querySelectorAll('.comp-numerico-btn').forEach(btn => {
    btn.addEventListener('click', function() {
      document.querySelectorAll('.comp-numerico-btn').forEach(b => b.classList.remove('active'));
      this.classList.add('active');
      exibicaoValor = this.dataset.exibicao;
      if (dadosAtuais) {
        reRenderAtual();
      }
    });
  });

})();
</script>
