<?php
/**
 * Depto de Engenharia e Automacao - Master Automacao - Autor: Derlivon Silva
 * (parte do Premium Express BI - Fire Sistemas)
 */

namespace App\Controllers;

use App\Core\Database;
use App\Core\View;
use App\Repositories\AuditoriaRepository;

class AuditoriaController
{
    private function repo(): AuditoriaRepository
    {
        return new AuditoriaRepository(Database::conectar());
    }

    private function config(): array
    {
        $path = dirname(__DIR__, 2) . '/config/database.php';
        return file_exists($path) ? (require $path) : [];
    }

    private function guardaConexao(): void
    {
        if (!Database::estaConfigurado()) {
            header('Location: /configurar'); exit;
        }
    }

    /** Parser robusto de período (?p=hoje|semana|mes|ano) ou ?data_ini=&data_fim= */
    private function parseDatas(): array
    {
        $hoje  = date('Y-m-d');
        $per   = (string)($_GET['p'] ?? '');
        $intervalos = [
            'hoje'   => [$hoje, $hoje],
            'semana' => [date('Y-m-d', strtotime('-6 days')), $hoje],
            'mes'    => [date('Y-m-01'), $hoje],
            'ano'    => [date('Y-01-01'), $hoje],
        ];
        if (isset($intervalos[$per])) {
            return [$intervalos[$per][0], $intervalos[$per][1], $per];
        }
        $ini = $_GET['data_ini'] ?? $intervalos['mes'][0];
        $fim = $_GET['data_fim'] ?? $hoje;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $ini)) $ini = $intervalos['mes'][0];
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fim)) $fim = $hoje;
        if ($fim < $ini) $fim = $ini;
        return [$ini, $fim, ''];
    }

    // ── INDEX do módulo Auditoria — dashboard consolidado ───────────────────
    public function index(): void
    {
        $this->guardaConexao();
        // Sempre mostra o MÊS ATUAL como visão padrão
        $ini = date('Y-m-01');
        $fim = date('Y-m-d');
        View::render('auditoria/index', [
            'titulo'   => 'Auditoria — Premium Express Gestão',
            'config'   => $this->config(),
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($this->config()),
            'erros'    => [],
            'ano'      => date('Y'),
            'dataIni'  => $ini,
            'dataFim'  => $fim,
        ]);
    }

    /** GET /api/auditoria/resumo — KPIs + mini rankings (Desconto+Cancel) do periodo */
    public function resumoApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        try {
            $desc = $this->repo()->descontoPorOperadora($ini, $fim);
            $canc = $this->repo()->cancelamentosPorOperadora($ini, $fim);

            $alertasDesc = array_filter($desc['lista'] ?? [], fn($r) => !empty($r['acima_media']));
            $alertasCanc = array_filter($canc['lista'] ?? [], fn($r) => !empty($r['acima_media']));

            echo json_encode([
                'ok'       => true,
                'data_ini' => $ini,
                'data_fim' => $fim,
                'desconto' => [
                    'total_fat'   => $desc['total_fat']  ?? 0,
                    'total_desc'  => $desc['total_desc'] ?? 0,
                    'media_pct'   => $desc['media_pct']  ?? 0,
                    'qtd_oper'    => count($desc['lista'] ?? []),
                    'qtd_alertas' => count($alertasDesc),
                    'top5'        => array_slice($desc['lista'] ?? [], 0, 5),
                ],
                'cancelamento' => [
                    'total_canc'  => $canc['total_canc'] ?? 0,
                    'qtd_canc'    => $canc['qtd_canc']   ?? 0,
                    'media_pct'   => $canc['media_pct']  ?? 0,
                    'qtd_oper'    => count($canc['lista'] ?? []),
                    'qtd_alertas' => count($alertasCanc),
                    'top5'        => array_slice($canc['lista'] ?? [], 0, 5),
                ],
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    // ── TELA: Desconto por Operadora ─────────────────────────────────────────
    public function descontoOperadora(): void
    {
        $this->guardaConexao();
        [$ini, $fim, $per] = $this->parseDatas();
        View::render('auditoria/desconto-operadora', [
            'titulo'   => 'Desconto por Operadora — Auditoria',
            'config'   => $this->config(),
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($this->config()),
            'erros'    => [],
            'ano'      => date('Y'),
            'dataIni'  => $ini,
            'dataFim'  => $fim,
            'periodo'  => $per,
        ]);
    }

    /** GET /api/auditoria/desconto-operadora?data_ini=&data_fim= */
    public function descontoOperadoraApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        try {
            $dados = $this->repo()->descontoPorOperadora($ini, $fim);
            echo json_encode([
                'ok'       => true,
                'data_ini' => $ini,
                'data_fim' => $fim,
                'lista'    => $dados['lista'],
                'totais'   => [
                    'faturado' => $dados['total_fat'],
                    'desconto' => $dados['total_desc'],
                    'media_pct'=> $dados['media_pct'],
                    'qtd_oper' => count($dados['lista']),
                ],
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
    }

    // ── TELA: Liberações de Caixa ────────────────────────────────────────────
    public function liberacoesCaixa(): void
    {
        $this->guardaConexao();
        [$ini, $fim, $per] = $this->parseDatas();
        $tipo = isset($_GET['tipo']) && $_GET['tipo'] !== '' ? (int)$_GET['tipo'] : null;
        View::render('auditoria/liberacoes-caixa', [
            'titulo'   => 'Liberações de Caixa — Auditoria',
            'config'   => $this->config(),
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($this->config()),
            'erros'    => [],
            'ano'      => date('Y'),
            'dataIni'  => $ini,
            'dataFim'  => $fim,
            'periodo'  => $per,
            'tipo'     => $tipo,
            'tipos'    => \App\Repositories\AuditoriaRepository::tiposLiberacao(),
        ]);
    }

    /** GET /api/auditoria/liberacoes-caixa?data_ini=&data_fim=&tipo= */
    public function liberacoesCaixaApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $tipo = isset($_GET['tipo']) && $_GET['tipo'] !== '' ? (int)$_GET['tipo'] : null;
        try {
            $dados = $this->repo()->liberacoesPorOperadora($ini, $fim, $tipo);
            // v3: expoe valor_desconto_real (TIPO=1) e valor_autorizado (TIPO 2,3) separados
            // pra o front renderizar TOTAIS_LOJA e Ticket Desconto medio corretamente.
            echo json_encode([
                'ok'                  => true,
                'data_ini'            => $ini,
                'data_fim'            => $fim,
                'tipo'                => $tipo,
                'solicitantes'        => $dados['solicitantes'],
                'supervisores'        => $dados['supervisores'],
                'total_geral'         => $dados['total_geral'],
                'totais_por_tipo'     => $dados['totais_por_tipo'],
                'media_por_oper'      => $dados['media_por_oper'],
                'valor_desconto_real' => $dados['valor_desconto_real'] ?? 0,
                'valor_autorizado'    => $dados['valor_autorizado']    ?? 0,
                'valor_total_geral'   => $dados['valor_total_geral']   ?? 0,
                'ticket_medio_loja'   => $dados['ticket_medio_loja']   ?? 0,
                'ticket_medio_sup'    => $dados['ticket_medio_sup']    ?? 0,
                'qtd_solic'           => count($dados['solicitantes']),
                'qtd_sup'             => count($dados['supervisores']),
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    /** GET /api/auditoria/liberacoes-caixa/detalhe?nome=&data_ini=&data_fim=&tipo= */
    public function liberacoesDetalheApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $nome = isset($_GET['nome']) ? trim((string)$_GET['nome']) : '';
        $tipo = isset($_GET['tipo']) && $_GET['tipo'] !== '' ? (int)$_GET['tipo'] : null;
        if ($nome === '') {
            echo json_encode(['ok' => false, 'erro' => 'Solicitante não informado (?nome=).'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $lista = $this->repo()->liberacoesDoSolicitante($ini, $fim, $nome, $tipo);
            echo json_encode(['ok' => true, 'lista' => $lista], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    /** GET /api/auditoria/liberacoes-caixa/por-supervisor?nome=&data_ini=&data_fim=&tipo= */
    public function liberacoesPorSupervisorApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $nome = isset($_GET['nome']) ? trim((string)$_GET['nome']) : '';
        $tipo = isset($_GET['tipo']) && $_GET['tipo'] !== '' ? (int)$_GET['tipo'] : null;
        if ($nome === '') {
            echo json_encode(['ok' => false, 'erro' => 'Supervisor não informado (?nome=).'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $lista = $this->repo()->liberacoesPorSupervisor($ini, $fim, $nome, $tipo);
            echo json_encode(['ok' => true, 'lista' => $lista], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    /**
     * GET /api/auditoria/liberacoes-caixa/perfil
     *   ?codigo=<login>&papel=solicitante|supervisor&data_ini=&data_fim=
     *
     * Retorna o perfil 360 graus do caixa (papel=solicitante) ou supervisor
     * (papel=supervisor) com KPIs, heatmap, evolucao, mix, top clientes/mensagens/
     * acessos, distribuicao de status e sinais de alerta. v1.4.34.
     */
    public function liberacoesPerfilApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $codigo = isset($_GET['codigo']) ? trim((string)$_GET['codigo']) : '';
        // Backward compat: aceita ?nome= tambem
        if ($codigo === '' && isset($_GET['nome'])) {
            $codigo = trim((string)$_GET['nome']);
        }
        $papel = isset($_GET['papel']) ? strtolower(trim((string)$_GET['papel'])) : 'solicitante';
        if (!in_array($papel, ['solicitante', 'supervisor'], true)) {
            $papel = 'solicitante';
        }
        if ($codigo === '') {
            echo json_encode(['ok' => false, 'erro' => 'Codigo nao informado (?codigo=).'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $perfil = $this->repo()->perfilLiberacao($codigo, $papel, $ini, $fim);
            $perfil['ok']    = true;
            $perfil['tipos'] = \App\Repositories\AuditoriaRepository::tiposLiberacao();
            echo json_encode($perfil, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    /** GET /api/auditoria/liberacoes-caixa/info?cod_seq= */
    public function liberacaoInfoApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        $codSeq = isset($_GET['cod_seq']) ? (int)$_GET['cod_seq'] : 0;
        if ($codSeq <= 0) {
            echo json_encode(['ok' => false, 'erro' => 'COD_SEQ inválido.'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $info = $this->repo()->detalheLiberacao($codSeq);
            echo json_encode($info, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE);
        }
    }

    // ── TELA: Cancelamentos por Operadora ────────────────────────────────────
    public function cancelamentosOperadora(): void
    {
        $this->guardaConexao();
        [$ini, $fim, $per] = $this->parseDatas();
        View::render('auditoria/cancelamentos-operadora', [
            'titulo'   => 'Cancelamentos por Operadora — Auditoria',
            'config'   => $this->config(),
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($this->config()),
            'erros'    => [],
            'ano'      => date('Y'),
            'dataIni'  => $ini,
            'dataFim'  => $fim,
            'periodo'  => $per,
        ]);
    }

    /** GET /api/auditoria/cancelamentos-operadora?data_ini=&data_fim= */
    public function cancelamentosOperadoraApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        try {
            $dados = $this->repo()->cancelamentosPorOperadora($ini, $fim);
            echo json_encode([
                'ok'       => true,
                'data_ini' => $ini,
                'data_fim' => $fim,
                'lista'    => $dados['lista'],
                'totais'   => [
                    'valor_cancelado' => $dados['total_canc'],
                    'valor_valido'    => $dados['total_val'],
                    'qtd_canceladas'  => $dados['qtd_canc'],
                    'media_pct'       => $dados['media_pct'],
                    'qtd_oper'        => count($dados['lista']),
                ],
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
    }

    /** GET /api/auditoria/cancelamentos-operadora/notas?nome=&data_ini=&data_fim= */
    public function notasCanceladasApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $nome = isset($_GET['nome']) ? (string)$_GET['nome'] : '';
        if ($nome === '') {
            echo json_encode(['ok' => false, 'erro' => 'Operadora não informada (?nome=).'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $notas = $this->repo()->notasCanceladasDaOperadora($ini, $fim, $nome);
            echo json_encode(['ok' => true, 'lista' => $notas], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
    }

    /** GET /api/auditoria/desconto-operadora/notas?cod=LOGIN&data_ini=&data_fim= */
    public function notasComDescontoApi(): void
    {
        header('Content-Type: application/json; charset=utf-8');
        [$ini, $fim] = $this->parseDatas();
        $cod = isset($_GET['cod']) ? trim((string)$_GET['cod']) : '';
        if ($cod === '') {
            echo json_encode(['ok' => false, 'erro' => 'Operadora não informada (?cod=).'], JSON_UNESCAPED_UNICODE);
            return;
        }
        try {
            $notas = $this->repo()->notasComDescontoDaOperadora($ini, $fim, $cod);
            echo json_encode(['ok' => true, 'lista' => $notas], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['ok' => false, 'erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
    }
}
