<?php
require_once(dirname(__DIR__) . '/config/db.php');

ini_set('display_errors', '0');
error_reporting(E_ALL);

$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, true);
$cdempresa = $_SESSION['cdempresa'] ?? 1;

function json_out_ind($arr, $code = 200) {
  http_response_code($code);
  header('Content-Type: application/json; charset=utf-8');
  echo json_encode($arr, JSON_UNESCAPED_UNICODE);
  exit;
}

set_error_handler(function($severity, $message, $file, $line) {
  $loc = basename($file) . ':' . $line;
  throw new ErrorException("$message @ $loc", 0, $severity, $file, $line);
});

set_exception_handler(function($e) {
  $loc = basename($e->getFile()) . ':' . $e->getLine();
  $msg = $e->getMessage();
  json_out_ind(['ok'=>false,'msg'=>"Erro interno ($loc): $msg"], 500);
});

$ajax = $_GET['ajax'] ?? '';
if ($ajax === '') { http_response_code(204); exit; }

switch ($ajax) {
  case 'comparar_periodos':
    compararIndicadores();
    break;

  default:
    json_out_ind(['ok' => false, 'msg' => 'Ação inválida'], 400);
}

/* ============================================================
 * COMPARAR INDICADORES — Período A vs B
 * Valores já pré-calculados em indicador_valor (tanto estáticos
 * quanto calculados). Apenas lê e compara.
 * ============================================================ */
