<?php
defined('BASEPATH') or exit('No direct script access allowed');

class API_model extends CI_Model
{


    public function __construct()
    {
        parent::__construct();
    }

    public function getDadosCliente($cpfCnpj)
    {
        $this->load->database();

        $cpf_cnpj_mascarado = $this->formatarDocumento($cpfCnpj);

        $query = $this->db->query('SELECT
                                        *
                                    FROM
                                        integracao.VIEW_PEDIDOS_MARKETPLACE vpm 
                                    WHERE
                                        vpm.CPF_CNPJ = ?', array($cpf_cnpj_mascarado));

        return $query->result_array();
    }


    private function formatarDocumento($documento)
    {
        $numeroLimpo = preg_replace('/\D/', '', $documento);

        if (strlen($numeroLimpo) === 11) {
            return preg_replace("/(\d{3})(\d{3})(\d{3})(\d{2})/", "\$1.\$2.\$3-\$4", $numeroLimpo);
        } elseif (strlen($numeroLimpo) === 14) {
            return preg_replace("/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/", "\$1.\$2.\$3/\$4-\$5", $numeroLimpo);
        } else {
            return 'Documento inválido';
        }
    }



    public function getProdutosJSM($sku, $measureUnit, $codigoEmpresa)
    {

        $parCashs = $this->getParCashCode($codigoEmpresa);

        $retorno = [];
        //$retorno['success'] = false;

        for ($i = 0; $i < sizeof($parCashs); $i++) {
            //$retorno['success'] = true;
            $parCash = $parCashs[$i];

            $cnpj = $parCash['CNPJ'];
            $cnpjLimpo = preg_replace('/\D/', '', $cnpj);
            $diretorio = $parCash['DIRETORIO'];

            $whereSku = "";
            $sqlParams = [];

            if (!is_null($sku) && $sku != 'null') {
                $whereSku = " AND ci.CODIGO = ?";
                $sqlParams[] = $sku;
            }

            $whereMeasureUnit = "";
            if (!is_null($measureUnit) && $measureUnit != "null") {
                $whereMeasureUnit =  " AND cu.UNIDADE = ?";
                $sqlParams[] = $measureUnit;
            }

            $query = $this->db->query("
                                        SELECT 
                                        --TOP(50)
                                            ci.CODIGO as sku,
                                            FORMAT(
                                                CASE
                                                    WHEN ci.DATAULTIMAENTRADA >= ci.DATA_ULTIMA_SAIDA AND ci.DATAULTIMAENTRADA >= ci.DATA_ULTIMA_VENDA THEN ci.DATAULTIMAENTRADA
                                                    WHEN ci.DATA_ULTIMA_SAIDA >= ci.DATAULTIMAENTRADA AND ci.DATA_ULTIMA_SAIDA >= ci.DATA_ULTIMA_VENDA THEN ci.DATA_ULTIMA_SAIDA
                                                    ELSE ci.DATA_ULTIMA_VENDA
                                                END, 
                                                'yyyy-MM-ddTHH:mm:ssZ'
                                            ) AS stockUpdateAt,
                                            ISNULL(ci.COD_BARRAS, ISNULL(bi.COD_BARRA, null)) as ean,
                                            ci.ESTOQUEATUAL as currentStock,
                                            ci.ESTOQUEMINIMO as minStock,
                                            ci.UNIDADE as measureUnitCode,
                                            cu.UNIDADE as measureUnit,
                                            '$cnpjLimpo' as cnpj
                                        FROM
                                            $diretorio.dbo.CAD_IEST ci 
                                        LEFT JOIN dbo.CAD_UNID cu ON(cu.CODIGO= ci.UNIDADE)
                                        LEFT JOIN (
                                            SELECT 
                                                COD_PROD,
                                                COD_BARRAS as COD_BARRA,
                                                QTDE_EMB,
                                                ROW_NUMBER() OVER (PARTITION BY COD_PROD ORDER BY QTDE_EMB ASC) as rn
                                            FROM 
                                                $diretorio.dbo.BARRAS_IEST
                                        ) bi ON bi.COD_PROD = ci.CODIGO AND bi.rn = 1 AND ci.COD_BARRAS IS NULL
                                        WHERE 
                                            ci.ATIVO = 'S'
                                            $whereSku
                                            $whereMeasureUnit
            ", $sqlParams);
            $products = $query->result_array();

            //$retorno = $products;
            //$retorno['resultCount'] = sizeof($products);
            //$retorno['companies'][] = $parCash;
            //$retorno['products'] = $products;

            for ($p = 0; $p < sizeof($products); $p++) {
                $produto = $products[$p];

                $retorno[] = [
                    'company' => $parCash['NOME_FANTASIA'],
                    'stockUpdateAt' => $produto['stockUpdateAt'],
                    'ean' => $produto['ean'],
                    'sku' => $produto['sku'],
                    'cnpj' => $produto['cnpj'],
                    'currentStock' => $produto['currentStock'],
                    'minStock' => $produto['minStock'],
                    'measureUnit' => $produto['measureUnit']
                ];
            }
        }


        return $retorno;
    }

    /**
     * Retorna unidades de medida a partir da tabela dbo.CAD_UNID.
     * Pode retornar todas as unidades ou filtrar por código e/ou sigla da unidade.
     *
     * @param int|null $codigo   Código da unidade (ex: 1)
     * @param string|null $unidade Sigla da unidade (ex: 'UN', 'PC')
     * @return array Lista de unidades encontradas
     */
    public function getUnidadesDeMedida($codigo = null, $unidade = null)
    {
        $this->load->database();

        $sql = "SELECT cu.CODIGO, cu.UNIDADE FROM dbo.CAD_UNID cu";
        $where = [];
        $params = [];

        if (!is_null($codigo) && $codigo !== '' && $codigo !== 'null') {
            $where[] = 'cu.CODIGO = ?';
            $params[] = (int) $codigo;
        }

        if (!is_null($unidade) && $unidade !== '' && $unidade !== 'null') {
            $where[] = 'cu.UNIDADE = ?';
            $params[] = strtoupper(trim($unidade));
        }

        if (!empty($where)) {
            $sql .= ' WHERE ' . implode(' AND ', $where);
        }

        $sql .= ' ORDER BY cu.UNIDADE ASC, cu.CODIGO ASC';

        $query = $this->db->query($sql, $params);
        return $query->result_array();
    }

    public function getParCash($cashwin)
    {
        $this->load->database();
        $query = $this->db->query("
                                    SELECT 
                                        pc.CODIGO ,
                                        pc.RAZAO_SOCIAL ,
                                        pc.NOME_FANTASIA ,
                                        pc.CNPJ ,
                                        pc.DIRETORIO
                                    FROM
                                        dbo.PAR_CASH pc 
                                    WHERE
                                        pc.ATIVO  = 'S' AND pc.DIRETORIO = ?", [$cashwin]);

        return $query->result_array();
    }

    public function getParCashCode($empresaCode)
    {
        $this->load->database();
        $query = $this->db->query("
                                    SELECT 
                                        pc.CODIGO ,
                                        pc.RAZAO_SOCIAL ,
                                        pc.NOME_FANTASIA ,
                                        pc.CNPJ ,
                                        pc.DIRETORIO,
                                        pc.PROD_DESC_FIXO_VENDA, 
                                        pc.COD_PROD_SUFRAMA
                                    FROM
                                        dbo.PAR_CASH pc 
                                    WHERE
                                        pc.ATIVO  = 'S' AND pc.CODIGO = ?", [$empresaCode]);

        return $query->result_array();
    }

    public function getVendasJSM($codigoVenda, $page, $limit, $date, $tipo_pedido, $dateStart, $dateEnd, $codigoEmpresa)
    {
        $this->load->database();
        $parCashs = $this->getParCashCode($codigoEmpresa);

        // Validar e ajustar parâmetros de paginação

        if ($limit > 50) {
            $limit = 50;
        } else if ($limit < 5) {
            $limit = 5;
        }

        $offset = ($page - 1) * $limit;

        foreach ($parCashs as $parCash) {
            $totalValorDevolucao = 0.0;
            $cnpj = $parCash['CNPJ'];
            $cnpjLimpo = preg_replace('/\D/', '', $cnpj);
            $diretorio = $parCash['DIRETORIO'];
            $NOME_FANTASIA = $parCash['NOME_FANTASIA'];


            $dateCondition = '';
            if (!empty($date)) {
                // Verifique se a data está no formato 'yyyy-mm-dd'
                if (preg_match('/^\d{4}-\d{2}-\d{2}$/', $date)) {

                    $dateParts = explode('-', $date);
                    $year = $dateParts[0];
                    $month = $dateParts[1];
                    $day = $dateParts[2];

                    if (checkdate($month, $day, $year)) {
                        $dateCondition = "AND CAST(v.DATA_VENDA as DATE) = CAST('$date' as DATE)";
                    } else {
                        return [
                            'error' => true,
                            'message' => 'data invalida (YYYY-MM-DD)'
                        ];
                    }
                } else {
                    return [
                        'error' => true,
                        'message' => 'data invalida (YYYY-MM-DD)'
                    ];
                }
            }

            $periodoCondition = '';
            if (!empty($dateStart) && !empty($dateEnd)) {
                // Verifique se as datas estão no formato 'yyyy-mm-dd'
                if (
                    preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateStart) &&
                    preg_match('/^\d{4}-\d{2}-\d{2}$/', $dateEnd)
                ) {
                    $startParts = explode('-', $dateStart);
                    $endParts = explode('-', $dateEnd);

                    if (checkdate($startParts[1], $startParts[2], $startParts[0]) && checkdate($endParts[1], $endParts[2], $endParts[0])) {
                        $periodoCondition = " AND CAST(v.DATA_VENDA as DATE) BETWEEN CAST('$dateStart' as DATE) AND CAST('$dateEnd' as DATE)";
                    } else {
                        return [
                            'error' => true,
                            'message' => 'data invalida (YYYY-MM-DD)'
                        ];
                    }
                } else {
                    return [
                        'error' => true,
                        'message' => 'data invalida (YYYY-MM-DD)'
                    ];
                }
            }

            $tipo_pedidoCondition = '';
            if (!empty($tipo_pedido)) {

                if ($tipo_pedido == 'pedido') {
                    $tipo_pedidoCondition = " AND v.DATA_FECHAMENTO IS NOT NULL AND v.DATA_FECHAMENTO <> '' ";
                } else if ($tipo_pedido == 'orcamento') {
                    $tipo_pedidoCondition = " AND (v.DATA_FECHAMENTO IS NULL OR v.DATA_FECHAMENTO = '') ";
                }
            }

            $totalVendaCondition = ' AND v.TOTAL_VENDA > 0 ';
            $codigoVendaCondition = '';
            if (!empty($codigoVenda) && is_numeric($codigoVenda)) {
                $codigoVendaCondition = " AND v.COD_VENDA = $codigoVenda";
                $totalVendaCondition = '';
            }

            // Contagem total de itens
            $totalQuery = $this->db->query("
                SELECT COUNT(*) as total 
                FROM $diretorio.dbo.VENDA v 
                INNER JOIN $diretorio.dbo.ITENSVEN i ON(i.COD_VENDA = v.COD_VENDA)
                INNER JOIN $diretorio.dbo.CAD_IEST ci ON(ci.CODIGO = i.COD_PROD)
                INNER JOIN dbo.CAD_VEND cv ON(cv.CODIGO = v.COD_VENDEDOR)
                INNER JOIN dbo.CAD_USUA usr ON(usr.VENDEDOR = cv.CODIGO)
                INNER JOIN dbo.CAD_CLIE cc ON(cc.CODIGO = v.COD_CLIENTE)
                INNER JOIN dbo.CAD_UNID cu ON(cu.CODIGO= ci.UNIDADE)
                INNER JOIN $diretorio.dbo.CAD_GRUP cg ON(cg.CODIGO = ci.GRUPO)
                INNER JOIN $diretorio.dbo.SUBGRUPO sg ON(sg.CODIGO = ci.SUBGRUPO)
                LEFT JOIN dbo.CAD_FORN cf ON(cf.CODIGO = ci.FORNECEDOR)
                LEFT JOIN (
                    SELECT 
                        COD_PROD,
                        COD_BARRAS as COD_BARRA,
                        QTDE_EMB,
                        ROW_NUMBER() OVER (PARTITION BY COD_PROD ORDER BY QTDE_EMB ASC) as rn
                    FROM 
                        $diretorio.dbo.BARRAS_IEST
                ) bi ON bi.COD_PROD = ci.CODIGO AND bi.rn = 1 AND ci.COD_BARRAS IS NULL
                WHERE 
                    v.DATA_VENDA >= DATEADD(day, -365, GETDATE())
                AND
                    v.COD_CLIENTE != 1
                AND
                    i.QUANTIDADE > 0
                $totalVendaCondition
                $dateCondition  
                $tipo_pedidoCondition   
                $periodoCondition   
                $codigoVendaCondition
            ");
            $total = $totalQuery->row()->total;

            // Consulta com paginação
            $query = $this->db->query("

                DECLARE @DataInicial DATETIME = DATEADD(DAY, -365, GETDATE());

                SELECT 
                    --CAMPOS DA TABELA VENDA
                    v.COD_VENDA as number_identifier,
                    CONVERT(varchar(25), v.DATA_HORA_VENDA, 126) + 'Z' AS purchase_date,
                    v.TOTAL_VENDA as total_price,
                    v.VALOR_DESC as total_price_descont,
                    (v.TOTAL_VENDA - v.VALOR_DESC) as total_descont,
                    '$cnpjLimpo' as store_cnpj,
                    usr.APELIDO as seller_identifier,
                    cv.CPF as seller_cpf,
                    usr.EMAIL_USUARIO as seller_email,
                    cv.CELULAR as seller_phone,
                    null as operator_identifier,
                    null as operator_cpf,
                    CASE cc.NATUREZA
                        WHEN 'F' THEN cc.CPF
                        WHEN 'J' THEN cc.CGC
                        ELSE 'Documento Invalido'
                    END as customer_document,
                    cc.NOME_FANTASIA as customer_identifier,
                    cc.EMAIL as customer_email,
                    cc.TELEFONE as customer_telefone,
                    cc.CELULAR as customer_celular,
                    cc.FAX as customer_telefone_outros,
                    ci.CODIGO as sku,
                    COALESCE(ci.COD_BARRAS, bi.COD_BARRAS) AS ean,
                    ci.DESCRICAO as description,
                    i.QUANTIDADE as quantity,
                    i.VALOR_UNIT as unit_price,
                    cu.UNIDADE as measureUnit,
                    NULL AS value_measureUnit,
                    cg.DESCRICAO as category,
                    sg.DESCRICAO as subcategory,
                    cf.NOME_FANTASIA as supplier,
                    cf.NOME_FANTASIA as supplier_submark,
                    v.DATA_FECHAMENTO,
					SUBSTRING(CONVERT(VARCHAR, n.DATADEEMISSAO, 121), 1, 11) as dataEmissaoNF,
					SUBSTRING(CONVERT(VARCHAR, n.HORA_EMISSAO, 121), 11, 13) as horaEmissaoNF,
					SUBSTRING(CONVERT(VARCHAR, n.DATADEEMISSAO, 121), 1, 10) + ' ' + SUBSTRING(CONVERT(VARCHAR, n.HORA_EMISSAO, 121), 12, 12) as dataHoraEmissaoNF,
                    CASE 
                        WHEN v.DATA_FECHAMENTO IS NULL THEN 'orcamento'
                        WHEN v.DATA_FECHAMENTO IS NOT NULL AND n.DATADEEMISSAO IS NOT NULL THEN 'pedido faturado'
                        WHEN v.DATA_FECHAMENTO IS NOT NULL THEN 'pedido'
                        ELSE 'orcamento'
                    END AS tipo_pedido
                FROM
                    $diretorio.dbo.VENDA v 
                INNER JOIN $diretorio.dbo.ITENSVEN i ON(i.COD_VENDA = v.COD_VENDA)
                INNER JOIN $diretorio.dbo.CAD_IEST ci ON(ci.CODIGO = i.COD_PROD)
                INNER JOIN dbo.CAD_VEND cv ON(cv.CODIGO = v.COD_VENDEDOR)
                INNER JOIN dbo.CAD_USUA usr ON(usr.VENDEDOR = cv.CODIGO)
                INNER JOIN dbo.CAD_CLIE cc ON(cc.CODIGO = v.COD_CLIENTE)
                INNER JOIN dbo.CAD_UNID cu ON(cu.CODIGO= ci.UNIDADE)
                INNER JOIN $diretorio.dbo.CAD_GRUP cg ON(cg.CODIGO = ci.GRUPO)
                INNER JOIN $diretorio.dbo.SUBGRUPO sg ON(sg.CODIGO = ci.SUBGRUPO)
                LEFT JOIN dbo.CAD_FORN cf ON(cf.CODIGO = ci.FORNECEDOR)
                LEFT JOIN $diretorio.dbo.NOTAF2 n ON(n.NDAVENDA = v.COD_VENDA )
                OUTER APPLY (
                    SELECT TOP 1 b.COD_BARRAS
                    FROM CASHWIN_ELETRO_LDB.dbo.BARRAS_IEST b
                    WHERE b.COD_PROD = ci.CODIGO
                    ORDER BY b.QTDE_EMB ASC
                ) bi
                WHERE 
                    v.DATA_VENDA >= @DataInicial
                AND
                    v.COD_CLIENTE != 1
                AND
                    i.QUANTIDADE > 0
                 $totalVendaCondition
                 $dateCondition 
                 $tipo_pedidoCondition  
                 $periodoCondition  
                 $codigoVendaCondition
                ORDER BY v.COD_VENDA DESC
                OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY
            ");


            $retornos = $query->result_array();

            foreach ($retornos as &$row) {
                $seller_cpf = preg_replace('/\D/', '', $row['seller_cpf']);
                $customer_document = preg_replace('/\D/', '', $row['customer_document']);
                $customer_telefone = preg_replace('/\D/', '', $row['customer_telefone']);
                $seller_phone = preg_replace('/\D/', '', $row['seller_phone']);

                $row['seller_cpf'] = $seller_cpf;
                $row['customer_document'] = $customer_document;
                $row['company'] = $NOME_FANTASIA;
                $row['customer_telefone'] = $customer_telefone;
                $row['seller_phone'] = $seller_phone;
            }

            // Calcular número total de páginas
            $pageCount = ceil($total / $limit);

            return [
                'page' => $page,
                'pageSize' => $limit,
                'pageCount' => $pageCount,
                'total' => $total,
                'results' => $retornos
            ];
        }

        return [
            'page' => $page,
            'pageSize' => $limit,
            'pageCount' => 0,
            'total' => 0,
            'results' => []
        ];
    }


    public function getVendasPKR($codigoVenda, $codigoEmpresa)
    {
        $this->load->database();

        if (empty($codigoVenda) || empty($codigoEmpresa)) {
            return [
                'page' => 1,
                'pageSize' => 0,
                'pageCount' => 0,
                'total' => 0,
                'results' => []
            ];
        }

        $parCashs = $this->getParCashCode($codigoEmpresa);

        foreach ($parCashs as $parCash) {
            $totalValorDevolucao = 0.0;
            $cnpj = $parCash['CNPJ'];
            $cnpjLimpo = preg_replace('/\D/', '', $cnpj);
            $diretorio = $parCash['DIRETORIO'];
            $NOME_FANTASIA = $parCash['NOME_FANTASIA'];
            $prodDescFixo = isset($parCash['PROD_DESC_FIXO_VENDA']) ? $parCash['PROD_DESC_FIXO_VENDA'] : null;
            $prodSuframa = isset($parCash['COD_PROD_SUFRAMA']) ? $parCash['COD_PROD_SUFRAMA'] : null;

            $productExclusion = '';
            $queryParams = [$codigoVenda];

            if (!empty($prodDescFixo)) {
                $productExclusion .= ' AND ci.CODIGO <> ?';
                $queryParams[] = $prodDescFixo;
            }

            if (!empty($prodSuframa)) {
                $productExclusion .= ' AND ci.CODIGO <> ?';
                $queryParams[] = $prodSuframa;
            }

            $query = $this->db->query(" 
                SELECT 
                    v.COD_VENDA as number_identifier,
                    CONVERT(varchar(25), v.DATA_HORA_VENDA, 126) + 'Z' AS purchase_date,
                    v.TOTAL_VENDA as total_price,
                    v.VALOR_DESC as total_price_descont,
                    (v.TOTAL_VENDA - v.VALOR_DESC) as total_descont,
                    '$cnpjLimpo' as store_cnpj,
                    usr.APELIDO as seller_identifier,
                    cv.CPF as seller_cpf,
                    usr.EMAIL_USUARIO as seller_email,
                    cv.CELULAR as seller_phone,
                    null as operator_identifier,
                    null as operator_cpf,
                    CASE cc.NATUREZA
                        WHEN 'F' THEN cc.CPF
                        WHEN 'J' THEN cc.CGC
                        ELSE 'Documento Invalido'
                    END as customer_document,
                    cc.CODIGO as customer_code,
                    cc.NOME_FANTASIA as customer_identifier,
                    cc.EMAIL as customer_email,
                    cc.TELEFONE as customer_telefone,
                    cc.CELULAR as customer_celular,
                    cc.FAX as customer_telefone_outros,
                    ci.CODIGO as sku,
                    COALESCE(ci.COD_BARRAS, bi.COD_BARRAS) AS ean,
                    ci.DESCRICAO as description,
                    i.QUANTIDADE as quantity,
                    i.VALOR_UNIT as unit_price,
                    cu.UNIDADE as measureUnit,
                    NULL AS value_measureUnit,
                    cg.DESCRICAO as category,
                    sg.DESCRICAO as subcategory,
                    cf.NOME_FANTASIA as supplier,
                    cf.NOME_FANTASIA as supplier_submark,
                    v.DATA_FECHAMENTO,
                    SUBSTRING(CONVERT(VARCHAR, n.DATADEEMISSAO, 121), 1, 11) as dataEmissaoNF,
                    SUBSTRING(CONVERT(VARCHAR, n.HORA_EMISSAO, 121), 11, 13) as horaEmissaoNF,
                    SUBSTRING(CONVERT(VARCHAR, n.DATADEEMISSAO, 121), 1, 10) + ' ' + SUBSTRING(CONVERT(VARCHAR, n.HORA_EMISSAO, 121), 12, 12) as dataHoraEmissaoNF,
                    CASE 
                        WHEN v.DATA_FECHAMENTO IS NULL THEN 'orcamento'
                        WHEN v.DATA_FECHAMENTO IS NOT NULL AND n.DATADEEMISSAO IS NOT NULL THEN 'pedido faturado'
                        WHEN v.DATA_FECHAMENTO IS NOT NULL THEN 'pedido'
                        ELSE 'orcamento'
                    END AS tipo_pedido,
                    cv2.CODIGO as VENDEDOR_EXTERNO_COD,
                    cv2.NOME as VENDEDOR_EXTERNO_NOME,
                    cv3.CODIGO as VENDEDOR_SUPERVISOR_COD,
                    cv3.NOME as VENDEDOR_SUPERVISOR_NOME
                FROM
                    $diretorio.dbo.VENDA v 
                INNER JOIN $diretorio.dbo.ITENSVEN i ON(i.COD_VENDA = v.COD_VENDA)
                INNER JOIN $diretorio.dbo.CAD_IEST ci ON(ci.CODIGO = i.COD_PROD)
                INNER JOIN dbo.CAD_VEND cv ON(cv.CODIGO = v.COD_VENDEDOR)
                INNER JOIN dbo.CAD_USUA usr ON(usr.VENDEDOR = cv.CODIGO)
                LEFT JOIN dbo.CAD_VEND cv2 ON(cv2.CODIGO = v.COD_VENDEDOR_EXT)
                LEFT JOIN dbo.CAD_VEND cv3 ON(cv3.CODIGO = v.VENDEDOR_SUPERVISOR)
                INNER JOIN dbo.CAD_CLIE cc ON(cc.CODIGO = v.COD_CLIENTE)
                INNER JOIN dbo.CAD_UNID cu ON(cu.CODIGO= ci.UNIDADE)
                INNER JOIN $diretorio.dbo.CAD_GRUP cg ON(cg.CODIGO = ci.GRUPO)
                INNER JOIN $diretorio.dbo.SUBGRUPO sg ON(sg.CODIGO = ci.SUBGRUPO)
                LEFT JOIN dbo.CAD_FORN cf ON(cf.CODIGO = ci.FORNECEDOR)
                LEFT JOIN $diretorio.dbo.NOTAF2 n ON(n.NDAVENDA = v.COD_VENDA )
                OUTER APPLY (
                    SELECT TOP 1 b.COD_BARRAS
                    FROM CASHWIN_ELETRO_LDB.dbo.BARRAS_IEST b
                    WHERE b.COD_PROD = ci.CODIGO
                    ORDER BY b.QTDE_EMB ASC
                ) bi
                WHERE 
                    v.COD_VENDA = ?
                AND
                    v.COD_CLIENTE != 1
                $productExclusion
            ", $queryParams);

            $retornos = $query->result_array();
            $totalValorDevolucao = 0.0;

            foreach ($retornos as $retorno) {
                if ((float)$retorno['quantity'] < 0) {
                    $totalValorDevolucao += (float)$retorno['unit_price'] * (float)$retorno['quantity'];
                }
            }

            foreach ($retornos as &$row) {
                $seller_cpf = preg_replace('/\D/', '', $row['seller_cpf']);
                $customer_document = preg_replace('/\D/', '', $row['customer_document']);
                $customer_telefone = preg_replace('/\D/', '', $row['customer_telefone']);
                $seller_phone = preg_replace('/\D/', '', $row['seller_phone']);

                $is_devolucao = false;

                if ($row['quantity'] < 0) {
                    $is_devolucao = true;
                }

                $row['seller_cpf'] = $seller_cpf;
                $row['customer_document'] = $customer_document;
                $row['company'] = $NOME_FANTASIA;
                $row['customer_telefone'] = $customer_telefone;
                $row['seller_phone'] = $seller_phone;
                $row['devolucao'] = $is_devolucao;
                $row['valor_da_devolucao'] = isset($totalValorDevolucao) ? $totalValorDevolucao : 0;
            }
            unset($row);

            $total = count($retornos);

            return [
                'page' => 1,
                'pageSize' => $total,
                'pageCount' => $total > 0 ? 1 : 0,
                'total' => $total,
                'results' => $retornos
            ];
        }

        return [
            'page' => 1,
            'pageSize' => 0,
            'pageCount' => 0,
            'total' => 0,
            'results' => []
        ];
    }


    public function getVendasJSMOREIGINAL($dataVenda, $page, $limit)
    {
        $this->load->database();
        $parCashs = $this->getParCash('CASHWIN_ELETRO_MGA');

        // Validar e ajustar parâmetros de paginação
        $limit = max(5, min(50, $limit)); // Limite mínimo de 5 e máximo de 50
        $offset = ($page - 1) * $limit;


        for ($i = 0; $i < sizeof($parCashs); $i++) {
            //$retorno['success'] = true;
            $parCash = $parCashs[$i];

            $cnpj = $parCash['CNPJ'];
            $cnpjLimpo = preg_replace('/\D/', '', $cnpj);
            $diretorio = $parCash['DIRETORIO'];



            $query = $this->db->query("
                                    SELECT 
                                        --CAMPOS DA TABELA VENDA
                                        v.COD_VENDA as number_identifier,
                                        FORMAT(v.DATA_HORA_VENDA, 'yyyy-MM-ddTHH:mm:ssZ') as purchase_date,
                                        v.TOTAL_VENDA as total_price,
                                        '$cnpjLimpo' as store_cnpj,
                                        usr.APELIDO as seller_identifier,
                                        cv.CPF as seller_cpf,
                                        usr.EMAIL_USUARIO as seller_email,
                                        cv.CELULAR as seller_phone,
                                        null as operator_identifier,
                                        null as operator_cpf,
                                        CASE cc.NATUREZA
                                            WHEN 'F' THEN cc.CPF
                                            WHEN 'J' THEN cc.CGC
                                            ELSE 'Documento Invalido'
                                        END as customer_document,
                                        cc.NOME_FANTASIA as customer_identifier,
                                        ci.CODIGO as sku,
                                        ISNULL(ci.COD_BARRAS, ISNULL(bi.COD_BARRA, null)) as ean,
                                        ci.DESCRICAO as description,
                                        i.QUANTIDADE as quantity,
                                        i.VALOR_UNIT as unit_price,
                                        cu.UNIDADE as measureUnit,
                                        null as value_measureUnit,
                                        cg.DESCRICAO as category,
                                        sg.DESCRICAO as subcategory,
                                        cf.NOME_FANTASIA as supplier,
                                        cf.NOME_FANTASIA as supplier_submark
                                    FROM
                                        $diretorio.dbo.VENDA v 
                                    INNER JOIN $diretorio.dbo.ITENSVEN i ON(i.COD_VENDA = v.COD_VENDA)
                                    INNER JOIN $diretorio.dbo.CAD_IEST ci ON(ci.CODIGO = i.COD_PROD)
                                    INNER JOIN dbo.CAD_VEND cv ON(cv.CODIGO = v.COD_VENDEDOR)
                                    INNER JOIN dbo.CAD_USUA usr ON(usr.VENDEDOR = cv.CODIGO)
                                    INNER JOIN dbo.CAD_CLIE cc ON(cc.CODIGO = v.COD_CLIENTE)
                                    INNER JOIN dbo.CAD_UNID cu ON(cu.CODIGO= ci.UNIDADE)
                                    INNER JOIN $diretorio.dbo.CAD_GRUP cg ON(cg.CODIGO = ci.GRUPO)
                                    INNER JOIN $diretorio.dbo.SUBGRUPO sg ON(sg.CODIGO = ci.SUBGRUPO)
                                    LEFT JOIN dbo.CAD_FORN cf ON(cf.CODIGO = ci.FORNECEDOR)
                                    LEFT JOIN (
                                        SELECT 
                                            COD_PROD,
                                            COD_BARRAS as COD_BARRA,
                                            QTDE_EMB,
                                            ROW_NUMBER() OVER (PARTITION BY COD_PROD ORDER BY QTDE_EMB ASC) as rn
                                        FROM 
                                            $diretorio.dbo.BARRAS_IEST
                                    ) bi ON bi.COD_PROD = ci.CODIGO AND bi.rn = 1 AND ci.COD_BARRAS IS NULL
                                    WHERE 
                                        v.DATA_VENDA >= DATEADD(day, -365, GETDATE())
                                    ORDER BY v.COD_VENDA DESC
                                     OFFSET $offset ROWS FETCH NEXT $limit ROWS ONLY
                                            ");

            $retornos = $query->result_array();

            foreach ($retornos as &$row) {
                $seller_cpf = preg_replace('/\D/', '', $row['seller_cpf']);
                $customer_document = preg_replace('/\D/', '', $row['customer_document']);
                $seller_phone = preg_replace('/\D/', '', $row['custoseller_phonemer_document']);

                $row['seller_cpf'] = $seller_cpf;
                $row['customer_document'] = $customer_document;
                $row['seller_phone'] = $seller_phone;
            }

            return $retornos;
        }

        return [];
    }


    public function getWebhookNaoEnviados()
    {
        $this->load->database();

        // Seleciona apenas o último evento pendente por (empresa, venda)
        $sql = "
            SELECT *
            FROM (
                SELECT 
                    wv.*,
                    ROW_NUMBER() OVER (
                        PARTITION BY wv.codigo_parcash, wv.codigo_venda
                        ORDER BY wv.data_hora_envio DESC, wv.id DESC
                    ) AS rn
                FROM LOG_SISTEMAS.dbo.webhook_vendas wv
                WHERE wv.data_hora_sucesso IS NULL
            ) x
            WHERE x.rn = 1
            ORDER BY x.data_hora_envio ASC
        ";

        $query = $this->db->query($sql);
        $ultimos = $query->result_array();

        $resultado = [];
        foreach ($ultimos as $webhook) {
            $codigo_parcash = $webhook['codigo_parcash'];
            $codigo_venda = $webhook['codigo_venda'];
            $eventType = $webhook['eventType'];
            $url_webhook = $webhook['url_webhook'];
            $codigo_webhook = $webhook['id'];

            $dataCashwin = $this->getCashwinName($codigo_parcash);
            $cashwinName = $dataCashwin[0]['DIRETORIO'];
            $dadosVenda = $this->getVenda($cashwinName, $codigo_venda);

            $frenteCaixa = $dadosVenda[0]['FRENTE_CAIXA'];
            $codCliente = $dadosVenda[0]['COD_CLIENTE'];
            $clientePadrao = $dadosVenda[0]['CLIENTE_PADRAO'];
            $SITUACAO = $dadosVenda[0]['SITUACAO'];
            $VALOR_DESC = floatval($dadosVenda[0]['VALOR_DESC']);

            if ($frenteCaixa == 'S' && $codCliente == $clientePadrao) {
                // Venda realizada no frente de caixa para cliente padrão, não envia webhook
                // Marca o webhook como enviado
                $this->setWebhookSuccess($codigo_venda, $codigo_parcash, $codigo_webhook);

                continue; // Pula para o próximo webhook
            }

            if ($SITUACAO != 'V' && $SITUACAO != 'F') {
                // Venda não está em situação válida para envio de webhook
                // Marca o webhook como enviado
                $this->setWebhookSuccess($codigo_venda, $codigo_parcash, $codigo_webhook);

                continue; // Pula para o próximo webhook
            }

            /*if ($VALOR_DESC <= 0) {
                // Venda com valor pago zerado ou negativo, não envia webhook
                $this->setWebhookSuccess($codigo_venda, $codigo_parcash, $codigo_webhook);
                continue;
            }*/

            $reqWebhook = $this->curlRequest($url_webhook, 'POST', [
                'empresa' => $codigo_parcash,
                'venda' => $codigo_venda,
                'type' => $eventType
            ]);

            $response = $reqWebhook['response'];

            if ($reqWebhook['status'] == 200 || $reqWebhook['status'] == 201) {
                // Marca todos os eventos pendentes desse grupo como enviados
                $this->setWebhookGroupSuccess($codigo_venda, $codigo_parcash, $response);
            }

            $webhook['request'] = $reqWebhook;
            $resultado[] = $webhook;
        }

        return $resultado;
    }

    public function setWebhookSuccess($codVenda, $codEmpresa, $codigo_webhook)
    {
        $this->load->database();

        $sql = "UPDATE LOG_SISTEMAS.dbo.webhook_vendas
                SET data_hora_sucesso = GETDATE()
                WHERE codigo_venda = ?
                  AND codigo_parcash = ?
                  AND id = ?";

        $this->db->query($sql, [$codVenda, $codEmpresa, $codigo_webhook]);

        // Retorna verdadeiro se a consulta afetou alguma linha
        return ($this->db->affected_rows() > 0);
    }

    // Marca todos os eventos pendentes (data_hora_sucesso IS NULL) para a venda/empresa como enviados
    public function setWebhookGroupSuccess($codVenda, $codEmpresa, $response)
    {
        $this->load->database();

        $sql = "UPDATE LOG_SISTEMAS.dbo.webhook_vendas
                SET data_hora_sucesso = GETDATE(),
                    response = ?
                WHERE codigo_venda = ?
                  AND codigo_parcash = ?
                  AND data_hora_sucesso IS NULL";

        $this->db->query($sql, [$response, $codVenda, $codEmpresa]);
        return ($this->db->affected_rows() > 0);
    }

    /**
     * Executa uma requisição HTTP usando cURL.
     * @param string $url URL de destino
     * @param string $method Método HTTP (GET, POST, PUT, DELETE, etc.)
     * @param array|string|null $postBody Corpo da requisição (array para JSON ou string para outros tipos)
     * @param array $headers Headers adicionais (opcional)
     * @return array [status, response, error]
     */
    public function curlRequest($url, $method = 'GET', $postBody = null, $headers = [], $timeout = 15)
    {


        $ch = curl_init();

        curl_setopt_array($ch, array(
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => '',
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 0,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_CUSTOMREQUEST => 'POST',
            CURLOPT_POSTFIELDS => json_encode($postBody),
            CURLOPT_HTTPHEADER => array(
                'Content-Type: application/json'
            ),
        ));


        $response = curl_exec($ch);
        $error = curl_error($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $info = curl_getinfo($ch);



        return [
            'status' => $status,
            'response' => $response,
            'error' => $error,
            'info' => $info,
        ];
    }


    public function getVenda($cashwin, $cod_venda)
    {
        $this->load->database();
        $query = $this->db->query("
                                    select
                                        v.COD_VENDA,
                                        v.COD_CLIENTE ,
                                        v.PAR_EMPRESA ,
                                        v.FRENTE_CAIXA ,
                                        v.SITUACAO,
                                        pc.CLIENTE_PADRAO ,
                                        v.VALOR_DESC
                                    from
                                        $cashwin.dbo.VENDA v 
                                    INNER JOIN dbo.PAR_CASH pc ON(pc.CODIGO = v.PAR_EMPRESA)
                                    where
                                        v.COD_VENDA = ?", [$cod_venda]);

        return $query->result_array();
    }

    public function getCashwinName($par_empresa)
    {
        $this->load->database();
        $query = $this->db->query("
                                    select
                                        pc.CODIGO,
                                        pc.DIRETORIO 
                                    from
                                        dbo.PAR_CASH pc 
                                    where
                                        pc.CODIGO = ?", [$par_empresa]);

        return $query->result_array();
    }
}
