<?php
/**
 * Depto de Engenharia e Automação - Master Automação - Autor: Derlivon Silva
 * (parte do Premium Express BI - Fire Sistemas)
 *
 * Margem por Item — Compra × Venda.
 * Responde: "esse preço de compra ainda deixa lucro? quem está vendendo no prejuízo?"
 *
 * Reusa 100% do ComprasRepository::itensMargem() + kpisMargem() — esta classe
 * só carrega filtros, garante a entrega JSON limpa e segue o pattern do
 * RupturaController (ob_start + shutdown handler pra blindar JSON em E_ERROR).
 */

namespace App\Controllers;

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

class MargemController
{
    private function repo(): ComprasRepository
    {
        return new ComprasRepository(Database::conectar());
    }

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

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

    /** Datas: padrão = últimos 30 dias até a última compra (mesma régua do RupturaController). */
    private function parseDatas(string $ultima): array
    {
        $padraoIni = date('Y-m-d', strtotime($ultima . ' -29 days'));
        $ini = $_GET['data_ini'] ?? $padraoIni;
        $fim = $_GET['data_fim'] ?? $ultima;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $ini)) $ini = $padraoIni;
        if (!preg_match('/^\d{4}-\d{2}-\d{2}$/', $fim)) $fim = $ultima;
        if ($fim < $ini) $fim = $ini;
        return [$ini, $fim];
    }

    /** GET /compras/margem — shell instantâneo, dados via /api/compras/margem */
    public function index(): void
    {
        $this->guardaConexao();
        $config  = $this->config();
        $hoje    = date('Y-m-d');
        $padraoIni = date('Y-m-d', strtotime($hoje . ' -29 days'));
        View::render('compras/margem', [
            'titulo'   => 'Margem por Item — Premium Express Gestão',
            'config'   => $config,
            'segmento' => Lojas::resolverSegmento($config),
            'filtros'  => ['dataIni' => $padraoIni, 'dataFim' => $hoje],
            'ano'      => date('Y'),
        ]);
    }

    /** GET /api/compras/margem
     *
     * Blindagem (igual RupturaController.php L77-111): ob_start + shutdown handler
     * pra devolver JSON limpo mesmo em E_ERROR (memória/timeout/parse) — antes
     * disso, Fatal cuspia HTML em cima do JSON parcial e o front estourava.
     */
    public function dadosApi(): void
    {
        @ini_set('memory_limit', '512M');
        @ini_set('display_errors', '0');

        while (ob_get_level() > 0) { @ob_end_clean(); }
        ob_start();

        register_shutdown_function(function () {
            $err = error_get_last();
            if (!$err) return;
            $fatais = E_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_USER_ERROR;
            if (!($err['type'] & $fatais)) return;
            while (ob_get_level() > 0) { @ob_end_clean(); }
            if (!headers_sent()) {
                http_response_code(500);
                header('Content-Type: application/json; charset=utf-8');
            }
            echo json_encode([
                'ok'      => false,
                'erro'    => 'Erro interno ao calcular Margem (' . $err['type'] . ').',
                'detalhe' => $err['message'] ?? '',
                'kpis'    => [], 'itens' => [], 'top_margem' => [], 'bottom_margem' => [],
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        });

        $this->guardaConexao();
        header('Content-Type: application/json; charset=utf-8');

        try {
            $repo   = $this->repo();
            $ultima = $repo->ultimaData();
            [$ini, $fim] = $this->parseDatas($ultima);

            $filtro = (string)($_GET['filtro'] ?? 'todos');
            $limite = max(50, min(2000, (int)($_GET['limite'] ?? 500)));

            $itens = [];
            $kpis  = [];
            try { $itens = $repo->itensMargem($ini, $fim, $filtro, $limite); } catch (\Throwable) {}
            try { $kpis  = $repo->kpisMargem($ini, $fim); }                  catch (\Throwable) {}

            // Top 20 por margem R$ no período (só os que tiveram venda e geraram margem)
            $comMargem = array_values(array_filter($itens, fn($r) => (float)$r['MARGEM_VALOR_VENDA'] > 0));
            usort($comMargem, fn($a, $b) => $b['MARGEM_VALOR_VENDA'] <=> $a['MARGEM_VALOR_VENDA']);
            $topMargem = array_slice($comMargem, 0, 20);

            // Bottom 20: itens com prejuízo no período (ordem decrescente do prejuízo absoluto)
            $emPrejuizo = array_values(array_filter($itens, function ($r) {
                return $r['PREJUIZO'] && (float)$r['QTD_VENDIDA'] > 0;
            }));
            usort($emPrejuizo, function ($a, $b) {
                $pa = ((float)$a['CUSTO_EFETIVO'] - (float)$a['PRECO_VENDA']) * (float)$a['QTD_VENDIDA'];
                $pb = ((float)$b['CUSTO_EFETIVO'] - (float)$b['PRECO_VENDA']) * (float)$b['QTD_VENDIDA'];
                return $pb <=> $pa;
            });
            $bottomMargem = array_slice($emPrejuizo, 0, 20);

            echo json_encode([
                'ok'            => true,
                'kpis'          => $kpis,
                'itens'         => $itens,
                'top_margem'    => $topMargem,
                'bottom_margem' => $bottomMargem,
                'data_ini'      => $ini,
                'data_fim'      => $fim,
                'filtro'        => $filtro,
                'limite'        => $limite,
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        } catch (\Throwable $e) {
            http_response_code(500);
            echo json_encode([
                'ok' => false, 'erro' => $e->getMessage(),
                'kpis' => [], 'itens' => [], 'top_margem' => [], 'bottom_margem' => [],
            ], JSON_UNESCAPED_UNICODE | JSON_INVALID_UTF8_SUBSTITUTE);
        }
        exit;
    }
}
