<?php
// Depto de Engenharia e Automacao - Master Automacao - Autor: Derlivon Silva

namespace App\Repositories;

use App\Core\Cache;
use App\Core\Lojas;

/**
 * Convênios — Grancard, VR, Alelo, etc.
 * Estrutura ERP Fire:
 *   CONVENIOS                — cadastro (COD_CONVENIO, COD_EMPRESA, APELIDO, ATIVO, COD_PESSOA)
 *   PESSOAS_CONVENIOS        — vínculo pessoa→convênio (matrícula, validade)
 *   RECEBER_PAGAR            — títulos a receber (FK COD_CONVENIO, SALDO_TITULO, VENCIMENTO)
 *   CONVENIOS_VALES          — vales emitidos
 */
class ConveniosRepository
{
    public function __construct(private \PDO $pdo) {}

    private function empresa(): int
    {
        try { $e = (int) Lojas::codEmpresaAtiva(); return $e ?: 5; }
        catch (\Throwable) { return 5; }
    }

    private function utf8($s): string
    {
        $s = (string)$s;
        if ($s !== '' && !mb_check_encoding($s, 'UTF-8')) {
            $s = mb_convert_encoding($s, 'UTF-8', 'Windows-1252');
        }
        return $s;
    }

    /** Lista convênios cadastrados (ativos) com KPIs no período + saldo total. */
    public function listar(string $dataIni, string $dataFim): array
    {
        $emp = $this->empresa();
        $ttl = ($dataFim >= date('Y-m-d')) ? 60 : 1800;
        return Cache::lembrar("conv_lista_{$dataIni}_{$dataFim}_{$emp}", $ttl, function () use ($emp, $dataIni, $dataFim) {
            $sql = "SELECT
                c.COD_CONVENIO,
                COALESCE(c.APELIDO, p.NOME) AS NOME,
                p.NOME AS RAZAO,
                c.ATIVO,
                COALESCE(c.DESCONTO, 0) DESCONTO,

                COALESCE((SELECT SUM(rp.VALOR_TITULO) FROM RECEBER_PAGAR rp
                          WHERE rp.COD_CONVENIO = c.COD_CONVENIO
                            AND rp.COD_EMPRESA  = c.COD_EMPRESA
                            AND rp.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'), 0) VENDIDO_PERIODO,

                COALESCE((SELECT SUM(rp.VALOR_TITULO - rp.SALDO_TITULO) FROM RECEBER_PAGAR rp
                          WHERE rp.COD_CONVENIO = c.COD_CONVENIO
                            AND rp.COD_EMPRESA  = c.COD_EMPRESA
                            AND rp.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'), 0) RECEBIDO_PERIODO,

                COALESCE((SELECT SUM(rp.SALDO_TITULO) FROM RECEBER_PAGAR rp
                          WHERE rp.COD_CONVENIO = c.COD_CONVENIO
                            AND rp.COD_EMPRESA  = c.COD_EMPRESA
                            AND rp.SALDO_TITULO > 0), 0) SALDO_TOTAL_ABERTO,

                COALESCE((SELECT SUM(rp.SALDO_TITULO) FROM RECEBER_PAGAR rp
                          WHERE rp.COD_CONVENIO = c.COD_CONVENIO
                            AND rp.COD_EMPRESA  = c.COD_EMPRESA
                            AND rp.SALDO_TITULO > 0
                            AND rp.VENCIMENTO < CURRENT_DATE), 0) SALDO_VENCIDO
            FROM CONVENIOS c
            LEFT JOIN PESSOAS p ON c.COD_PESSOA = p.COD_PESSOA
            WHERE c.COD_EMPRESA = {$emp}
            ORDER BY VENDIDO_PERIODO DESC, NOME";

            $rows = $this->pdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
            foreach ($rows as &$r) {
                $r['NOME']  = $this->utf8($r['NOME']  ?? '');
                $r['RAZAO'] = $this->utf8($r['RAZAO'] ?? '');
            }
            return $rows;
        });
    }

    /** KPIs gerais — soma de todos os convênios da loja no período. */
    public function painel(string $dataIni, string $dataFim): array
    {
        $emp = $this->empresa();
        $ttl = ($dataFim >= date('Y-m-d')) ? 60 : 1800;
        return Cache::lembrar("conv_painel_{$dataIni}_{$dataFim}_{$emp}", $ttl, function () use ($emp, $dataIni, $dataFim) {
            $kpis = $this->pdo->query("SELECT
                COUNT(DISTINCT c.COD_CONVENIO)                              TOTAL_CONVENIOS_ATIVOS,
                COALESCE(SUM(rp.VALOR_TITULO), 0)                           VENDIDO_PERIODO,
                COALESCE(SUM(rp.VALOR_TITULO - rp.SALDO_TITULO), 0)         RECEBIDO_PERIODO,
                COALESCE(SUM(CASE WHEN rp.SALDO_TITULO > 0 THEN rp.SALDO_TITULO ELSE 0 END), 0) SALDO_ABERTO_PERIODO,
                COUNT(rp.PARCELA)                                           QTD_TITULOS
            FROM CONVENIOS c
            LEFT JOIN RECEBER_PAGAR rp
                   ON rp.COD_CONVENIO = c.COD_CONVENIO
                  AND rp.COD_EMPRESA  = c.COD_EMPRESA
                  AND rp.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'
            WHERE c.COD_EMPRESA = {$emp}")->fetch(\PDO::FETCH_ASSOC) ?: [];

            $vencido = $this->pdo->query("SELECT
                COALESCE(SUM(rp.SALDO_TITULO),0) TOTAL,
                COUNT(*) QTD
            FROM RECEBER_PAGAR rp
            WHERE rp.COD_EMPRESA = {$emp}
              AND rp.COD_CONVENIO IS NOT NULL
              AND rp.SALDO_TITULO > 0
              AND rp.VENCIMENTO < CURRENT_DATE")->fetch(\PDO::FETCH_ASSOC) ?: [];

            return [
                'total_convenios_ativos' => (int)($kpis['TOTAL_CONVENIOS_ATIVOS'] ?? 0),
                'vendido_periodo'        => (float)($kpis['VENDIDO_PERIODO'] ?? 0),
                'recebido_periodo'       => (float)($kpis['RECEBIDO_PERIODO'] ?? 0),
                'saldo_aberto_periodo'   => (float)($kpis['SALDO_ABERTO_PERIODO'] ?? 0),
                'qtd_titulos_periodo'    => (int)($kpis['QTD_TITULOS'] ?? 0),
                'vencido_total'          => (float)($vencido['TOTAL'] ?? 0),
                'qtd_titulos_vencidos'   => (int)($vencido['QTD'] ?? 0),
            ];
        });
    }

    /** Aging: títulos em aberto agrupados por faixa de dias desde o vencimento.
     *  Pega titulos com COD_CONVENIO E titulos vinculados a forma-de-pgto-tipo-convenio. */
    public function aging(): array
    {
        $emp = $this->empresa();
        return Cache::lembrar("conv_aging_v2_{$emp}", 300, function () use ($emp) {
            // Lista das formas-tipo-convenio (Grancard/VR/etc) p/ filtrar
            $formasIn = '';
            try {
                $sqlForm = "SELECT DISTINCT fp.COD_FORMA_PGTO, TRIM(fp.DESCRICAO) D FROM FORMA_PGTO fp WHERE fp.COD_EMPRESA = {$emp}
                            UNION
                            SELECT DISTINCT fn.COD_FORMA_PGTO,
                                   (SELECT FIRST 1 TRIM(fp2.DESCRICAO) FROM FORMA_PGTO fp2 WHERE fp2.COD_FORMA_PGTO = fn.COD_FORMA_PGTO AND TRIM(COALESCE(fp2.DESCRICAO,'')) <> '')
                            FROM FORMAS_NOTAS fn WHERE fn.COD_EMPRESA = {$emp} AND fn.DATA_EMISSAO >= DATEADD(MONTH, -24, CURRENT_DATE)";
                $codigos = [];
                foreach ($this->pdo->query($sqlForm) as $r) {
                    if ($this->ehFormaTipoConvenio((string)($r['D'] ?? ''))) {
                        $codigos[] = (string)$r['COD_FORMA_PGTO'];
                    }
                }
                $codigos = array_values(array_unique($codigos));
                if ($codigos) {
                    $formasIn = "'" . implode("','", array_map(fn($k) => str_replace("'","''",$k), $codigos)) . "'";
                }
            } catch (\Throwable) { /* segue só com COD_CONVENIO */ }

            $cond = "(rp.COD_CONVENIO IS NOT NULL";
            if ($formasIn) {
                $cond .= " OR EXISTS (SELECT 1 FROM FORMAS_NOTAS fn
                            WHERE fn.NR_NOTA = rp.NR_NOTA
                              AND fn.COD_EMPRESA = rp.COD_EMPRESA
                              AND fn.SEQ_FORMA_NOTAS = rp.SEQ_FORMA_NOTAS
                              AND fn.COD_FORMA_PGTO IN ({$formasIn}))";
            }
            $cond .= ")";

            $sql = "SELECT
                CASE
                  WHEN rp.VENCIMENTO >= CURRENT_DATE                                        THEN 'A_VENCER'
                  WHEN DATEDIFF(DAY FROM rp.VENCIMENTO TO CURRENT_DATE) <= 15                THEN 'D_0_15'
                  WHEN DATEDIFF(DAY FROM rp.VENCIMENTO TO CURRENT_DATE) <= 30                THEN 'D_16_30'
                  WHEN DATEDIFF(DAY FROM rp.VENCIMENTO TO CURRENT_DATE) <= 60                THEN 'D_31_60'
                  ELSE                                                                            'D_61_MAIS'
                END FAIXA,
                COUNT(*) QTD,
                SUM(rp.SALDO_TITULO) SALDO,
                SUM(CASE WHEN rp.VENCIMENTO < CURRENT_DATE
                         THEN DATEDIFF(DAY FROM rp.VENCIMENTO TO CURRENT_DATE) ELSE 0 END * 1.0)
                  / NULLIF(COUNT(*),0)                                                       DIAS_MEDIO_ATRASO
            FROM RECEBER_PAGAR rp
            WHERE rp.COD_EMPRESA = {$emp}
              AND rp.SALDO_TITULO > 0
              AND {$cond}
            GROUP BY 1";
            $rows = $this->pdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
            // normaliza dicionário com todas as faixas mesmo se vazias
            $out = [
                'A_VENCER'   => ['QTD'=>0,'SALDO'=>0.0,'DIAS'=>0.0,'label'=>'A vencer'],
                'D_0_15'     => ['QTD'=>0,'SALDO'=>0.0,'DIAS'=>0.0,'label'=>'0–15 dias'],
                'D_16_30'    => ['QTD'=>0,'SALDO'=>0.0,'DIAS'=>0.0,'label'=>'16–30 dias'],
                'D_31_60'    => ['QTD'=>0,'SALDO'=>0.0,'DIAS'=>0.0,'label'=>'31–60 dias'],
                'D_61_MAIS'  => ['QTD'=>0,'SALDO'=>0.0,'DIAS'=>0.0,'label'=>'+60 dias'],
            ];
            foreach ($rows as $r) {
                $k = $r['FAIXA'];
                if (isset($out[$k])) {
                    $out[$k]['QTD']   = (int)$r['QTD'];
                    $out[$k]['SALDO'] = (float)$r['SALDO'];
                    $out[$k]['DIAS']  = (float)($r['DIAS_MEDIO_ATRASO'] ?? 0);
                }
            }
            return $out;
        });
    }

    /** Top conveniados via FORMAS DE PAGTO tipo convênio (Grancard/VR/Alelo/...).
     *  Pra clientes (Importados) que NÃO usam tabela CONVENIOS formal. */
    public function topConveniadosFormas(string $dataIni, string $dataFim, int $limite = 30): array
    {
        $emp = $this->empresa();
        $ttl = ($dataFim >= date('Y-m-d')) ? 60 : 1800;
        return Cache::lembrar("conv_top_formas_{$dataIni}_{$dataFim}_{$emp}_{$limite}", $ttl, function () use ($emp, $dataIni, $dataFim, $limite) {
            // 1) Descobre quais formas-tipo-convenio existem na empresa
            $sqlForm = "SELECT DISTINCT fn.COD_FORMA_PGTO,
                              (SELECT FIRST 1 TRIM(fp.DESCRICAO) FROM FORMA_PGTO fp WHERE fp.COD_FORMA_PGTO = fn.COD_FORMA_PGTO AND TRIM(COALESCE(fp.DESCRICAO,'')) <> '') DESCR
                       FROM FORMAS_NOTAS fn
                       WHERE fn.COD_EMPRESA = {$emp}
                         AND fn.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'";
            $formas = [];
            try {
                foreach ($this->pdo->query($sqlForm) as $r) {
                    $descr = (string)($r['DESCR'] ?? '');
                    if ($this->ehFormaTipoConvenio($descr)) {
                        $formas[(string)$r['COD_FORMA_PGTO']] = $this->utf8($descr);
                    }
                }
            } catch (\Throwable) { return []; }
            if (!$formas) return [];

            $inFormas = "'" . implode("','", array_map(fn($k) => str_replace("'","''",$k), array_keys($formas))) . "'";

            // 2) Top pessoas usando essas formas no periodo
            $sql = "SELECT FIRST {$limite}
                p.COD_PESSOA,
                p.NOME,
                p.FONE_PRINC,
                fn.COD_FORMA_PGTO,
                COUNT(DISTINCT fn.NR_NOTA)              QTD_COMPRAS,
                SUM(fn.VALOR)                           TOTAL_COMPRADO,
                MAX(fn.DATA_EMISSAO)                    ULTIMA_COMPRA
            FROM FORMAS_NOTAS fn
            JOIN NOTAS_CAB nc ON nc.NR_NOTA = fn.NR_NOTA
                              AND nc.COD_EMPRESA = fn.COD_EMPRESA
                              AND nc.COD_TIPO_OPERACAO = fn.COD_TIPO_OPERACAO
            JOIN PESSOAS p ON nc.COD_PESSOA = p.COD_PESSOA
            WHERE fn.COD_EMPRESA = {$emp}
              AND fn.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'
              AND fn.COD_FORMA_PGTO IN ({$inFormas})
              AND nc.COD_PESSOA IS NOT NULL
            GROUP BY p.COD_PESSOA, p.NOME, p.FONE_PRINC, fn.COD_FORMA_PGTO
            ORDER BY TOTAL_COMPRADO DESC";

            $rows = [];
            try { $rows = $this->pdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC); }
            catch (\Throwable) { return []; }

            // 3) Saldo em aberto por pessoa+forma (consulta secundaria)
            foreach ($rows as &$r) {
                $cod = (string)$r['COD_FORMA_PGTO'];
                try {
                    $st = $this->pdo->prepare("
                        SELECT COALESCE(SUM(rp.SALDO_TITULO),0) S
                        FROM RECEBER_PAGAR rp
                        JOIN FORMAS_NOTAS fn ON rp.NR_NOTA = fn.NR_NOTA
                                             AND rp.COD_EMPRESA = fn.COD_EMPRESA
                                             AND rp.SEQ_FORMA_NOTAS = fn.SEQ_FORMA_NOTAS
                        WHERE fn.COD_EMPRESA = ? AND fn.COD_FORMA_PGTO = ?
                          AND rp.COD_PESSOA = ? AND rp.SALDO_TITULO > 0
                    ");
                    $st->execute([$emp, $cod, $r['COD_PESSOA']]);
                    $r['TOTAL_EM_ABERTO'] = (float)$st->fetchColumn();
                } catch (\Throwable) { $r['TOTAL_EM_ABERTO'] = 0.0; }
                $r['NOME']     = $this->utf8($r['NOME'] ?? '');
                $r['CONVENIO'] = $formas[$cod] ?? ('Forma ' . $cod);
            }
            return $rows;
        });
    }

    /** Top conveniados (pessoas que mais consumiram via convênio no período). */
    public function topConveniados(string $dataIni, string $dataFim, int $limite = 30): array
    {
        $emp = $this->empresa();
        $ttl = ($dataFim >= date('Y-m-d')) ? 60 : 1800;
        return Cache::lembrar("conv_top_{$dataIni}_{$dataFim}_{$emp}_{$limite}", $ttl, function () use ($emp, $dataIni, $dataFim, $limite) {
            $sql = "SELECT FIRST {$limite}
                p.COD_PESSOA,
                p.NOME,
                p.FONE_PRINC,
                COALESCE(cv.APELIDO, pc.DESCRICAO) CONVENIO,
                COUNT(rp.PARCELA)                  QTD_COMPRAS,
                SUM(rp.VALOR_TITULO)               TOTAL_COMPRADO,
                SUM(rp.SALDO_TITULO)               TOTAL_EM_ABERTO,
                MAX(rp.DATA_EMISSAO)               ULTIMA_COMPRA
            FROM RECEBER_PAGAR rp
            JOIN PESSOAS p     ON rp.COD_PESSOA   = p.COD_PESSOA
            JOIN CONVENIOS cv  ON rp.COD_CONVENIO = cv.COD_CONVENIO AND cv.COD_EMPRESA = rp.COD_EMPRESA
            LEFT JOIN PESSOAS_CONVENIOS pc ON pc.COD_PESSOA = p.COD_PESSOA AND pc.COD_CONVENIO = cv.COD_CONVENIO
            WHERE rp.COD_EMPRESA = {$emp}
              AND rp.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'
            GROUP BY p.COD_PESSOA, p.NOME, p.FONE_PRINC, COALESCE(cv.APELIDO, pc.DESCRICAO)
            ORDER BY TOTAL_COMPRADO DESC";
            $rows = $this->pdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC);
            foreach ($rows as &$r) {
                $r['NOME']     = $this->utf8($r['NOME'] ?? '');
                $r['CONVENIO'] = $this->utf8($r['CONVENIO'] ?? '—');
            }
            return $rows;
        });
    }

    /** Existe pelo menos 1 convênio cadastrado? (para esconder menu se segmento não usa). */
    public function temConvenios(): bool
    {
        $emp = $this->empresa();
        try {
            $r = $this->pdo->query("SELECT COUNT(*) C FROM CONVENIOS WHERE COD_EMPRESA = {$emp}")->fetch();
            return ((int)($r['C'] ?? 0)) > 0;
        } catch (\Throwable) { return false; }
    }

    /** Formas de pagamento "tipo convenio" (Grancard, VR, Alelo, Sodexo, Ticket, etc).
     *  Detecta por heuristica no nome da FORMA_PGTO + olha vendas reais em FORMAS_NOTAS.
     *  Saldo aberto vem de RECEBER_PAGAR via JOIN nota+seq_forma_notas.
     *  Util quando o ERP nao usa o modulo CONVENIOS formal (tabela CONVENIOS vazia). */
    public function formasConvenio(string $dataIni, string $dataFim): array
    {
        $emp = $this->empresa();
        $ttl = ($dataFim >= date('Y-m-d')) ? 60 : 1800;
        return Cache::lembrar("conv_formas_{$dataIni}_{$dataFim}_{$emp}", $ttl, function () use ($emp, $dataIni, $dataFim) {
            // 1) Quais formas de pgto foram USADAS na empresa no periodo (ou historicamente)?
            //    Pega descricao em QUALQUER empresa (Grancard pode estar cadastrada em outra emp mas usada na atual).
            $sql = "SELECT fn.COD_FORMA_PGTO,
                           (SELECT FIRST 1 TRIM(fp.DESCRICAO) FROM FORMA_PGTO fp WHERE fp.COD_FORMA_PGTO = fn.COD_FORMA_PGTO AND TRIM(COALESCE(fp.DESCRICAO,'')) <> '') DESCR,
                           COUNT(DISTINCT fn.NR_NOTA) Q,
                           COALESCE(SUM(fn.VALOR), 0)     VENDIDO_PERIODO
                    FROM FORMAS_NOTAS fn
                    WHERE fn.COD_EMPRESA = {$emp}
                      AND fn.DATA_EMISSAO BETWEEN '{$dataIni}' AND '{$dataFim}'
                    GROUP BY fn.COD_FORMA_PGTO";

            $rows = [];
            try { $rows = $this->pdo->query($sql)->fetchAll(\PDO::FETCH_ASSOC); }
            catch (\Throwable) { return []; }

            // 2) Filtra so as "tipo convenio" — heuristica: nome bate com palavras-chave OU codigo
            //    em lista do config (cliente pode forcar codigos via config/database.php['formas_convenio']).
            $cfg = $this->configCliente();
            $forcadas = array_map('strval', (array)($cfg['formas_convenio'] ?? []));
            $out = [];
            foreach ($rows as $r) {
                $cod   = (string)($r['COD_FORMA_PGTO'] ?? '');
                $descr = $this->utf8($r['DESCR'] ?? '');
                if ($cod === '') continue;
                $bate = ($forcadas && in_array($cod, $forcadas, true)) || $this->ehFormaTipoConvenio($descr);
                if (!$bate) continue;

                // saldo aberto + vencido (via JOIN RECEBER_PAGAR x FORMAS_NOTAS)
                $aberto = 0.0; $vencido = 0.0; $qtdAberto = 0; $qtdVencido = 0;
                try {
                    $st = $this->pdo->prepare("
                        SELECT COUNT(*) Q,
                               COALESCE(SUM(rp.SALDO_TITULO),0) S,
                               COUNT(CASE WHEN rp.VENCIMENTO < CURRENT_DATE THEN 1 END) QV,
                               COALESCE(SUM(CASE WHEN rp.VENCIMENTO < CURRENT_DATE THEN rp.SALDO_TITULO ELSE 0 END),0) V
                        FROM RECEBER_PAGAR rp
                        JOIN FORMAS_NOTAS fn ON rp.NR_NOTA = fn.NR_NOTA
                                              AND rp.COD_EMPRESA = fn.COD_EMPRESA
                                              AND rp.SEQ_FORMA_NOTAS = fn.SEQ_FORMA_NOTAS
                        WHERE fn.COD_EMPRESA = ?
                          AND fn.COD_FORMA_PGTO = ?
                          AND rp.SALDO_TITULO > 0
                    ");
                    $st->execute([$emp, $cod]);
                    $r2 = $st->fetch(\PDO::FETCH_ASSOC) ?: [];
                    $qtdAberto  = (int)($r2['Q']  ?? 0);
                    $aberto     = (float)($r2['S']  ?? 0);
                    $qtdVencido = (int)($r2['QV'] ?? 0);
                    $vencido    = (float)($r2['V']  ?? 0);
                } catch (\Throwable) { /* JOIN pode falhar em algum ERP — segue com 0 */ }

                $vendido = (float)$r['VENDIDO_PERIODO'];
                $recebido = max(0.0, $vendido - $aberto);
                $out[] = [
                    'COD_CONVENIO'        => 'F'.$cod,           // prefixo F = forma de pgto
                    'NOME'                => $descr !== '' ? $descr : ('Forma '.$cod),
                    'RAZAO'               => 'Forma de pagamento ' . $cod,
                    'ATIVO'               => 'S',
                    'DESCONTO'            => 0,
                    'VENDIDO_PERIODO'     => $vendido,
                    'RECEBIDO_PERIODO'    => $recebido,
                    'SALDO_TOTAL_ABERTO'  => $aberto,
                    'SALDO_VENCIDO'       => $vencido,
                    'QTD_NOTAS'           => (int)$r['Q'],
                    'QTD_TITULOS_ABERTOS' => $qtdAberto,
                    'QTD_TITULOS_VENCIDOS'=> $qtdVencido,
                    'ORIGEM'              => 'forma_pgto',
                ];
            }
            usort($out, fn($a,$b) => $b['VENDIDO_PERIODO'] <=> $a['VENDIDO_PERIODO']);
            return $out;
        });
    }

    /** Helper interno — le config/database.php pra overrides do cliente. */
    private function configCliente(): array
    {
        static $cache = null;
        if ($cache !== null) return $cache;
        $path = dirname(__DIR__, 2) . '/config/database.php';
        $cache = file_exists($path) ? (array)(@include $path) : [];
        return $cache;
    }

    /** Classifica se uma descrição de FORMA_PGTO é "convênio" (Grancard/Alelo/Sodexo/Ticket/VR-ref/Vale-ref/Convênio).
     *  Exclui explicitamente: TROCA VALE, CREDITO LOJA, DEVOLUÇÃO. Cliente pode forçar inclusão via
     *  'formas_convenio' => ['06','XX'] no config/database.php OU lista personalizada via 'kw_convenio' / 'kw_nao_convenio'. */
    public function ehFormaTipoConvenio(string $descricao): bool
    {
        $up = strtoupper(trim($descricao));
        if ($up === '') return false;
        $cfg = $this->configCliente();
        $neg = (array)($cfg['kw_nao_convenio'] ?? ['TROCA','CREDITO LOJA','DEVOLU','VALE PRESENTE','GIFT']);
        foreach ($neg as $k) { if (str_contains($up, strtoupper((string)$k))) return false; }
        $pos = (array)($cfg['kw_convenio'] ?? [
            'GRANCARD','GRAN CARD',
            'ALELO','SODEX','SODEXO',
            'TICKET',
            'VR REFEI','VR-REFEI','VRREFEI',
            'VALE-REFEI','VALE REFEI','VALEREF',
            'VALE-ALIM','VALE ALIM','VALEALIM',
            'CONVEN','CONVENIO',
            'FLASH','PLUXEE','BEN VISA','BEN PASS',
            'TRR','BANRICOMPRAS',
        ]);
        foreach ($pos as $k) { if (str_contains($up, strtoupper((string)$k))) return true; }
        return false;
    }
}
