<?php

namespace App\Controllers;

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

class ComprasController
{
    private function repo(): ComprasRepository
    {
        return new ComprasRepository(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; }
    }

    private function tentar(callable $fn, mixed $padrao, array &$erros): mixed
    {
        try { return $fn(); } catch (\Throwable $e) { $erros[] = $e->getMessage(); return $padrao; }
    }

    // ── Filtros SEM consulta ao banco — só session + GET ─────────────────────
    // Usado para render do shell: TTFB < 10ms, sem conexão Firebird.
    private function filtrosSemDB(): array
    {
        $hoje    = date('Y-m-d');
        $sessAno = isset($_SESSION['filtro_ano']) ? (int)$_SESSION['filtro_ano'] : null;
        $sessMes = isset($_SESSION['filtro_mes']) && (int)$_SESSION['filtro_mes'] > 0
                   ? (int)$_SESSION['filtro_mes'] : null;

        if ($sessAno && $sessMes) {
            $defaultIni = sprintf('%04d-%02d-01', $sessAno, $sessMes);
            $fimDoMes   = date('Y-m-t', strtotime($defaultIni));
            $defaultFim = min($fimDoMes, $hoje);
            if ($defaultIni > $hoje) { $defaultIni = $defaultFim = $hoje; }
        } elseif ($sessAno) {
            $defaultIni = sprintf('%04d-01-01', $sessAno);
            $defaultFim = min(sprintf('%04d-12-31', $sessAno), $hoje);
        } else {
            $defaultIni = date('Y-m-01');
            $defaultFim = $hoje;
        }

        $dataIni = $_GET['data_ini'] ?? $defaultIni;
        $dataFim = $_GET['data_fim'] ?? $defaultFim;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataIni)) $dataIni = $defaultIni;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataFim))  $dataFim = $defaultFim;
        if ($dataFim < $dataIni) $dataFim = $dataIni;

        $anoSel  = (int)substr($dataIni, 0, 4);
        $anoAtual = (int)date('Y');
        // Anos estáticos (últimos 5) — API retorna anos reais e JS atualiza as abas
        $anos = range($anoAtual, max(2020, $anoAtual - 4));

        return compact('dataIni', 'dataFim', 'anos', 'anoSel');
    }

    // ── Filtros COM banco (para páginas ainda não convertidas) ────────────────
    private function filtros(ComprasRepository $repo): array
    {
        $ultima  = $repo->ultimaData();
        $sessAno = isset($_SESSION['filtro_ano']) ? (int)$_SESSION['filtro_ano'] : null;
        $sessMes = isset($_SESSION['filtro_mes']) && (int)$_SESSION['filtro_mes'] > 0 ? (int)$_SESSION['filtro_mes'] : null;

        $hoje = date('Y-m-d');
        if ($sessAno && $sessMes) {
            $defaultIni = sprintf('%04d-%02d-01', $sessAno, $sessMes);
            $fimDoMes   = date('Y-m-t', strtotime($defaultIni));
            $defaultFim = min($fimDoMes, $hoje);
            if ($defaultIni > $hoje) { $defaultIni = $defaultFim = $ultima; }
        } elseif ($sessAno) {
            $defaultIni = sprintf('%04d-01-01', $sessAno);
            $defaultFim = min(sprintf('%04d-12-31', $sessAno), $hoje);
        } else {
            $defaultIni = date('Y-m-01', strtotime($ultima));
            $defaultFim = $ultima;
        }

        $dataIni = $_GET['data_ini'] ?? $defaultIni;
        $dataFim = $_GET['data_fim'] ?? $defaultFim;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataIni)) $dataIni = $defaultIni;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataFim))  $dataFim = $defaultFim;
        if ($dataFim < $dataIni) $dataFim = $dataIni;

        $anos   = $repo->anosDisponiveis();
        $anoSel = (int)substr($dataIni, 0, 4);
        return compact('dataIni', 'dataFim', 'anos', 'anoSel');
    }

    // ── API helper: parse e valida datas do GET ───────────────────────────────
    private function parseDatas(string $ultimaFallback): array
    {
        $dataIni = $_GET['data_ini'] ?? date('Y-m-01', strtotime($ultimaFallback));
        $dataFim = $_GET['data_fim'] ?? $ultimaFallback;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataIni)) $dataIni = date('Y-m-01', strtotime($ultimaFallback));
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataFim))  $dataFim = $ultimaFallback;
        if ($dataFim < $dataIni) $dataFim = $dataIni;
        return [$dataIni, $dataFim];
    }

    // ════════════════════════════════════════════════════════════════════════
    //  PÁGINAS — shell instantâneo, sem queries no render
    // ════════════════════════════════════════════════════════════════════════

    public function dashboard(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        $filtros = $this->filtrosSemDB();
        View::render('compras/dashboard', [
            'titulo'   => 'Dashboard de Compras — Premium Express Gestão',
            'config'   => $config,
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($config),
            'filtros'  => $filtros,
            'erros'    => [],
            'ano'      => date('Y'),
        ]);
    }

    public function notasEntrada(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        // Shell não faz Database::verificar() — sem conexão Firebird aqui.
        // Erros de conexão são retornados pelos endpoints JSON via AJAX.
        $filtros = $this->filtrosSemDB();

        View::render('compras/notas-entrada', [
            'titulo'   => 'Notas de Entrada — Premium Express Gestão',
            'config'   => $config,
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($config),
            'filtros'  => $filtros,
            'erros'    => [],
            'ano'      => date('Y'),
        ]);
    }

    public function porFornecedor(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        $filtros = $this->filtrosSemDB();
        // Por fornecedor defaults to full-year window
        if (!isset($_GET['data_ini'])) {
            $filtros['dataIni'] = substr($filtros['dataFim'], 0, 4) . '-01-01';
        }

        View::render('compras/por-fornecedor', [
            'titulo'   => 'Compras por Fornecedor — Premium Express Gestão',
            'config'   => $config,
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($config),
            'filtros'  => $filtros,
            'erros'    => [],
            'ano'      => date('Y'),
        ]);
    }

    public function comprasVendas(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        $filtros = $this->filtrosSemDB();

        View::render('compras/compras-vendas', [
            'titulo'   => 'Compras × Vendas — Premium Express Gestão',
            'config'   => $config,
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($config),
            'filtros'  => $filtros,
            'erros'    => [],
            'ano'      => date('Y'),
        ]);
    }

    public function custoMedio(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        $filtros = $this->filtrosSemDB();

        View::render('compras/custo-medio', [
            'titulo'   => 'Custo Médio de Compra — Premium Express Gestão',
            'config'   => $config,
            'conexao'  => ['success' => true, 'mensagem' => ''],
            'segmento' => \App\Core\Lojas::resolverSegmento($config),
            'filtros'  => $filtros,
            'erros'    => [],
            'ano'      => date('Y'),
        ]);
    }

    // ════════════════════════════════════════════════════════════════════════
    //  APIs JSON — dados carregados pelo browser após o shell aparecer
    // ════════════════════════════════════════════════════════════════════════

    /** GET /api/compras/custo-medio?data_ini=&data_fim=&alvo=6&apenas=&ordenar=&busca=&limite= */
    public function custoMedioApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            [$dataIni, $dataFim] = $this->parseDatas($ultima);
            $g = $_GET;
            $f = [
                'data_ini' => $dataIni,
                'data_fim' => $dataFim,
                'alvo'     => $g['alvo']    ?? 6,
                'apenas'   => $g['apenas']  ?? '',
                'tipo'     => $g['tipo']    ?? '',
                'ordenar'  => $g['ordenar'] ?? 'custo',
                'busca'    => $g['busca']   ?? '',
                'limite'   => $g['limite']  ?? 1000,
            ];
            $out = $repo->custoMedioCompra($f);
            $out['anos'] = $repo->anosDisponiveis();
            echo json_encode($out, JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/dashboard?data_ini=&data_fim= */
    public function dashboardApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            [$dataIni, $dataFim] = $this->parseDatas($ultima);
            $anos = $repo->anosDisponiveis();

            $kpis         = [];
            $evolucao     = [];
            $diaSemana    = [];
            $fornecedores = [];
            $itensValor   = [];
            $itensQtd     = [];
            $totalVendas  = 0.0;

            try { $kpis         = $repo->kpis($dataIni, $dataFim); }                       catch (\Throwable) {}
            try { $evolucao      = $repo->evolucaoDiaria($dataIni, $dataFim); }              catch (\Throwable) {}
            try { $diaSemana     = $repo->comprasPorDiaSemana($dataIni, $dataFim); }         catch (\Throwable) {}
            try { $fornecedores  = $repo->fornecedoresDetalhado($dataIni, $dataFim); }       catch (\Throwable) {}
            try { $itensValor    = $repo->itensMaisComprados($dataIni, $dataFim, 20); }      catch (\Throwable) {}
            try { $itensQtd      = $repo->itensMaisCompradosQtd($dataIni, $dataFim, 20); }  catch (\Throwable) {}
            try { $totalVendas   = $repo->totalVendasPeriodo($dataIni, $dataFim); }          catch (\Throwable) {}
            $variacaoPreco  = [];
            $comparativoForn = [];
            try { $variacaoPreco   = $repo->variacaoPreco($dataIni, $dataFim, 20); }         catch (\Throwable) {}
            try { $comparativoForn = $repo->comparativoFornecedorItem($dataIni, $dataFim); } catch (\Throwable) {}

            // Quick wins do roadmap Compras (06/2026):
            //   - kpis_yoy   = comparativo mês anterior + ano anterior
            //   - devolucoes = total devolvido no período (excluído do gasto líquido)
            //   - impostos   = ICMS+IPI+ST+FRETE — peso fiscal sobre o bruto
            // Depto de Engenharia e Automação - Master Automação - Autor: Derlivon Silva
            $kpisYoY    = [];
            $devolucoes = [];
            $impostos   = [];
            try { $kpisYoY    = $repo->kpisComparativo($dataIni, $dataFim);   } catch (\Throwable) {}
            try { $devolucoes = $repo->devolucoesCompras($dataIni, $dataFim); } catch (\Throwable) {}
            try { $impostos   = $repo->kpisImpostos($dataIni, $dataFim);      } catch (\Throwable) {}

            echo json_encode([
                'kpis'         => $kpis,
                'evolucao'     => $evolucao,
                'dia_semana'   => $diaSemana,
                'fornecedores' => $fornecedores,
                'itens_valor'  => $itensValor,
                'itens_qtd'    => $itensQtd,
                'total_vendas' => $totalVendas,
                'anos'         => $anos,
                'data_ini'        => $dataIni,
                'data_fim'        => $dataFim,
                'variacao_preco'  => $variacaoPreco,
                'comparativo_forn'=> $comparativoForn,
                'kpis_yoy'        => $kpisYoY,
                'devolucoes'      => $devolucoes,
                'impostos'        => $impostos,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/kpis?data_ini=&data_fim= */
    public function kpisApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        $erros = [];
        try {
            $repo  = $this->repo();
            $ultima = $repo->ultimaData();
            [$dataIni, $dataFim] = $this->parseDatas($ultima);
            $kpis  = $repo->kpis($dataIni, $dataFim);
            $anos  = $repo->anosDisponiveis();
            echo json_encode([
                'kpis'      => $kpis,
                'anos'      => $anos,
                'ultimaData'=> $ultima,
                'dataIni'   => $dataIni,
                'dataFim'   => $dataFim,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/notas?data_ini=&data_fim=&limite=50 */
    public function notasApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            [$dataIni, $dataFim] = $this->parseDatas($ultima);
            $limite = min(200, max(10, (int)($_GET['limite'] ?? 50)));
            $notas  = $repo->notasEntrada($dataIni, $dataFim, $limite);
            echo json_encode(['notas' => $notas], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/itens-mais-caros?data_ini=&data_fim= */
    public function itensMaisCarosApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            [$dataIni, $dataFim] = $this->parseDatas($ultima);
            $itens  = $repo->itensMaisCaros($dataIni, $dataFim);
            echo json_encode(['itens' => $itens], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/por-fornecedor?data_ini=&data_fim= */
    public function porFornecedorApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            // Por fornecedor defaults to full-year window
            $dataIni = $_GET['data_ini'] ?? date('Y-01-01', strtotime($ultima));
            $dataFim = $_GET['data_fim'] ?? $ultima;
            if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataIni)) $dataIni = date('Y-01-01', strtotime($ultima));
            if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $dataFim))  $dataFim = $ultima;
            if ($dataFim < $dataIni) $dataFim = $dataIni;
            $anos   = $repo->anosDisponiveis();
            $linhas = $repo->porFornecedor($dataIni, $dataFim);
            $itens  = $repo->itensMaisComprados($dataIni, $dataFim);
            echo json_encode([
                'linhas'  => $linhas,
                'itens'   => $itens,
                'anos'    => $anos,
                'dataIni' => $dataIni,
                'dataFim' => $dataFim,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }

    /** GET /api/compras/compras-vendas?ano= */
    public function comprasVendasApi(): void
    {
        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');
        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            $anoSel = isset($_GET['ano']) && ctype_digit($_GET['ano'])
                ? (int)$_GET['ano']
                : (int)substr($ultima, 0, 4);
            $anos   = $repo->anosDisponiveis();
            $linhas = $repo->comprasVendasMensal($anoSel);
            echo json_encode([
                'linhas'  => $linhas,
                'anos'    => $anos,
                'anoSel'  => $anoSel,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode(['erro' => $e->getMessage()], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }
}