function compararIndicadores() {
  global $pdo, $cdempresa;

  $anoA   = (int)($_GET['ano_a'] ?? 0);
  $anoB   = (int)($_GET['ano_b'] ?? 0);
  $mesesA = array_filter(array_map('intval', (array)($_GET['meses_a'] ?? [])));
  $mesesB = array_filter(array_map('intval', (array)($_GET['meses_b'] ?? [])));
  $cdindicador = !empty($_GET['cdindicador']) ? (int)$_GET['cdindicador'] : null;
  $cdgrupo = !empty($_GET['cdgrupo']) ? (int)$_GET['cdgrupo'] : null;

  if (!$anoA || !$anoB || empty($mesesA) || empty($mesesB)) {
    json_out_ind(['ok' => false, 'msg' => 'Informe os dois períodos para comparar.'], 400);
  }

  foreach (array_merge($mesesA, $mesesB) as $m) {
    if ($m < 1 || $m > 12) {
      json_out_ind(['ok' => false, 'msg' => 'Mês inválido.'], 400);
    }
  }

  // ---------- Carregar indicadores ----------
  $sqlInd = "
    SELECT i.cdindicador, i.nome, i.descricao, i.mascara, i.mascara_calc, i.tipo
      FROM back.indicador i
      LEFT JOIN back.grupo_indicador g ON g.cdgrupo = i.cdgrupo
     WHERE i.flativo = 0
       AND EXISTS (SELECT 1 FROM back.indicador_empresa ie WHERE ie.cdindicador = i.cdindicador AND ie.cdempresa = :emp)
  ";
  $paramsInd = [':emp' => $cdempresa];
  if ($cdindicador) {
    $sqlInd .= " AND i.cdindicador = :cdind";
    $paramsInd[':cdind'] = $cdindicador;
  }
  if ($cdgrupo) {
    $sqlInd .= " AND i.cdgrupo = :cdgrupo";
    $paramsInd[':cdgrupo'] = $cdgrupo;
  }
  $sqlInd .= " ORDER BY g.ordem NULLS LAST, g.cdgrupo NULLS LAST, CASE WHEN i.tipo = 'calculado' THEN 1 ELSE 0 END, i.ordem NULLS LAST, i.cdindicador";
  $stInd = $pdo->prepare($sqlInd);
  $stInd->execute($paramsInd);
  $indicadores = $stInd->fetchAll(PDO::FETCH_ASSOC);

  if (empty($indicadores)) {
    json_out_ind(['ok' => true, 'indicadores' => []]);
  }

  $calcVar = function(float $va, float $vb): array {
    $varAbs = $vb - $va;
    $varPct = ($va != 0) ? (($vb - $va) / abs($va)) * 100 : ($vb != 0 ? 100 : 0);
    return [round($varAbs, 4), round($varPct, 2)];
  };

  // ---------- Ler valores já gravados em indicador_valor ----------
  $mesesNome = ['','jan','fev','mar','abr','mai','jun','jul','ago','set','out','nov','dez'];
  $resultado = [];

  foreach ($indicadores as $ind) {
    $cdind = (int)$ind['cdindicador'];
    $isCalc = $ind['tipo'] === 'calculado';

    // Ler valores por mês (para detalhamento por granularidade)
    $mesesAObj = lerValoresPorMes($pdo, $cdind, $cdempresa, $anoA, $mesesA, $mesesNome, $isCalc);
    $mesesBObj = lerValoresPorMes($pdo, $cdind, $cdempresa, $anoB, $mesesB, $mesesNome, $isCalc);

    $somaA = array_sum(array_values((array)$mesesAObj));
    $somaB = array_sum(array_values((array)$mesesBObj));

    // Para calculado: total = média dos meses não-zero (mesma lógica da prévia)
    if ($isCalc) {
      $nzA = array_filter((array)$mesesAObj, fn($v) => (float)$v !== 0.0);
      $nzB = array_filter((array)$mesesBObj, fn($v) => (float)$v !== 0.0);
      $va = count($nzA) > 0 ? $somaA / count($nzA) : 0;
      $vb = count($nzB) > 0 ? $somaB / count($nzB) : 0;
    } else {
      $va = $somaA;
      $vb = $somaB;
    }

    [$varAbs, $varPct] = $calcVar($va, $vb);

    $resultado[] = [
      'cdindicador'   => (int)$ind['cdindicador'],
      'nome'          => $ind['nome'],
      'descricao'     => $ind['descricao'],
      'tipo'          => $ind['tipo'],
      'mascara'       => $isCalc ? ($ind['mascara_calc'] ?: $ind['mascara']) : $ind['mascara'],
      'valor_a'       => round($va, 4),
      'valor_b'       => round($vb, 4),
      'meses_a'       => $mesesAObj,
      'meses_b'       => $mesesBObj,
      'variacao_abs'  => $varAbs,
      'variacao_pct'  => $varPct,
    ];
  }

  json_out_ind([
    'ok'          => true,
    'indicadores' => $resultado,
    'mesesA'      => array_values($mesesA),
    'mesesB'      => array_values($mesesB),
  ]);
}

/**
 * Ler valores por mês individual de indicador_valor.
 * Retorna objeto {mesref: valor} para cada mês solicitado.
 */
function lerValoresPorMes(PDO $pdo, int $cdindicador, int $cdempresa,
                           int $ano, array $meses, array $mesesNome, bool $useCalc = false): object {
  $result = new \stdClass();
  foreach ($meses as $m) $result->{$m} = 0;

  $cols = [];
  foreach ($meses as $m) {
    $col = $mesesNome[$m] ?? null;
    if (!$col) continue;
    if ($useCalc) {
      $cols[] = "{$col}_calc AS m{$m}";
    } else {
      $src = in_array($col, ['set', 'out']) ? "\"$col\"" : $col;
      $cols[] = "COALESCE($src, 0) AS m{$m}";
    }
  }
  if (empty($cols)) return $result;

  $sql = "SELECT " . implode(', ', $cols) . " FROM back.indicador_valor
           WHERE cdindicador = ? AND cdempresa = ? AND anoref = ?";
  $st = $pdo->prepare($sql);
  $st->execute([$cdindicador, $cdempresa, $ano]);
  $row = $st->fetch(PDO::FETCH_ASSOC);
  if ($row) {
    foreach ($meses as $m) {
      $result->{$m} = round((float)($row["m{$m}"] ?? 0), 4);
    }
  }
  return $result;
}
