<?php

namespace App\Services;

/**
 * Service Wrapper para integra??o com m?dulo NF-e
 *
 * Encapsula a integra??o com o m?dulo NF-e independente,
 * carregando suas depend?ncias e expondo uma interface limpa.
 */
class NFeIntegrationService
{
    private $nfeService = null;
    private $initialized = false;

    /**
     * Valida se o XML ? realmente procNFe completo e não resNFe
     *
     * @param string $xml Conte?do XML da NF-e
     * @return array ['valido' => bool, 'tipo' => 'procNFe'|'resNFe'|'desconhecido', 'tem_itens' => bool]
     */
    private static function validarTipoXml(string $xml): array
    {
        $resultado = [
            "valido" => false,
            "tipo" => "desconhecido",
            "tem_itens" => false,
        ];

        try {
            $dom = new \DOMDocument();
            if (!$dom->loadXML($xml)) {
                return $resultado;
            }

            // Verificar se ? resNFe - REJEITAR
            $resNFe = $dom->getElementsByTagName("resNFe");
            if ($resNFe->length > 0) {
                $resultado["tipo"] = "resNFe";
                return $resultado; // não ? v?lido, ? resumo
            }

            // Verificar se ? procNFe ou nfeProc
            $procNFe = $dom->getElementsByTagName("procNFe");
            $nfeProc = $dom->getElementsByTagName("nfeProc");
            $nfe = $dom->getElementsByTagName("NFe");

            if (
                $procNFe->length > 0 ||
                $nfeProc->length > 0 ||
                ($nfe->length > 0 && $resNFe->length == 0)
            ) {
                // Verificar se tem itens (det) - essencial para ser XML completo
                $det = $dom->getElementsByTagName("det");
                $temItens = $det->length > 0;

                $resultado["valido"] = true;
                $resultado["tipo"] =
                    $procNFe->length > 0 || $nfeProc->length > 0
                    ? "procNFe"
                    : "NFe";
                $resultado["tem_itens"] = $temItens;
            }
        } catch (\Exception $e) {
            error_log("Erro ao validar tipo de XML: " . $e->getMessage());
        }

        return $resultado;
    }

    /**
     * Extrai dados do destinatário de um XML de NF-e completo
     *
     * @param string $xml Conteúdo XML da NF-e (procNFe/NFe completo)
     * @return array ['cnpj' => '', 'razao_social' => '']
     */
    public static function extrairDadosDestinatario(string $xml): array
    {
        $dados = [
            "cnpj" => "",
            "razao_social" => "",
        ];

        try {
            $dom = new \DOMDocument();
            if (!$dom->loadXML($xml)) {
                return $dados;
            }

            // Namespace padrão da NF-e
            $nfeNs = "http://www.portalfiscal.inf.br/nfe";

            // Buscar dentro de <dest> (destinatário)
            $xpath = new \DOMXPath($dom);
            $xpath->registerNamespace("nfe", $nfeNs);

            $dest = $xpath->query("//nfe:dest | //dest")->item(0);
            if (!$dest) {
                $destNodes = $dom->getElementsByTagName("dest");
                $dest = $destNodes->length > 0 ? $destNodes->item(0) : null;
            }

            if ($dest instanceof \DOMElement) {
                $cnpjDest = $xpath
                    ->query(".//nfe:CNPJ | .//CNPJ", $dest)
                    ->item(0);
                if (!$cnpjDest) {
                    $cnpjNodes = $dest->getElementsByTagName("CNPJ");
                    $cnpjDest =
                        $cnpjNodes->length > 0 ? $cnpjNodes->item(0) : null;
                }

                $cpfDest = $xpath->query(".//nfe:CPF | .//CPF", $dest)->item(0);
                if (!$cpfDest) {
                    $cpfNodes = $dest->getElementsByTagName("CPF");
                    $cpfDest =
                        $cpfNodes->length > 0 ? $cpfNodes->item(0) : null;
                }

                $nomeDest = $xpath
                    ->query(".//nfe:xNome | .//xNome", $dest)
                    ->item(0);
                if (!$nomeDest) {
                    $nomeNodes = $dest->getElementsByTagName("xNome");
                    $nomeDest =
                        $nomeNodes->length > 0 ? $nomeNodes->item(0) : null;
                }

                if ($cnpjDest instanceof \DOMNode) {
                    $dados["cnpj"] = trim($cnpjDest->nodeValue);
                } elseif ($cpfDest instanceof \DOMNode) {
                    $dados["cnpj"] = trim($cpfDest->nodeValue);
                }

                if ($nomeDest instanceof \DOMNode) {
                    $dados["razao_social"] = trim($nomeDest->nodeValue);
                }
            }

            error_log(
                "🔍 Extração de dados do destinatário - CNPJ: '{$dados["cnpj"]}', Razão: '{$dados["razao_social"]}'"
            );
        } catch (\Exception $e) {
            error_log(
                "Erro ao extrair dados do destinatário: " . $e->getMessage()
            );
        }

        return $dados;
    }

    /**
     * Extrai dados do emissor (fornecedor) de um XML de NF-e
     * Funciona tanto com resNFe quanto com XML completo (procNFe/NFe)
     *
     * @param string $xml Conte?do XML da NF-e
     * @return array ['cnpj' => '', 'razao_social' => '']
     */
    public static function extrairDadosEmissor(string $xml): array
    {
        $dados = [
            "cnpj" => "",
            "razao_social" => "",
        ];

        try {
            $dom = new \DOMDocument();
            if (!$dom->loadXML($xml)) {
                return $dados;
            }

            // Namespace padr?o da NF-e
            $nfeNs = "http://www.portalfiscal.inf.br/nfe";

            // Tentar 1: Buscar diretamente no n?vel raiz (resNFe) - com e sem namespace
            $xpath = new \DOMXPath($dom);
            $xpath->registerNamespace("nfe", $nfeNs);

            // Tentar com namespace
            $cnpjNode = $xpath->query("//nfe:CNPJ | //CNPJ")->item(0);
            $cpfNode = $xpath->query("//nfe:CPF | //CPF")->item(0);
            $nomeNode = $xpath->query("//nfe:xNome | //xNome")->item(0);

            // Se não encontrou com XPath, tentar diretamente
            if (!$cnpjNode) {
                $cnpjNode = $dom->getElementsByTagName("CNPJ")->item(0);
            }
            if (!$cpfNode) {
                $cpfNode = $dom->getElementsByTagName("CPF")->item(0);
            }
            if (!$nomeNode) {
                $nomeNode = $dom->getElementsByTagName("xNome")->item(0);
            }

            if ($cnpjNode) {
                $dados["cnpj"] = trim($cnpjNode->nodeValue);
            } elseif ($cpfNode) {
                $dados["cnpj"] = trim($cpfNode->nodeValue);
            }

            if ($nomeNode) {
                $dados["razao_social"] = trim($nomeNode->nodeValue);
            }

            // Tentar 2: Buscar dentro de <emit> (XML completo) - com e sem namespace
            if (empty($dados["cnpj"]) || empty($dados["razao_social"])) {
                $emit = $xpath->query("//nfe:emit | //emit")->item(0);
                if (!$emit) {
                    $emitNodes = $dom->getElementsByTagName("emit");
                    $emit = $emitNodes->length > 0 ? $emitNodes->item(0) : null;
                }

                if ($emit instanceof \DOMElement) {
                    if (empty($dados["cnpj"])) {
                        $cnpjEmit = $xpath
                            ->query(".//nfe:CNPJ | .//CNPJ", $emit)
                            ->item(0);
                        if (!$cnpjEmit) {
                            $cnpjNodes = $emit->getElementsByTagName("CNPJ");
                            $cnpjEmit =
                                $cnpjNodes->length > 0
                                ? $cnpjNodes->item(0)
                                : null;
                        }

                        $cpfEmit = $xpath
                            ->query(".//nfe:CPF | .//CPF", $emit)
                            ->item(0);
                        if (!$cpfEmit) {
                            $cpfNodes = $emit->getElementsByTagName("CPF");
                            $cpfEmit =
                                $cpfNodes->length > 0
                                ? $cpfNodes->item(0)
                                : null;
                        }

                        if ($cnpjEmit instanceof \DOMNode) {
                            $dados["cnpj"] = trim($cnpjEmit->nodeValue);
                        } elseif ($cpfEmit instanceof \DOMNode) {
                            $dados["cnpj"] = trim($cpfEmit->nodeValue);
                        }
                    }

                    if (empty($dados["razao_social"])) {
                        $nomeEmit = $xpath
                            ->query(".//nfe:xNome | .//xNome", $emit)
                            ->item(0);
                        if (!$nomeEmit) {
                            $nomeNodes = $emit->getElementsByTagName("xNome");
                            $nomeEmit =
                                $nomeNodes->length > 0
                                ? $nomeNodes->item(0)
                                : null;
                        }
                        if ($nomeEmit instanceof \DOMNode) {
                            $dados["razao_social"] = trim($nomeEmit->nodeValue);
                        }
                    }
                }
            }

            error_log(
                "?? Extra??o de dados do emissor - CNPJ: '{$dados["cnpj"]}', Raz?o: '{$dados["razao_social"]}'"
            );
        } catch (\Exception $e) {
            error_log("Erro ao extrair dados do emissor: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
        }

        return $dados;
    }

    /**
     * NOTA: Este m?todo não funciona como esperado.
     * A consulta de situa??o (sefazConsultaChave) retorna apenas informa??es sobre a NF-e (status, protocolo),
     * não retorna o XML completo (procNFe).
     *
     * O XML completo (procNFe) s? est? dispon?vel via:
     * 1. Download direto (sefazDownload) - quando dispon?vel
     * 2. Solicita??o direta ao fornecedor
     *
     * @deprecated Este m?todo não retorna o XML completo. Use apenas para obter informa??es da NF-e.
     */
    public static function buscarXmlCompletoPorConsulta(
        array $empresa,
        string $chaveNfe,
        $db = null
    ): array {
        try {
            error_log("=== BUSCAR XML COMPLETO VIA CONSULTA ===");
            error_log("Chave: {$chaveNfe}");

            // Carregar autoload do NFePHP
            $nfeAutoload =
                \ROOT_PATH . "/src/Integrations/NFe/vendor/autoload.php";
            if (file_exists($nfeAutoload)) {
                require_once $nfeAutoload;
            } else {
                require_once \ROOT_PATH . "/vendor/autoload.php";
            }

            // Verificar se NFePHP est? dispon?vel
            if (!class_exists("\NFePHP\NFe\Tools")) {
                return [
                    "sucesso" => false,
                    "erro" => "NFePHP não est? instalado",
                ];
            }

            // Ler certificado
            $certificadoPath = \ROOT_PATH . $empresa["certificado_path"];
            if (!file_exists($certificadoPath)) {
                return [
                    "sucesso" => false,
                    "erro" => "Certificado não encontrado: " . $certificadoPath,
                ];
            }

            $certificadoConteudo = file_get_contents($certificadoPath);
            $senhaCertificado = $empresa["senha_certificado"];
            $ambiente =
                ($empresa["ambiente_nfe"] ?? "producao") === "producao" ? 1 : 2;

            // Configurar NFePHP
            $config = [
                "atualizacao" => date("Y-m-d H:i:s"),
                "tpAmb" => $ambiente,
                "razaosocial" => $empresa["razao_social"] ?? "",
                "cnpj" => preg_replace("/\D/", "", $empresa["cnpj"] ?? ""),
                "siglaUF" => "PE",
                "schemes" => "PL_009_V4",
                "versao" => "4.00",
                "tokenIBPT" => "",
                "CSC" => "",
                "CSCid" => "",
            ];

            $certificate = \NFePHP\Common\Certificate::readPfx(
                $certificadoConteudo,
                $senhaCertificado
            );
            $tools = new \NFePHP\NFe\Tools(json_encode($config), $certificate);

            // Consultar situa??o da NF-e
            error_log("Consultando situa??o da NF-e: {$chaveNfe}");
            // O m?todo correto ? sefazConsultaChave
            $response = $tools->sefazConsultaChave($chaveNfe);

            error_log("Response da consulta: " . substr($response, 0, 500));

            // Processar resposta
            $dom = new \DOMDocument();
            $dom->loadXML($response);

            // Verificar status
            $cStat = $dom->getElementsByTagName("cStat")->item(0);
            $xMotivo = $dom->getElementsByTagName("xMotivo")->item(0);

            $cStatValue = $cStat ? $cStat->nodeValue : "";
            $xMotivoValue = $xMotivo ? $xMotivo->nodeValue : "";

            error_log("cStat: {$cStatValue}, xMotivo: {$xMotivoValue}");

            if ($cStatValue == "100") {
                // NF-e autorizada
                // Tentar extrair o XML completo (procNFe)
                $procNFe = $dom->getElementsByTagName("procNFe")->item(0);
                if ($procNFe) {
                    $xmlCompleto = $dom->saveXML($procNFe);
                    error_log(
                        "? XML completo (procNFe) encontrado na consulta"
                    );

                    // Verificar se realmente ? procNFe (não resNFe)
                    if (
                        strpos($xmlCompleto, "<resNFe") !== false &&
                        strpos($xmlCompleto, "<procNFe") === false &&
                        strpos($xmlCompleto, "<NFe") === false
                    ) {
                        error_log("? A consulta retornou resNFe, não procNFe");
                        return [
                            "sucesso" => false,
                            "erro" =>
                                "A consulta retornou apenas resumo (resNFe), não o XML completo (procNFe)",
                        ];
                    }

                    // Salvar no banco
                    if ($db) {
                        try {
                            $stmtCompany = $db->prepare(
                                "SELECT id FROM companies LIMIT 1"
                            );
                            $stmtCompany->execute();
                            $companyRow = $stmtCompany->fetch();
                            $companyId = $companyRow ? $companyRow["id"] : 1;

                            $stmt = $db->prepare("
                                UPDATE nfe_recebidas
                                SET xml_completo = :xml_completo,
                                    updated_at = NOW()
                                WHERE chave_nfe = :chave_nfe AND company_id = :company_id
                            ");
                            $stmt->execute([
                                "xml_completo" => $xmlCompleto,
                                "chave_nfe" => $chaveNfe,
                                "company_id" => $companyId,
                            ]);
                            error_log("? XML completo salvo no banco");
                        } catch (\Exception $e) {
                            error_log(
                                "Erro ao salvar XML completo no banco: " .
                                $e->getMessage()
                            );
                        }
                    }

                    return [
                        "sucesso" => true,
                        "xml_completo" => $xmlCompleto,
                    ];
                } else {
                    error_log(
                        "?? procNFe não encontrado na resposta da consulta de situa??o."
                    );
                    error_log(
                        "?? A consulta de situa??o (sefazConsultaChave) retorna apenas informa??es sobre a NF-e (status, protocolo), não o XML completo (procNFe)."
                    );
                    error_log(
                        "?? O XML completo (procNFe) s? est? dispon?vel via download (sefazDownload) ou deve ser solicitado ao fornecedor."
                    );

                    // A consulta de situa??o não retorna o XML completo, apenas informa??es
                    // Precisamos informar que o XML completo não est? dispon?vel via consulta
                    return [
                        "sucesso" => false,
                        "erro" =>
                            "A consulta de situa??o não retorna o XML completo (procNFe). Ela retorna apenas informa??es sobre a NF-e (status, protocolo). O XML completo (procNFe) s? est? dispon?vel via download direto da SEFAZ ou deve ser solicitado ao fornecedor.",
                    ];
                }
            } else {
                error_log(
                    "?? NF-e não autorizada ou não encontrada. cStat: {$cStatValue}"
                );
                return [
                    "sucesso" => false,
                    "erro" => "NF-e não autorizada: {$xMotivoValue}",
                ];
            }
        } catch (\Exception $e) {
            error_log(
                "Erro ao buscar XML completo via consulta: " . $e->getMessage()
            );
            error_log("Stack trace: " . $e->getTraceAsString());
            return [
                "sucesso" => false,
                "erro" => "Erro ao buscar XML completo: " . $e->getMessage(),
            ];
        }
    }

    /**
     * Inicializa o servi?o NF-e e suas depend?ncias
     */
    private function initialize(): void
    {
        if ($this->initialized) {
            return;
        }

        try {
            // 1. Carregar autoload do m?dulo NF-e
            $nfeAutoload =
                \ROOT_PATH . "/src/Integrations/NFe/vendor/autoload.php";
            if (!file_exists($nfeAutoload)) {
                throw new \Exception(
                    "Autoload do m?dulo NF-e não encontrado. Execute composer install na pasta src/Integrations/NFe"
                );
            }
            require_once $nfeAutoload;

            // 2. Carregar configura??es do m?dulo NF-e
            $configFile =
                \ROOT_PATH . "/src/Integrations/NFe/config_producao.php";
            if (!file_exists($configFile)) {
                throw new \Exception(
                    "Arquivo de configura??o do m?dulo NF-e não encontrado: " .
                    $configFile
                );
            }
            require_once $configFile;

            // 3. Verificar se a classe existe
            if (!class_exists("\App\Services\NFeService")) {
                throw new \Exception(
                    "Classe NFeService não encontrada no m?dulo NF-e"
                );
            }

            // 4. Instanciar o servi?o
            $this->nfeService = new \App\Services\NFeService();
            $this->initialized = true;

            error_log("NFeIntegrationService: Inicializado com sucesso");
        } catch (\Exception $e) {
            error_log(
                "NFeIntegrationService: Erro ao inicializar - " .
                $e->getMessage()
            );
            throw new \Exception(
                "Erro ao inicializar servi?o NF-e: " . $e->getMessage()
            );
        }
    }

    /**
     * Emite NF-e sem usar banco de dados
     *
     * @param array $dados Dados da NF-e no formato esperado pela API
     * @return array Resultado da emiss?o
     * @throws \Exception Se houver erro na emiss?o
     */
    public function emitirNFe(array $dados): array
    {
        $this->initialize();

        if (!$this->nfeService) {
            throw new \Exception("Servi?o NF-e não inicializado");
        }

        try {
            // Validar dados b?sicos
            $this->validarDados($dados);

            // Chamar o servi?o do m?dulo NF-e
            $resultado = $this->nfeService->emitirSemBanco($dados);

            // Log do resultado
            if ($resultado["success"]) {
                error_log(
                    "NFeIntegrationService: NF-e emitida com sucesso - N?mero: {$resultado["numero"]}, Chave: {$resultado["chave_acesso"]}"
                );
            } else {
                error_log(
                    "NFeIntegrationService: Erro ao emitir NF-e - " .
                    ($resultado["error"] ?? "Erro desconhecido")
                );
            }

            return $resultado;
        } catch (\Exception $e) {
            error_log(
                "NFeIntegrationService: Exce??o ao emitir NF-e - " .
                $e->getMessage()
            );
            throw $e;
        }
    }

    /**
     * Valida dados b?sicos antes de enviar para emiss?o
     */
    private function validarDados(array $dados): void
    {
        $camposObrigatorios = [
            "empresa" => ["cnpj", "nome"],
            "nfe" => ["numero", "serie"],
            "itens" => [],
        ];

        // Validar empresa
        if (empty($dados["empresa"]["cnpj"])) {
            throw new \Exception("CNPJ da empresa ? obrigat?rio");
        }

        // Validar NF-e
        if (empty($dados["nfe"]["numero"]) || empty($dados["nfe"]["serie"])) {
            throw new \Exception("N?mero e s?rie da NF-e s?o obrigat?rios");
        }

        // Validar itens
        if (
            empty($dados["itens"]) ||
            !is_array($dados["itens"]) ||
            count($dados["itens"]) === 0
        ) {
            throw new \Exception("A NF-e deve conter pelo menos um item");
        }

        // Validar cada item
        foreach ($dados["itens"] as $index => $item) {
            if (empty($item["descricao"])) {
                throw new \Exception("Item #{$index}: Descri??o ? obrigat?ria");
            }
            if (
                empty($item["quantidade_comercial"]) ||
                floatval($item["quantidade_comercial"]) <= 0
            ) {
                throw new \Exception("Item #{$index}: Quantidade inv?lida");
            }
            if (
                empty($item["valor_unitario"]) ||
                floatval($item["valor_unitario"]) <= 0
            ) {
                throw new \Exception("Item #{$index}: Valor unit?rio inv?lido");
            }
        }
    }

    /**
     * Cancela NF-e
     */
    public function cancelarNFe(array $dados): array
    {
        $this->initialize();

        if (!$this->nfeService) {
            throw new \Exception("Servi?o NF-e não inicializado");
        }

        try {
            // Chamar m?todo de cancelamento do m?dulo NF-e
            $resultado = $this->nfeService->cancelarNFe($dados);

            return $resultado;
        } catch (\Exception $e) {
            error_log(
                "NFeIntegrationService: Exce??o ao cancelar NF-e - " .
                $e->getMessage()
            );
            throw $e;
        }
    }

    /**
     * Emite Carta de Corre??o Eletr?nica (CCE)
     */
    public function cartaCorrecaoNFe(array $dados): array
    {
        $this->initialize();

        if (!$this->nfeService) {
            throw new \Exception("Servi?o NF-e não inicializado");
        }

        try {
            // Chamar m?todo de carta de corre??o do m?dulo NF-e
            $resultado = $this->nfeService->cartaCorrecao($dados);

            return $resultado;
        } catch (\Exception $e) {
            error_log(
                "NFeIntegrationService: Exce??o ao enviar CCE - " .
                $e->getMessage()
            );
            throw $e;
        }
    }

    /**
     * Gera DANFE de preview antes da emissão
     */
    public function previewDanfe(array $dados): array
    {
        $this->initialize();

        if (!$this->nfeService) {
            throw new \Exception("Servi?o NF-e não inicializado");
        }

        try {
            // Validar dados b?sicos
            $this->validarDados($dados);

            // Chamar m?todo de preview do m?dulo NF-e
            $resultado = $this->nfeService->previewDanfe($dados);

            // Log do resultado
            if ($resultado["success"]) {
                error_log(
                    "NFeIntegrationService: DANFE de preview gerado com sucesso"
                );
            } else {
                error_log(
                    "NFeIntegrationService: Erro ao gerar preview - " .
                    ($resultado["error"] ?? "Erro desconhecido")
                );
            }

            return $resultado;
        } catch (\Exception $e) {
            error_log(
                "NFeIntegrationService: Exce??o ao gerar preview - " .
                $e->getMessage()
            );
            throw $e;
        }
    }

    /**
     * Verifica se o m?dulo NF-e est? dispon?vel e configurado
     */
    public function verificarDisponibilidade(): array
    {
        $status = [
            "disponivel" => false,
            "erros" => [],
            "avisos" => [],
        ];

        // Verificar autoload
        $nfeAutoload = \ROOT_PATH . "/src/Integrations/NFe/vendor/autoload.php";
        if (!file_exists($nfeAutoload)) {
            $status["erros"][] = "Autoload do m?dulo NF-e não encontrado";
            return $status;
        }

        // Verificar configura??o
        $configFile = \ROOT_PATH . "/src/Integrations/NFe/config_producao.php";
        if (!file_exists($configFile)) {
            $status["erros"][] = "Arquivo de configura??o não encontrado";
            return $status;
        }

        // Verificar classe
        try {
            require_once $nfeAutoload;
            if (!class_exists("\App\Services\NFeService")) {
                $status["erros"][] = "Classe NFeService não encontrada";
                return $status;
            }
        } catch (\Exception $e) {
            $status["erros"][] =
                "Erro ao carregar m?dulo NF-e: " . $e->getMessage();
            return $status;
        }

        $status["disponivel"] = true;
        return $status;
    }

    /**
     * Consulta NF-e destinadas ? empresa (Manifesto do Destinat?rio)
     */
    public function consultarNFeDestinatario(array $empresa, $db = null): array
    {
        try {
            $this->initialize();

            // Dados da empresa (mapear colunas PT/EN)
            $cnpj = preg_replace(
                "/[^0-9]/",
                "",
                $empresa["cnpj"] ?? ($empresa["document"] ?? "")
            );
            $companyId = $empresa["id"] ?? ($empresa["company_id"] ?? 1);

            if (empty($cnpj)) {
                throw new \Exception("CNPJ da empresa não informado");
            }

            // Configurar certificado
            $certificadoPath = $empresa["certificado_path"] ?? "";
            if (empty($certificadoPath)) {
                throw new \Exception("Certificado digital não configurado");
            }

            if (strpos($certificadoPath, \ROOT_PATH) !== 0) {
                $certificadoPath =
                    \ROOT_PATH . "/" . ltrim($certificadoPath, "/");
            }

            if (!file_exists($certificadoPath)) {
                throw new \Exception(
                    "Certificado digital não encontrado no caminho: " .
                    $certificadoPath
                );
            }

            $senhaCertificado = $empresa["senha_certificado"] ?? "";
            if (empty($senhaCertificado)) {
                throw new \Exception("Senha do certificado não configurada");
            }

            // Ambiente (1=Produ??o, 2=Homologa??o)
            $ambiente =
                ($empresa["ambiente_nfe"] ?? "homologacao") === "producao"
                ? 1
                : 2;
            $ambienteStr = $ambiente == 1 ? "producao" : "homologacao";
            $uf = $empresa["uf"] ?? ($empresa["state"] ?? "PE");

            // Buscar ?ltimo NSU consultado (se tiver DB)
            // IMPORTANTE: Usar ultimo_nsu (que vem do ultNSU da SEFAZ), não o max_nsu
            $ultNSU = 0;
            if ($db) {
                try {
                    $stmt = $db->prepare("
                        SELECT ultimo_nsu, max_nsu
                        FROM nfe_distribuicao_dfe
                        WHERE company_id = :company_id AND ambiente = :ambiente
                        LIMIT 1
                    ");
                    $stmt->execute([
                        "company_id" => $companyId,
                        "ambiente" => $ambienteStr,
                    ]);
                    $controle = $stmt->fetch();

                    if ($controle) {
                        // CORRE??O: Usar ultimo_nsu (vem do ultNSU da SEFAZ)
                        // Se ultimo_nsu for 0, tenta max_nsu como fallback
                        $ultNSU = $controle["ultimo_nsu"] ?? 0;
                        if ($ultNSU == 0) {
                            $ultNSU = $controle["max_nsu"] ?? 0;
                        }
                        error_log("?? Usando ?ltimo NSU armazenado: {$ultNSU}");
                    }
                } catch (\Exception $e) {
                    error_log(
                        "Aviso ao buscar ?ltimo NSU: " . $e->getMessage()
                    );
                }
            }

            // Consultar documentos destinados ao CNPJ via NFePHP
            $nfes = [];

            try {
                // Carregar NFePHP
                if (!class_exists("\NFePHP\NFe\Tools")) {
                    throw new \Exception("NFePHP não est? instalado");
                }

                // Configurar Tools da NFePHP
                $config = [
                    "atualizacao" => date("Y-m-d H:i:s"),
                    "tpAmb" => $ambiente,
                    "razaosocial" =>
                        $empresa["razao_social"] ?? ($empresa["name"] ?? ""),
                    "siglaUF" => $uf,
                    "cnpj" => $cnpj,
                    "schemes" => "PL_009_V4",
                    "versao" => "4.00",
                    "tokenIBPT" => "AAAAAAA",
                    "CSC" => "",
                    "CSCid" => "",
                ];

                $tools = new \NFePHP\NFe\Tools(
                    json_encode($config),
                    \NFePHP\Common\Certificate::readPfx(
                        file_get_contents($certificadoPath),
                        $senhaCertificado
                    )
                );

                // Fazer consulta de distribui??o DFe
                // Usar o ultNSU buscado do banco (ou 0 se for a primeira consulta)
                // NSU = 0 busca todas as notas desde o in?cio
                // NSU > 0 busca apenas notas novas desde o ?ltimo NSU consultado

                error_log("=== Iniciando consulta DistDFe ===");
                error_log("CNPJ: {$cnpj}");
                error_log("Ambiente: {$ambiente}");
                error_log("UF: {$uf}");
                error_log("NSU: {$ultNSU}");

                $response = $tools->sefazDistDFe($ultNSU);

                error_log("Response SEFAZ: " . substr($response, 0, 500));

                // Processar resposta
                $st = new \NFePHP\NFe\Common\Standardize($response);
                $std = $st->toStd();

                error_log("cStat retornado: " . ($std->cStat ?? "null"));
                error_log("xMotivo: " . ($std->xMotivo ?? "null"));

                // Tratar erro 656 (Consumo Indevido)
                if ($std->cStat == 656) {
                    error_log("?? SEFAZ retornou erro 656: Consumo Indevido");

                    // Salvar ultNSU retornado para pr?xima consulta
                    if (isset($std->ultNSU) && $db) {
                        $ultNSURetornado = (int) $std->ultNSU;
                        $diferencaNSU = $ultNSURetornado - $ultNSU;

                        if ($diferencaNSU > 0) {
                            error_log("?? ATENÇÃO: NSU estava desatualizado!");
                            error_log("   NSU consultado: {$ultNSU}");
                            error_log(
                                "   NSU correto (SEFAZ): {$ultNSURetornado}"
                            );
                            error_log(
                                "   Diferen?a: {$diferencaNSU} documentos podem ter sido perdidos"
                            );
                        }

                        error_log(
                            "?? Salvando ultNSU retornado pela SEFAZ: {$ultNSURetornado}"
                        );

                        try {
                            $stmt = $db->prepare("
                                INSERT INTO nfe_distribuicao_dfe
                                (company_id, ultimo_nsu, max_nsu, ambiente, created_at, updated_at)
                                VALUES (:company_id, :ultimo_nsu, 0, :ambiente, NOW(), NOW())
                                ON DUPLICATE KEY UPDATE
                                    ultimo_nsu = VALUES(ultimo_nsu),
                                    updated_at = NOW()
                            ");
                            $stmt->execute([
                                "company_id" => $companyId,
                                "ultimo_nsu" => $ultNSURetornado,
                                "ambiente" => $ambienteStr,
                            ]);
                            error_log(
                                "? ultNSU salvo com sucesso: {$ultNSURetornado}"
                            );

                            // Se havia diferen?a, sugerir consulta manual
                            if ($diferencaNSU > 0) {
                                error_log(
                                    "?? SUGEST?O: Considere fazer uma consulta manual para recuperar as NF-e perdidas (NSU 0 at? {$ultNSURetornado})"
                                );
                            }
                        } catch (\Exception $e) {
                            error_log(
                                "Erro ao salvar ultNSU: " . $e->getMessage()
                            );
                        }
                    }

                    // não lan?ar exce??o, retornar resultado vazio com aviso
                    // Isso permite que o monitor continue funcionando com NF-e j? armazenadas

                    // Calcular pr?xima consulta (60 minutos a partir de agora)
                    $proximaConsulta = date("H:i", strtotime("+60 minutes"));

                    $avisoMsg =
                        "Por motivo de segurança, a SEFAZ limita a uma consulta a cada 60 minutos. A próxima consulta será às " .
                        $proximaConsulta .
                        ".";

                    return [
                        "nfes" => [],
                        "aviso" => $avisoMsg,
                        "ult_nsu" => $std->ultNSU ?? "0",
                    ];
                }

                // Tratar erro 137 (Nenhum documento)
                if ($std->cStat == 137) {
                    error_log("?? SEFAZ: Nenhum documento localizado");

                    // Log detalhado do NSU
                    $ultNSURetornado = isset($std->ultNSU)
                        ? (int) $std->ultNSU
                        : 0;
                    $maxNSURetornado = isset($std->maxNSU)
                        ? (int) $std->maxNSU
                        : 0;
                    error_log(
                        "?? NSU Info - Consultado: {$ultNSU}, Retornado ultNSU: {$ultNSURetornado}, maxNSU: {$maxNSURetornado}"
                    );

                    if (
                        $ultNSURetornado == $maxNSURetornado &&
                        $maxNSURetornado > 0
                    ) {
                        error_log(
                            "? NSU sincronizado: Voc? est? atualizado! não h? documentos novos."
                        );
                    }

                    // Mesmo sem documentos, atualizar NSU se vier
                    if (isset($std->ultNSU) && $db) {
                        error_log("?? Atualizando ultNSU: {$ultNSURetornado}");

                        try {
                            $stmt = $db->prepare("
                                INSERT INTO nfe_distribuicao_dfe
                                (company_id, ultimo_nsu, max_nsu, ambiente, ultima_consulta, created_at, updated_at)
                                VALUES (:company_id, :ultimo_nsu, 0, :ambiente, NOW(), NOW(), NOW())
                                ON DUPLICATE KEY UPDATE
                                    ultimo_nsu = VALUES(ultimo_nsu),
                                    ultima_consulta = NOW(),
                                    updated_at = NOW()
                            ");
                            $stmt->execute([
                                "company_id" => $companyId,
                                "ultimo_nsu" => $ultNSURetornado,
                                "ambiente" => $ambienteStr,
                            ]);
                        } catch (\Exception $e) {
                            error_log(
                                "Erro ao salvar ultNSU: " . $e->getMessage()
                            );
                        }
                    }
                }

                if ($std->cStat == 138) {
                    // Documento localizado
                    error_log("? Documentos localizados!");
                    // Processar documentos encontrados
                    if (isset($std->loteDistDFeInt)) {
                        $totalDocs = is_array($std->loteDistDFeInt->docZip)
                            ? count($std->loteDistDFeInt->docZip)
                            : (isset($std->loteDistDFeInt->docZip)
                                ? 1
                                : 0);
                        error_log(
                            "?? Total de documentos no lote: {$totalDocs}"
                        );

                        $docs = is_array($std->loteDistDFeInt->docZip)
                            ? $std->loteDistDFeInt->docZip
                            : [$std->loteDistDFeInt->docZip];

                        foreach ($docs as $index => $doc) {
                            // Tentar diferentes formas de acessar schema e NSU
                            $schema = "";
                            $nsu = "";
                            $xmlContentBase64 = "";

                            // Verificar se ? objeto com atributos
                            if (is_object($doc)) {
                                // Tentar acessar como propriedade
                                $schema =
                                    $doc->schema ??
                                    ($doc->{'@attributes'}["schema"] ?? "");
                                $nsu =
                                    $doc->NSU ??
                                    ($doc->{'@attributes'}["NSU"] ?? "");

                                // Tentar acessar o valor (pode ser $value, __toString, ou direto)
                                if (isset($doc->{'$value'})) {
                                    $xmlContentBase64 = $doc->{'$value'};
                                } elseif (isset($doc->__toString)) {
                                    $xmlContentBase64 = (string) $doc;
                                } elseif (method_exists($doc, "__toString")) {
                                    $xmlContentBase64 = (string) $doc;
                                } else {
                                    // Tentar como string direto
                                    $xmlContentBase64 = (string) $doc;
                                }
                            } elseif (is_string($doc)) {
                                // Se for string direto, pode ser que schema e NSU estejam em outro lugar
                                $xmlContentBase64 = $doc;
                            }

                            // Log detalhado para debug
                            error_log(
                                "?? Documento #{$index} - Schema: '{$schema}', NSU: '{$nsu}', Tipo: " .
                                gettype($doc)
                            );
                            if (is_object($doc)) {
                                error_log(
                                    "   Propriedades: " .
                                    implode(
                                        ", ",
                                        array_keys(get_object_vars($doc))
                                    )
                                );
                            }

                            // REJEITAR resNFe - APENAS PROCESSA procNFe
                            // Pular se for resNFe
                            if (strpos($schema, "resNFe") !== false) {
                                error_log(
                                    "   ❌ Pulando documento #{$index}: É resNFe - resNFe NÃO É PROCESSADO!"
                                );
                                continue;
                            }

                            // Se não tem schema, verificar o conteúdo para detectar resNFe
                            if (empty($schema) && !empty($xmlContentBase64)) {
                                try {
                                    $xmlTest = gzdecode(
                                        base64_decode($xmlContentBase64)
                                    );
                                    if ($xmlTest !== false) {
                                        $domTest = new \DOMDocument();
                                        if ($domTest->loadXML($xmlTest)) {
                                            // Se for resNFe, rejeitar
                                            if (
                                                $domTest->getElementsByTagName(
                                                    "resNFe"
                                                )->length > 0
                                            ) {
                                                error_log(
                                                    "   ❌ Pulando documento #{$index}: Detectado como resNFe pelo conteúdo - resNFe NÃO É PROCESSADO!"
                                                );
                                                continue;
                                            }
                                        }
                                    }
                                } catch (\Exception $e) {
                                    // Continuar processamento se houver erro
                                }
                            }

                            // Processar apenas procNFe/nfeProc/NFe completo
                            // Descompactar documento
                            if (empty($xmlContentBase64)) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: conteúdo vazio"
                                );
                                continue;
                            }

                            $xmlContent = gzdecode(
                                base64_decode($xmlContentBase64)
                            );
                            if ($xmlContent === false) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: erro ao descompactar"
                                );
                                continue;
                            }

                            $domDoc = new \DOMDocument();
                            if (!$domDoc->loadXML($xmlContent)) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: XML inválido"
                                );
                                continue;
                            }

                            // Verificar se é resNFe - REJEITAR
                            if (
                                $domDoc->getElementsByTagName("resNFe")
                                    ->length > 0
                            ) {
                                error_log(
                                    "   ❌ Pulando documento #{$index}: É resNFe - resNFe NÃO É PROCESSADO!"
                                );
                                continue;
                            }

                            // Verificar se é procNFe, nfeProc ou NFe completo
                            $temProcNFe =
                                $domDoc->getElementsByTagName("procNFe")
                                    ->length > 0;
                            $temNfeProc =
                                $domDoc->getElementsByTagName("nfeProc")
                                    ->length > 0;
                            $temNFe =
                                $domDoc->getElementsByTagName("NFe")->length >
                                0;

                            if (!$temProcNFe && !$temNfeProc && !$temNFe) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: Não é procNFe, nfeProc ou NFe"
                                );
                                continue;
                            }

                            // Verificar se tem itens (det) - essencial para ser XML completo
                            $temDet =
                                $domDoc->getElementsByTagName("det")->length >
                                0;
                            if (!$temDet) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: Não contém itens (det)"
                                );
                                continue;
                            }

                            // Extrair chave da NF-e do XML completo (DEVE TER 44 DÍGITOS)
                            $chNFe = "";

                            // PRIORIDADE 1: Extrair do atributo Id da tag <NFe> (formato: NFe + 44 dígitos)
                            $nfeNode = $domDoc->getElementsByTagName("NFe")->item(0);
                            if ($nfeNode) {
                                $idNFe = $nfeNode->getAttribute("Id") ?? "";
                                if (!empty($idNFe) && strpos($idNFe, 'NFe') === 0) {
                                    $chNFe = str_replace("NFe", "", $idNFe);
                                    if (strlen($chNFe) === 44) {
                                        error_log("   ✅ Chave extraída do atributo Id da tag <NFe>: {$chNFe}");
                                    } else {
                                        $chNFe = ""; // Invalidar se não tiver 44 dígitos
                                    }
                                }
                            }

                            // PRIORIDADE 2: Extrair do infProt->Id (formato: NFe + 44 dígitos)
                            if (empty($chNFe) || strlen($chNFe) !== 44) {
                                $infProt = $domDoc->getElementsByTagName("infProt")->item(0);
                                if ($infProt) {
                                    $idProt = $infProt->getAttribute("Id") ?? "";
                                    if (!empty($idProt) && strpos($idProt, 'NFe') === 0) {
                                        $chaveTemp = str_replace("NFe", "", $idProt);
                                        if (strlen($chaveTemp) === 44) {
                                            $chNFe = $chaveTemp;
                                            error_log("   ✅ Chave extraída do infProt->Id: {$chNFe}");
                                        }
                                    }
                                }
                            }

                            // PRIORIDADE 3: Extrair da tag <chNFe> se existir
                            if (empty($chNFe) || strlen($chNFe) !== 44) {
                                $chNFeNode = $domDoc->getElementsByTagName("chNFe")->item(0);
                                if ($chNFeNode && strlen($chNFeNode->nodeValue) === 44) {
                                    $chNFe = preg_replace('/\D/', '', $chNFeNode->nodeValue);
                                    if (strlen($chNFe) === 44) {
                                        error_log("   ✅ Chave extraída da tag <chNFe>: {$chNFe}");
                                    }
                                }
                            }

                            // PRIORIDADE 4: Usar chave conhecida APENAS se tiver 44 dígitos
                            if ((empty($chNFe) || strlen($chNFe) !== 44) && !empty($chaveNfe)) {
                                $chaveLimpa = preg_replace('/\D/', '', $chaveNfe);
                                if (strlen($chaveLimpa) === 44) {
                                    $chNFe = $chaveLimpa;
                                    error_log("   ✅ Chave usada da variável conhecida (44 dígitos): {$chNFe}");
                                } else {
                                    error_log("   ⚠️ Chave conhecida tem tamanho inválido: {$chaveLimpa} (" . strlen($chaveLimpa) . " dígitos) - IGNORANDO");
                                }
                            }

                            if (empty($chNFe)) {
                                error_log(
                                    "   ⚠️ Pulando documento #{$index}: Não foi possível extrair chave da NF-e"
                                );
                                continue;
                            }

                            $nfe = [
                                "chave_nfe" => $chNFe,
                                "nsu" => $nsu ?: $index + 1,
                                "schema" => $schema ?: "procNFe",
                            ];

                            error_log(
                                "   ✅ NF-e processada (procNFe completo) - Chave: {$chNFe}, NSU: {$nfe["nsu"]}"
                            );

                            // Extrair dados do emissor (fornecedor)
                            $dadosEmissor = self::extrairDadosEmissor(
                                $xmlContent
                            );
                            $nfe["cnpj_fornecedor"] = $dadosEmissor["cnpj"];
                            $nfe["razao_social"] =
                                $dadosEmissor["razao_social"];

                            // Extrair dados do destinatário (importante para validação)
                            $dadosDestinatario = self::extrairDadosDestinatario(
                                $xmlContent
                            );
                            $nfe["cnpj_destinatario"] = $dadosDestinatario["cnpj"];
                            $nfe["razao_social_destinatario"] = $dadosDestinatario["razao_social"];

                            error_log(
                                "   ✅ Fornecedor (emitente) extraído: {$nfe["razao_social"]} - CNPJ: {$nfe["cnpj_fornecedor"]}"
                            );
                            error_log(
                                "   ✅ Destinatário extraído: {$nfe["razao_social_destinatario"]} - CNPJ: {$nfe["cnpj_destinatario"]}"
                            );

                            // VALIDAÇÃO: Verificar se o CNPJ do certificado usado (destinatário) corresponde ao CNPJ do destinatário extraído do XML
                            $cnpjCertificado = preg_replace("/\D/", "", $cnpj);
                            $cnpjDestinatarioXML = preg_replace("/\D/", "", $nfe["cnpj_destinatario"] ?? "");

                            if (!empty($cnpjDestinatarioXML) && $cnpjCertificado !== $cnpjDestinatarioXML) {
                                error_log(
                                    "   ⚠️ ATENÇÃO: CNPJ do certificado ({$cnpjCertificado}) não corresponde ao CNPJ do destinatário no XML ({$cnpjDestinatarioXML})"
                                );
                            } else {
                                error_log(
                                    "   ✅ Validação: CNPJ do certificado corresponde ao destinatário do XML"
                                );
                            }

                            // Extrair valor e data
                            $totalNode = $domDoc
                                ->getElementsByTagName("total")
                                ->item(0);
                            $vNFNode = $totalNode
                                ? $totalNode
                                    ->getElementsByTagName("vNF")
                                    ->item(0)
                                : null;
                            $nfe["valor"] = $vNFNode
                                ? $vNFNode->nodeValue
                                : "0.00";

                            // Buscar ideNode novamente para extrair data
                            $ideNode = $domDoc->getElementsByTagName("ide")->item(0);
                            $dhEmi = $ideNode
                                ? $ideNode
                                    ->getElementsByTagName("dhEmi")
                                    ->item(0)->nodeValue ?? ""
                                : "";
                            $nfe["data_emissao"] = $dhEmi
                                ? date("d/m/Y", strtotime($dhEmi))
                                : "";

                            // Verificar se já foi manifestada
                            $nfe["status"] = "pendente";

                            $nfes[] = $nfe;
                        }

                        error_log("Total de NF-e processadas: " . count($nfes));
                    } else {
                        error_log(
                            "?? loteDistDFeInt não encontrado no retorno"
                        );
                    }
                } else {
                    error_log(
                        "?? cStat diferente de 138. Retorno: cStat={$std->cStat}, xMotivo={$std->xMotivo}"
                    );
                }

                // Atualizar ?ltimo NSU consultado (sempre atualizar, mesmo sem documentos)
                if (isset($std->ultNSU) && $db) {
                    $ultNSURetornado = (int) $std->ultNSU;
                    $maxNSURetornado = isset($std->maxNSU)
                        ? (int) $std->maxNSU
                        : 0;

                    error_log(
                        "?? Atualizando NSU - ultNSU: {$ultNSURetornado}, maxNSU: {$maxNSURetornado}"
                    );

                    try {
                        $stmt = $db->prepare("
                            INSERT INTO nfe_distribuicao_dfe
                            (company_id, ultimo_nsu, max_nsu, ultima_consulta, total_documentos, ambiente, created_at, updated_at)
                            VALUES (:company_id, :ultimo_nsu, :max_nsu, NOW(), :novos, :ambiente, NOW(), NOW())
                            ON DUPLICATE KEY UPDATE
                                ultimo_nsu = VALUES(ultimo_nsu),
                                max_nsu = VALUES(max_nsu),
                                ultima_consulta = NOW(),
                                total_documentos = total_documentos + VALUES(total_documentos),
                                updated_at = NOW()
                        ");
                        $stmt->execute([
                            "company_id" => $companyId,
                            "ultimo_nsu" => $ultNSURetornado,
                            "max_nsu" => $maxNSURetornado,
                            "novos" => count($nfes),
                            "ambiente" => $ambienteStr,
                        ]);

                        error_log("? NSU salvo com sucesso");
                    } catch (\Exception $e) {
                        error_log("Erro ao salvar NSU: " . $e->getMessage());
                    }
                }

                // Salvar NF-e no banco (se tiver DB)
                if ($db && count($nfes) > 0) {
                    try {
                        $stmt = $db->prepare("
                            INSERT INTO nfe_recebidas
                            (company_id, chave_nfe, nsu, cnpj_fornecedor, razao_social_fornecedor,
                             cnpj_destinatario, destinatario_cnpj, data_emissao, valor_total, tipo_documento, status_manifesto)
                            VALUES
                            (:company_id, :chave_nfe, :nsu, :cnpj_fornecedor, :razao_social,
                             :cnpj_destinatario, :cnpj_destinatario, :data_emissao, :valor_total, :tipo_documento, :status_manifesto)
                            ON DUPLICATE KEY UPDATE
                                status_manifesto = VALUES(status_manifesto),
                                cnpj_fornecedor = COALESCE(NULLIF(VALUES(cnpj_fornecedor), ''), cnpj_fornecedor),
                                razao_social_fornecedor = COALESCE(NULLIF(VALUES(razao_social_fornecedor), ''), razao_social_fornecedor),
                                cnpj_destinatario = COALESCE(NULLIF(VALUES(cnpj_destinatario), ''), cnpj_destinatario),
                                destinatario_cnpj = COALESCE(NULLIF(VALUES(destinatario_cnpj), ''), destinatario_cnpj),
                                updated_at = NOW()
                        ");

                        foreach ($nfes as $nfe) {
                            $dataEmissao = null;
                            if (!empty($nfe["data_emissao"])) {
                                $dataEmissao = \DateTime::createFromFormat(
                                    "d/m/Y",
                                    $nfe["data_emissao"]
                                );
                                $dataEmissao = $dataEmissao
                                    ? $dataEmissao->format("Y-m-d H:i:s")
                                    : null;
                            }

                            error_log(
                                "   ?? Salvando NF-e no banco - Chave: {$nfe["chave_nfe"]}, CNPJ: " .
                                ($nfe["cnpj_fornecedor"] ?? "vazio") .
                                ", Raz?o: " .
                                ($nfe["razao_social"] ?? "vazio")
                            );

                            $stmt->execute([
                                "company_id" => $companyId,
                                "chave_nfe" => $nfe["chave_nfe"],
                                "nsu" => $nfe["nsu"],
                                "cnpj_fornecedor" =>
                                    $nfe["cnpj_fornecedor"] ?? null,
                                "razao_social" => $nfe["razao_social"] ?? null,
                                "cnpj_destinatario" => $nfe["cnpj_destinatario"] ?? null,
                                "data_emissao" => $dataEmissao,
                                "valor_total" => $nfe["valor"] ?? 0,
                                "tipo_documento" => $nfe["schema"] ?? "resNFe",
                                "status_manifesto" =>
                                    $nfe["status"] ?? "pendente",
                            ]);
                        }

                        error_log(
                            "? Salvou " . count($nfes) . " NF-e no banco"
                        );
                    } catch (\Exception $e) {
                        error_log(
                            "Erro ao salvar NF-e no banco: " . $e->getMessage()
                        );
                    }
                }
            } catch (\Exception $e) {
                error_log("Erro ao consultar DistDFe: " . $e->getMessage());
                error_log("Stack trace: " . $e->getTraceAsString());
                throw new \Exception(
                    "Erro na consulta SEFAZ: " . $e->getMessage()
                );
            }

            return [
                "sucesso" => true,
                "nfes" => $nfes,
                "total" => count($nfes),
                "mensagem" => "Consulta realizada com sucesso",
            ];
        } catch (\Exception $e) {
            error_log(
                "Erro ao consultar NF-e destinat?rio: " . $e->getMessage()
            );

            return [
                "sucesso" => false,
                "nfes" => [],
                "total" => 0,
                "mensagem" => $e->getMessage(),
            ];
        }
    }

    /**
     * Envia manifesta??o do destinat?rio para SEFAZ
     */
    public function manifestarDestinatario(
        array $empresa,
        string $chaveNfe,
        string $tipo
    ): array {
        try {
            $this->initialize();

            // Validar tipo de manifesta??o
            $tiposValidos = [
                "confirmacao",
                "desconhecimento",
                "nao_realizada",
                "ciencia",
            ];
            if (!in_array($tipo, $tiposValidos)) {
                throw new \Exception("Tipo de manifesta??o inv?lido");
            }

            // Configurar certificado
            $certificadoPath = $empresa["certificado_path"] ?? "";
            if (empty($certificadoPath)) {
                throw new \Exception("Certificado digital não configurado");
            }

            if (strpos($certificadoPath, \ROOT_PATH) !== 0) {
                $certificadoPath =
                    \ROOT_PATH . "/" . ltrim($certificadoPath, "/");
            }

            if (!file_exists($certificadoPath)) {
                throw new \Exception(
                    "Certificado digital não encontrado no caminho: " .
                    $certificadoPath
                );
            }

            $senhaCertificado = $empresa["senha_certificado"] ?? "";
            if (empty($senhaCertificado)) {
                throw new \Exception("Senha do certificado não configurada");
            }

            $ambiente =
                ($empresa["ambiente_nfe"] ?? "homologacao") === "producao"
                ? 1
                : 2;

            // Mapear tipo para c?digo da SEFAZ
            $tipoEventoMap = [
                "confirmacao" => "210200", // Confirma??o da Opera??o
                "ciencia" => "210210", // Ci?ncia da Opera??o
                "desconhecimento" => "210220", // Desconhecimento da Opera??o
                "nao_realizada" => "210240", // Opera??o não Realizada
            ];

            $tipoEvento = $tipoEventoMap[$tipo] ?? "210200";

            // Mapear CNPJ
            $cnpj = preg_replace(
                "/[^0-9]/",
                "",
                $empresa["cnpj"] ?? ($empresa["document"] ?? "")
            );
            $uf = $empresa["uf"] ?? ($empresa["state"] ?? "PE");

            // Configurar NFePHP
            try {
                if (!class_exists("\NFePHP\NFe\Tools")) {
                    throw new \Exception("NFePHP não est? instalado");
                }

                $config = [
                    "atualizacao" => date("Y-m-d H:i:s"),
                    "tpAmb" => $ambiente,
                    "razaosocial" =>
                        $empresa["razao_social"] ?? ($empresa["name"] ?? ""),
                    "siglaUF" => $uf,
                    "cnpj" => $cnpj,
                    "schemes" => "PL_009_V4",
                    "versao" => "4.00",
                    "tokenIBPT" => "AAAAAAA",
                    "CSC" => "",
                    "CSCid" => "",
                ];

                $tools = new \NFePHP\NFe\Tools(
                    json_encode($config),
                    \NFePHP\Common\Certificate::readPfx(
                        file_get_contents($certificadoPath),
                        $senhaCertificado
                    )
                );

                // Preparar dados do evento
                $justificativa = "";
                switch ($tipo) {
                    case "confirmacao":
                        $justificativa = "Confirmacao da Operacao";
                        break;
                    case "desconhecimento":
                        $justificativa = "Desconhecimento da Operacao";
                        break;
                    case "nao_realizada":
                        $justificativa = "Operacao nao Realizada";
                        break;
                    case "ciencia":
                        $justificativa = "Ciencia da Operacao";
                        break;
                }

                // Validar chave antes de enviar (deve ter exatamente 44 dígitos)
                $chaveNfeLimpa = preg_replace('/\D/', '', $chaveNfe);
                if (strlen($chaveNfeLimpa) !== 44) {
                    error_log("❌ ERRO: Chave NF-e inválida no manifestarDestinatario. Tamanho: " . strlen($chaveNfeLimpa) . ", Chave: {$chaveNfe}");
                    throw new \Exception("Chave da NF-e inválida. A chave deve ter exatamente 44 dígitos, mas foi recebida com " . strlen($chaveNfeLimpa) . " dígitos. Chave: {$chaveNfe}");
                }

                error_log("✅ Chave validada para manifestação: {$chaveNfeLimpa} (44 dígitos)");

                // Enviar manifesta??o usando a chave limpa
                $response = $tools->sefazManifesta(
                    $chaveNfeLimpa,
                    $tipoEvento,
                    $justificativa
                );

                // Processar resposta
                $st = new \NFePHP\NFe\Common\Standardize($response);
                $std = $st->toStd();

                $sucesso = $std->cStat == 135 || $std->cStat == 128 || $std->cStat == 573; // 573=Duplicidade (já manifestada)
                $protocolo = $std->infEvento->nProt ?? null;
                $mensagem =
                    $std->infEvento->xMotivo ??
                    ($std->xMotivo ?? "Manifestação enviada");

                // ============================================
                // APÓS MANIFESTAÇÃO: SALVAR NO BANCO
                // ============================================
                if ($sucesso) {
                    error_log("✅ Manifestação OK! Salvando registro no banco...");

                    // Buscar company_id da empresa
                    $companyId = null;
                    try {
                        $dbConn = \App\Core\Database::getInstance()->getConnection();

                        // Tentar pegar company_id diretamente da empresa se existir
                        if (isset($empresa["company_id"]) && !empty($empresa["company_id"])) {
                            $companyId = (int) $empresa["company_id"];
                            error_log("🔍 Company ID obtido do array empresa: {$companyId}");
                        } else {
                            // Tentar buscar pelo CNPJ
                            $cnpjEmpresa = preg_replace('/\D/', '', $empresa["cnpj"] ?? ($empresa["document"] ?? ""));
                            if (!empty($cnpjEmpresa)) {
                                $stmtCompany = $dbConn->prepare("SELECT id FROM companies WHERE document = :cnpj OR cnpj = :cnpj LIMIT 1");
                                $stmtCompany->execute(['cnpj' => $cnpjEmpresa]);
                                $companyRow = $stmtCompany->fetch();
                                if ($companyRow) {
                                    $companyId = (int) $companyRow["id"];
                                    error_log("🔍 Company ID encontrado pelo CNPJ: {$companyId}");
                                }
                            }

                            // Se ainda não encontrou, usar o primeiro disponível
                            if (!$companyId) {
                                $stmtCompany = $dbConn->prepare("SELECT id FROM companies LIMIT 1");
                                $stmtCompany->execute();
                                $companyRow = $stmtCompany->fetch();
                                if ($companyRow) {
                                    $companyId = (int) $companyRow["id"];
                                    error_log("🔍 Company ID usando primeiro disponível: {$companyId}");
                                } else {
                                    $companyId = 1; // Fallback
                                    error_log("⚠️ Nenhuma company encontrada, usando fallback: {$companyId}");
                                }
                            }
                        }

                        error_log("✅ Company ID final usado: {$companyId}");
                    } catch (\Exception $e) {
                        error_log("❌ ERRO ao buscar company_id: " . $e->getMessage());
                        error_log("Stack trace: " . $e->getTraceAsString());
                        $companyId = 1; // Fallback
                    }

                    // Tentar buscar procNFe para extrair dados completos
                    $xmlCompleto = null;
                    $numeroNFe = "";
                    $serieNFe = "";
                    $dataEmissao = null;
                    $valorTotal = 0;
                    $cnpjFornecedor = "";
                    $razaoSocialFornecedor = "";

                    try {
                        error_log("🔍 Buscando procNFe após manifestação...");
                        sleep(2); // Aguardar SEFAZ processar

                        $responseDist = $tools->sefazDistDFe(0, 0, $chaveNfe);
                        $stDist = new \NFePHP\NFe\Common\Standardize($responseDist);
                        $stdDist = $stDist->toStd();

                        error_log("🔍 Busca procNFe após manifestação - cStat: " . ($stdDist->cStat ?? "null"));

                        if (isset($stdDist->loteDistDFeInt) && isset($stdDist->loteDistDFeInt->docZip)) {
                            $docsDist = is_array($stdDist->loteDistDFeInt->docZip)
                                ? $stdDist->loteDistDFeInt->docZip
                                : [$stdDist->loteDistDFeInt->docZip];

                            foreach ($docsDist as $docDist) {
                                $conteudoDist = "";
                                if (is_object($docDist)) {
                                    if (isset($docDist->{'$value'})) {
                                        $conteudoDist = $docDist->{'$value'};
                                    } else {
                                        $conteudoDist = (string) $docDist;
                                    }
                                } else {
                                    $conteudoDist = (string) $docDist;
                                }

                                if (!empty($conteudoDist)) {
                                    $xmlDist = @gzdecode(base64_decode($conteudoDist));
                                    if ($xmlDist === false) {
                                        $xmlDist = base64_decode($conteudoDist);
                                    }

                                    // Verificar se é procNFe
                                    if (
                                        !empty($xmlDist) &&
                                        stripos($xmlDist, '<resNFe') === false &&
                                        strpos($xmlDist, $chaveNfe) !== false &&
                                        (stripos($xmlDist, '<nfeProc') !== false || stripos($xmlDist, '<det ') !== false)
                                    ) {
                                        error_log("✅ procNFe encontrado após manifestação!");
                                        $xmlCompleto = $xmlDist;

                                        // Extrair dados do XML
                                        try {
                                            $domSave = new \DOMDocument();
                                            $domSave->loadXML($xmlDist);

                                            $ide = $domSave->getElementsByTagName("ide")->item(0);
                                            $numeroNFe = $ide ? ($ide->getElementsByTagName("nNF")->item(0)->nodeValue ?? "") : "";
                                            $serieNFe = $ide ? ($ide->getElementsByTagName("serie")->item(0)->nodeValue ?? "") : "";
                                            $dataEmissao = $ide ? ($ide->getElementsByTagName("dhEmi")->item(0)->nodeValue ?? "") : "";

                                            $total = $domSave->getElementsByTagName("total")->item(0);
                                            $vTotal = $total ? $total->getElementsByTagName("vNF")->item(0) : null;
                                            $valorTotal = $vTotal ? (float) $vTotal->nodeValue : 0;

                                            // Extrair dados do emissor
                                            $dadosEmissor = self::extrairDadosEmissor($xmlDist);
                                            $cnpjFornecedor = $dadosEmissor["cnpj"] ?? "";
                                            $razaoSocialFornecedor = $dadosEmissor["razao_social"] ?? "";

                                            error_log("✅ Dados extraídos do XML: Número={$numeroNFe}, Série={$serieNFe}, Valor={$valorTotal}");
                                        } catch (\Exception $e) {
                                            error_log("⚠️ Erro ao extrair dados do XML: " . $e->getMessage());
                                        }

                                        break;
                                    }
                                }
                            }
                        }
                    } catch (\Exception $e) {
                        error_log("⚠️ Erro ao buscar procNFe após manifestação: " . $e->getMessage());
                    }

                    // SALVAR NO BANCO (mesmo que não tenha encontrado o procNFe)
                    try {
                        $dbConn = \App\Core\Database::getInstance()->getConnection();

                        // Converter data_emissao para formato MySQL
                        $dataEmissaoFormatada = null;
                        if (!empty($dataEmissao)) {
                            try {
                                $dataEmissaoFormatada = date("Y-m-d H:i:s", strtotime($dataEmissao));
                            } catch (\Exception $e) {
                                error_log("⚠️ Erro ao formatar data_emissao: " . $e->getMessage());
                            }
                        }

                        // Usar INSERT ... ON DUPLICATE KEY UPDATE
                        $stmtSave = $dbConn->prepare("
                            INSERT INTO nfe_recebidas (
                                company_id, chave_nfe, nsu, cnpj_fornecedor, razao_social_fornecedor,
                                numero_nfe, serie_nfe, data_emissao, valor_total,
                                tipo_documento, status_manifesto, data_manifesto, protocolo_manifesto,
                                xml_completo, created_at, updated_at
                            ) VALUES (
                                :company_id, :chave_nfe, :nsu, :cnpj_fornecedor, :razao_social_fornecedor,
                                :numero_nfe, :serie_nfe, :data_emissao, :valor_total,
                                :tipo_documento, :status_manifesto, :data_manifesto, :protocolo_manifesto,
                                :xml_completo, NOW(), NOW()
                            ) ON DUPLICATE KEY UPDATE
                                status_manifesto = VALUES(status_manifesto),
                                data_manifesto = VALUES(data_manifesto),
                                protocolo_manifesto = VALUES(protocolo_manifesto),
                                xml_completo = COALESCE(VALUES(xml_completo), xml_completo),
                                cnpj_fornecedor = COALESCE(NULLIF(VALUES(cnpj_fornecedor), ''), cnpj_fornecedor),
                                razao_social_fornecedor = COALESCE(NULLIF(VALUES(razao_social_fornecedor), ''), razao_social_fornecedor),
                                numero_nfe = COALESCE(NULLIF(VALUES(numero_nfe), ''), numero_nfe),
                                serie_nfe = COALESCE(NULLIF(VALUES(serie_nfe), ''), serie_nfe),
                                data_emissao = COALESCE(NULLIF(VALUES(data_emissao), ''), data_emissao),
                                valor_total = COALESCE(NULLIF(VALUES(valor_total), 0), valor_total),
                                updated_at = NOW()
                        ");

                        $resultado = $stmtSave->execute([
                            'company_id' => $companyId,
                            'chave_nfe' => $chaveNfe,
                            'nsu' => 0,
                            'cnpj_fornecedor' => $cnpjFornecedor,
                            'razao_social_fornecedor' => $razaoSocialFornecedor,
                            'numero_nfe' => $numeroNFe,
                            'serie_nfe' => $serieNFe,
                            'data_emissao' => $dataEmissaoFormatada,
                            'valor_total' => $valorTotal,
                            'tipo_documento' => 'NFe',
                            'status_manifesto' => 'confirmada',
                            'data_manifesto' => date("Y-m-d H:i:s"),
                            'protocolo_manifesto' => $protocolo,
                            'xml_completo' => $xmlCompleto
                        ]);

                        $rowsAffected = $stmtSave->rowCount();
                        error_log("✅ NF-e salva/atualizada no banco após manifestação! Chave: {$chaveNfe}, Linhas afetadas: {$rowsAffected}");

                        if ($rowsAffected === 0) {
                            error_log("⚠️ ATENÇÃO: Nenhuma linha foi afetada no INSERT/UPDATE. Pode ser problema de chave única.");
                        }
                    } catch (\Exception $e) {
                        error_log("❌ ERRO ao salvar NF-e no banco: " . $e->getMessage());
                        error_log("Stack trace: " . $e->getTraceAsString());
                    }
                }

                return [
                    "sucesso" => $sucesso,
                    "protocolo" => $protocolo,
                    "mensagem" => $mensagem,
                    "cStat" => $std->cStat ?? null,
                ];
            } catch (\Exception $e) {
                error_log(
                    "Erro ao enviar manifestação SEFAZ: " . $e->getMessage()
                );
                throw new \Exception(
                    "Erro ao comunicar com SEFAZ: " . $e->getMessage()
                );
            }
        } catch (\Exception $e) {
            error_log("Erro ao manifestar NF-e: " . $e->getMessage());

            return [
                "sucesso" => false,
                "protocolo" => null,
                "mensagem" => $e->getMessage(),
            ];
        }
    }

    /**
     * Download manual de uma NF-e específica pela chave
     */
    public static function downloadNFeManual(
        array $empresa,
        string $chaveNfe,
        $db
    ): array {
        try {
            error_log("=== DOWNLOAD MANUAL NF-e ===");
            error_log("Chave: {$chaveNfe}");
            error_log("Empresa CNPJ: " . ($empresa["cnpj"] ?? ""));

            // ============================================
            // PASSO 1: VERIFICAR SE JÁ TEMOS O XML NO BANCO
            // ============================================
            if ($db) {
                try {
                    $stmtXml = $db->prepare("
                        SELECT xml_completo, status_manifesto
                        FROM nfe_recebidas
                        WHERE chave_nfe = :chave_nfe
                        AND xml_completo IS NOT NULL
                        AND xml_completo != ''
                        AND LENGTH(xml_completo) > 1000
                        LIMIT 1
                    ");
                    $stmtXml->execute(["chave_nfe" => $chaveNfe]);
                    $nfeComXml = $stmtXml->fetch();

                    if ($nfeComXml && !empty($nfeComXml['xml_completo'])) {
                        $xmlDoDb = $nfeComXml['xml_completo'];

                        // Verificar se é procNFe válido (não resNFe)
                        if (
                            stripos($xmlDoDb, '<resNFe') === false &&
                            (stripos($xmlDoDb, '<nfeProc') !== false || stripos($xmlDoDb, '<det ') !== false)
                        ) {
                            error_log("✅ XML completo (procNFe) encontrado no banco de dados!");
                            return [
                                "sucesso" => true,
                                "xml_completo" => $xmlDoDb,
                            ];
                        }
                    }
                } catch (\Exception $e) {
                    error_log("⚠️ Erro ao buscar XML do banco: " . $e->getMessage());
                }
            }

            // ============================================
            // PASSO 2: IDENTIFICAR DESTINATÁRIO ANTES
            // ============================================
            // A SEFAZ só retorna procNFe completo quando o certificado pertence ao DESTINATÁRIO
            // Outros sistemas conseguem porque identificam o destinatário ANTES do download

            $empresaParaDownload = $empresa; // Começar com a empresa informada
            $cnpjEmitente = substr($chaveNfe, 6, 14); // CNPJ do emitente está na chave (posições 6-19)

            // 1. Tentar identificar destinatário no banco de dados PRIMEIRO
            if ($db) {
                try {
                    // Buscar NF-e já cadastrada com essa chave
                    $stmtNFe = $db->prepare("
                        SELECT
                            cnpj_destinatario,
                            destinatario_cnpj,
                            cnpj_emitente,
                            emitente_cnpj
                        FROM nfe_recebidas
                        WHERE chave_nfe = :chave_nfe
                        LIMIT 1
                    ");
                    $stmtNFe->execute(["chave_nfe" => $chaveNfe]);
                    $nfeExistente = $stmtNFe->fetch();

                    if ($nfeExistente) {
                        $cnpjDestinatario = $nfeExistente["cnpj_destinatario"] ?? $nfeExistente["destinatario_cnpj"] ?? null;
                        if (!empty($cnpjDestinatario)) {
                            $cnpjDestinatarioLimpo = preg_replace("/\D/", "", $cnpjDestinatario);
                            error_log("🔍 CNPJ do destinatário encontrado no banco: {$cnpjDestinatarioLimpo}");

                            // Buscar empresa do destinatário
                            $stmtDest = $db->prepare("
                                SELECT * FROM companies
                                WHERE REPLACE(REPLACE(REPLACE(REPLACE(document, '.', ''), '/', ''), '-', ''), ' ', '') = :cnpj
                                AND certificado_path IS NOT NULL
                                AND certificado_path != ''
                                LIMIT 1
                            ");
                            $stmtDest->execute(["cnpj" => $cnpjDestinatarioLimpo]);
                            $empresaDestinatario = $stmtDest->fetch();

                            if ($empresaDestinatario && isset($empresaDestinatario["senha_certificado"])) {
                                error_log("✅ Usando certificado do DESTINATÁRIO identificado no banco!");
                                $empresaParaDownload = $empresaDestinatario;
                                // Ajustar campos
                                if (!isset($empresaParaDownload["razao_social"]) && isset($empresaParaDownload["name"])) {
                                    $empresaParaDownload["razao_social"] = $empresaParaDownload["name"];
                                }
                                if (!isset($empresaParaDownload["cnpj"]) && isset($empresaParaDownload["document"])) {
                                    $empresaParaDownload["cnpj"] = $empresaParaDownload["document"];
                                }
                            }
                        }
                    }

                    // 2. Se não encontrou no banco, verificar se a empresa atual é o emitente
                    // Se for emitente, tentar encontrar o destinatário entre outras empresas
                    $cnpjEmpresaAtual = preg_replace("/\D/", "", $empresa["cnpj"] ?? $empresa["document"] ?? "");
                    if ($cnpjEmpresaAtual === $cnpjEmitente) {
                        error_log("⚠️ Empresa atual é o EMITENTE. Buscando destinatário entre outras empresas...");

                        // Buscar empresas com certificado que não sejam o emitente
                        $stmtOutras = $db->prepare("
                            SELECT * FROM companies
                            WHERE certificado_path IS NOT NULL
                            AND certificado_path != ''
                            AND REPLACE(REPLACE(REPLACE(REPLACE(document, '.', ''), '/', ''), '-', ''), ' ', '') != :cnpj_emitente
                            LIMIT 5
                        ");
                        $stmtOutras->execute(["cnpj_emitente" => $cnpjEmitente]);
                        $outrasEmpresas = $stmtOutras->fetchAll();

                        if (count($outrasEmpresas) === 1) {
                            // Se há apenas uma empresa com certificado que não é emitente, provavelmente é o destinatário
                            $empresaParaDownload = $outrasEmpresas[0];
                            if (!isset($empresaParaDownload["razao_social"]) && isset($empresaParaDownload["name"])) {
                                $empresaParaDownload["razao_social"] = $empresaParaDownload["name"];
                            }
                            if (!isset($empresaParaDownload["cnpj"]) && isset($empresaParaDownload["document"])) {
                                $empresaParaDownload["cnpj"] = $empresaParaDownload["document"];
                            }
                            error_log("✅ Assumindo que a única empresa com certificado (não emitente) é o destinatário: " . ($empresaParaDownload["cnpj"] ?? ""));
                        }
                    }
                } catch (\Exception $e) {
                    error_log("⚠️ Erro ao identificar destinatário no banco: " . $e->getMessage());
                }
            }

            // Ler certificado da empresa identificada (destinatário ou original)
            $certificadoPath = \ROOT_PATH . $empresaParaDownload["certificado_path"];
            if (!file_exists($certificadoPath)) {
                return [
                    "sucesso" => false,
                    "erro" => "Certificado não encontrado: " . $certificadoPath,
                ];
            }

            $certificadoConteudo = file_get_contents($certificadoPath);
            $senhaCertificado = $empresaParaDownload["senha_certificado"];
            $ambiente =
                ($empresaParaDownload["ambiente_nfe"] ?? "producao") === "producao" ? 1 : 2;

            // Configurar NFePHP
            $config = [
                "atualizacao" => date("Y-m-d H:i:s"),
                "tpAmb" => $ambiente,
                "razaosocial" => $empresaParaDownload["razao_social"] ?? "",
                "cnpj" => preg_replace("/\D/", "", $empresaParaDownload["cnpj"] ?? ""),
                "siglaUF" => "PE",
                "schemes" => "PL_009_V4",
                "versao" => "4.00",
                "tokenIBPT" => "",
                "CSC" => "",
                "CSCid" => "",
            ];

            $certificate = \NFePHP\Common\Certificate::readPfx(
                $certificadoConteudo,
                $senhaCertificado
            );
            $tools = new \NFePHP\NFe\Tools(json_encode($config), $certificate);

            // Download da NF-e completa
            error_log("Fazendo download da chave: {$chaveNfe}");
            $response = $tools->sefazDownload($chaveNfe);

            error_log(
                "Response raw (primeiros 1000 chars): " .
                substr($response, 0, 1000)
            );

            // Processar resposta usando Standardize
            $std = null;
            try {
                $st = new \NFePHP\NFe\Common\Standardize($response);
                $std = $st->toStd();
                $cStatValue = $std->cStat ?? "";
                $xMotivoValue = $std->xMotivo ?? "";
                error_log("cStat (via Standardize): {$cStatValue}");
                error_log("xMotivo (via Standardize): {$xMotivoValue}");
            } catch (\Exception $e) {
                error_log(
                    "⚠️ Erro ao usar Standardize, tentando DOM direto: " .
                    $e->getMessage()
                );
            }

            // Processar resposta também via DOM (fallback)
            $dom = new \DOMDocument();
            $dom->loadXML($response);

            // Verificar status via DOM também
            $cStat = $dom->getElementsByTagName("cStat")->item(0);
            $xMotivo = $dom->getElementsByTagName("xMotivo")->item(0);
            $cStatValueDom = $cStat ? $cStat->nodeValue : "";
            $xMotivoValueDom = $xMotivo ? $xMotivo->nodeValue : "";

            if (empty($cStatValue)) {
                $cStatValue = $cStatValueDom;
                $xMotivoValue = $xMotivoValueDom;
            }

            error_log("cStat: {$cStatValue}");
            error_log("xMotivo: {$xMotivoValue}");

            // Verificar status da resposta
            if ($cStatValue === "632") {
                return [
                    "sucesso" => false,
                    "erro" =>
                        "SEFAZ: [632] Rejeição - solicitação fora de prazo (mais de 90 dias). Peça o XML diretamente ao fornecedor.",
                ];
            }

            if ($cStatValue != "138") {
                return [
                    "sucesso" => false,
                    "erro" => "SEFAZ: [{$cStatValue}] {$xMotivoValue}",
                ];
            }

            // NF-e disponível (cStat = 138)
            // Extrair XML da NF-e - pode estar em diferentes formatos
            $xmlCompleto = null;

            // Tentar 1: procNFe direto
            $procNFe = $dom->getElementsByTagName("procNFe")->item(0);
            if ($procNFe) {
                $xmlTeste = $dom->saveXML($procNFe);
                $validacao = self::validarTipoXml($xmlTeste);
                if ($validacao["valido"] && $validacao["tipo"] !== "resNFe") {
                    $xmlCompleto = $xmlTeste;
                    error_log(
                        "✅ XML encontrado em procNFe direto - tipo: {$validacao["tipo"]}"
                    );
                }
            }

            // Tentar 2: docZip via Standardize
            if (!$xmlCompleto && isset($std) && isset($std->loteDistDFeInt)) {
                error_log("🔍 Tentando extrair via Standardize...");
                $loteDist = $std->loteDistDFeInt;
                $docs = is_array($loteDist->docZip)
                    ? $loteDist->docZip
                    : [$loteDist->docZip];

                foreach ($docs as $idx => $doc) {
                    $conteudoBase64Std = "";
                    if (is_object($doc)) {
                        if (isset($doc->{'$value'})) {
                            $conteudoBase64Std = $doc->{'$value'};
                        } elseif (method_exists($doc, "__toString")) {
                            $conteudoBase64Std = (string) $doc;
                        }
                    } else {
                        $conteudoBase64Std = (string) $doc;
                    }

                    if (!empty($conteudoBase64Std)) {
                        try {
                            $xmlComprimidoStd = base64_decode(
                                $conteudoBase64Std
                            );
                            $xmlTesteStd = @gzdecode($xmlComprimidoStd);
                            if ($xmlTesteStd === false) {
                                $xmlTesteStd = $xmlComprimidoStd;
                            }

                            $validacaoStd = self::validarTipoXml($xmlTesteStd);
                            if (
                                $validacaoStd["valido"] &&
                                $validacaoStd["tipo"] !== "resNFe"
                            ) {
                                $xmlCompleto = $xmlTesteStd;
                                error_log(
                                    "✅ XML completo encontrado via Standardize - docZip #{$idx}"
                                );
                                break;
                            }
                        } catch (\Exception $e) {
                            error_log(
                                "⚠️ Erro ao processar docZip #{$idx} via Standardize: " .
                                $e->getMessage()
                            );
                        }
                    }
                }
            }

            // Tentar 3: docZip via DOM
            if (!$xmlCompleto) {
                $docZips = $dom->getElementsByTagName("docZip");
                error_log(
                    "🔍 Total de docZip encontrados via DOM: {$docZips->length}"
                );

                for ($i = 0; $i < $docZips->length; $i++) {
                    $docZip = $docZips->item($i);
                    $schema = trim($docZip->getAttribute("schema") ?? "");
                    $conteudoBase64 = $docZip->nodeValue ?? "";

                    // Pular resNFe pelo schema
                    if (stripos($schema, "resNFe") !== false) {
                        continue;
                    }

                    if (empty($conteudoBase64)) {
                        continue;
                    }

                    try {
                        $xmlComprimido = base64_decode($conteudoBase64);
                        if ($xmlComprimido === false) {
                            continue;
                        }

                        $xmlTeste = @gzdecode($xmlComprimido);
                        if ($xmlTeste === false) {
                            $xmlTeste = $xmlComprimido;
                        }

                        $domTeste = new \DOMDocument();
                        if (!@$domTeste->loadXML($xmlTeste)) {
                            continue;
                        }

                        // Verificar se é resNFe no conteúdo
                        $temResNFe =
                            $domTeste->getElementsByTagName("resNFe")->length >
                            0;
                        if ($temResNFe) {
                            continue;
                        }

                        // Verificar se é procNFe, nfeProc ou NFe completo
                        $temProcNFe =
                            $domTeste->getElementsByTagName("procNFe")->length >
                            0;
                        $temNfeProc =
                            $domTeste->getElementsByTagName("nfeProc")->length >
                            0;
                        $temNFe =
                            $domTeste->getElementsByTagName("NFe")->length > 0;

                        if ($temProcNFe || $temNfeProc || $temNFe) {
                            $temDet =
                                $domTeste->getElementsByTagName("det")->length >
                                0;
                            if ($temDet) {
                                $xmlCompleto = $xmlTeste;
                                error_log(
                                    "✅ XML completo encontrado em docZip #{$i} - contém itens (det)"
                                );
                                break;
                            }
                        }
                    } catch (\Exception $e) {
                        error_log(
                            "⚠️ Erro ao processar docZip #{$i}: " .
                            $e->getMessage()
                        );
                        continue;
                    }
                }
            }

            // Tentar 4: procNFeZip
            if (!$xmlCompleto) {
                $procNFeZip = $dom->getElementsByTagName("procNFeZip")->item(0);
                if ($procNFeZip) {
                    $conteudoBase64 = $procNFeZip->nodeValue ?? "";
                    if (!empty($conteudoBase64)) {
                        $xmlComprimido = base64_decode($conteudoBase64);
                        $xmlTeste = gzdecode($xmlComprimido);
                        if ($xmlTeste !== false) {
                            $validacao = self::validarTipoXml($xmlTeste);
                            if (
                                $validacao["valido"] &&
                                $validacao["tipo"] !== "resNFe"
                            ) {
                                $xmlCompleto = $xmlTeste;
                                error_log(
                                    "✅ XML completo encontrado em procNFeZip"
                                );
                            }
                        }
                    }
                }
            }

            // Tentar 5: procNFeGrupoZip
            if (!$xmlCompleto) {
                $procNFeGrupoZip = $dom
                    ->getElementsByTagName("procNFeGrupoZip")
                    ->item(0);
                if ($procNFeGrupoZip) {
                    $nfeZip = $procNFeGrupoZip
                        ->getElementsByTagName("NFeZip")
                        ->item(0);
                    $protNFeZip = $procNFeGrupoZip
                        ->getElementsByTagName("protNFeZip")
                        ->item(0);

                    if ($nfeZip && $protNFeZip) {
                        $nfeBase64 = $nfeZip->nodeValue ?? "";
                        $protBase64 = $protNFeZip->nodeValue ?? "";

                        if (!empty($nfeBase64) && !empty($protBase64)) {
                            $nfeXml = gzdecode(base64_decode($nfeBase64));
                            $protXml = gzdecode(base64_decode($protBase64));

                            if ($nfeXml !== false && $protXml !== false) {
                                $xmlTeste =
                                    '<?xml version="1.0" encoding="UTF-8"?><nfeProc
    xmlns="http://www.portalfiscal.inf.br/nfe" versao="4.00">' .
                                    $nfeXml .
                                    $protXml .
                                    "</nfeProc>";
                                $validacao = self::validarTipoXml($xmlTeste);
                                if (
                                    $validacao["valido"] &&
                                    $validacao["tipo"] !== "resNFe"
                                ) {
                                    $xmlCompleto = $xmlTeste;
                                    error_log(
                                        "✅ XML completo montado a partir de procNFeGrupoZip"
                                    );
                                }
                            }
                        }
                    }
                }
            }

            // Se não encontrou XML completo, retornar erro
            if (!$xmlCompleto) {
                error_log(
                    "❌ XML completo (procNFe) não encontrado no download."
                );
                error_log(
                    "🔍 Tentamos buscar em: procNFe direto, docZip, procNFeZip, procNFeGrupoZip"
                );

                // Analisar a resposta para identificar o que foi retornado
                $docZips = $dom->getElementsByTagName("docZip");
                $schemasEncontrados = [];
                for ($i = 0; $i < $docZips->length; $i++) {
                    $docZip = $docZips->item($i);
                    $schema = $docZip->getAttribute("schema") ?? "sem schema";
                    $schemasEncontrados[] = $schema;
                }

                if (!empty($schemasEncontrados)) {
                    error_log(
                        "🔍 Schemas encontrados na resposta: " .
                        implode(", ", $schemasEncontrados)
                    );

                    // VERIFICAR SE APENAS resNFe FOI ENCONTRADO - BUSCAR procNFe VIA sefazDistDFe
                    // resNFe NÃO É PROCESSADO - VAMOS BUSCAR O procNFe COMPLETO
                    $apenasResNFe = true;
                    foreach ($schemasEncontrados as $schema) {
                        if (stripos($schema, "resNFe") === false) {
                            $apenasResNFe = false;
                            break;
                        }
                    }

                    if ($apenasResNFe) {
                        error_log(
                            "⚠️ Apenas resNFe foi encontrado. Tentando extrair CNPJ do destinatário do resNFe..."
                        );

                        // Extrair NSU e CNPJ do destinatário do resNFe retornado
                        $nsuDoResNFe = null;
                        $cnpjDestinatarioResNFe = null; // Variável para usar na mensagem de erro
                        try {
                            $docZipResNFe = $docZips->item(0);
                            if ($docZipResNFe) {
                                $nsuAttr = $docZipResNFe->getAttribute("NSU");
                                if (!empty($nsuAttr)) {
                                    $nsuDoResNFe = (int) $nsuAttr;
                                    error_log(
                                        "🔍 NSU extraído do resNFe: {$nsuDoResNFe}"
                                    );
                                }

                                // Extrair XML do resNFe para obter CNPJ do destinatário
                                $conteudoResNFe = $docZipResNFe->nodeValue ?? "";
                                if (!empty($conteudoResNFe)) {
                                    try {
                                        $xmlResNFeComprimido = base64_decode($conteudoResNFe);
                                        $xmlResNFe = @gzdecode($xmlResNFeComprimido);
                                        if ($xmlResNFe === false) {
                                            $xmlResNFe = $xmlResNFeComprimido;
                                        }

                                        if (!empty($xmlResNFe)) {
                                            // Tentar extrair CNPJ do destinatário do resNFe
                                            $dadosDestinatario = self::extrairDadosDestinatario($xmlResNFe);
                                            $cnpjDestinatarioResNFe = preg_replace("/\D/", "", $dadosDestinatario["cnpj"] ?? "");

                                            // Se não encontrou via extrairDadosDestinatario, tentar buscar diretamente no resNFe
                                            if (empty($cnpjDestinatarioResNFe)) {
                                                try {
                                                    $domResNFe = new \DOMDocument();
                                                    if ($domResNFe->loadXML($xmlResNFe)) {
                                                        // resNFe pode ter o CNPJ do destinatário em diferentes locais
                                                        // Tentar buscar por CNPJ ou CPF no XML
                                                        $cnpjNodes = $domResNFe->getElementsByTagName("CNPJ");
                                                        $cpfNodes = $domResNFe->getElementsByTagName("CPF");

                                                        // Procurar CNPJ que não seja do emitente (emitente está na chave)
                                                        $cnpjEmitente = substr($chaveNfe, 6, 14);
                                                        foreach ($cnpjNodes as $cnpjNode) {
                                                            $cnpjValor = preg_replace("/\D/", "", $cnpjNode->nodeValue);
                                                            if (!empty($cnpjValor) && $cnpjValor !== $cnpjEmitente) {
                                                                $cnpjDestinatarioResNFe = $cnpjValor;
                                                                error_log("🔍 CNPJ do destinatário encontrado no resNFe (via tag CNPJ): {$cnpjDestinatarioResNFe}");
                                                                break;
                                                            }
                                                        }

                                                        // Se não encontrou CNPJ, tentar CPF
                                                        if (empty($cnpjDestinatarioResNFe) && $cpfNodes->length > 0) {
                                                            $cpfValor = preg_replace("/\D/", "", $cpfNodes->item(0)->nodeValue);
                                                            if (!empty($cpfValor)) {
                                                                $cnpjDestinatarioResNFe = $cpfValor;
                                                                error_log("🔍 CPF do destinatário encontrado no resNFe: {$cnpjDestinatarioResNFe}");
                                                            }
                                                        }
                                                    }
                                                } catch (\Exception $e) {
                                                    error_log("⚠️ Erro ao buscar CNPJ diretamente no resNFe: " . $e->getMessage());
                                                }
                                            }

                                            // Se ainda não encontrou, tentar buscar no banco de dados pela chave da NF-e
                                            if (empty($cnpjDestinatarioResNFe) && $db) {
                                                try {
                                                    // Tentar diferentes nomes de coluna dependendo da estrutura da tabela
                                                    $stmtChave = $db->prepare("
    SELECT cnpj_destinatario, cnpj_emitente, destinatario_cnpj, emitente_cnpj
    FROM nfe_recebidas
    WHERE chave_nfe = :chave_nfe
    LIMIT 1
    ");
                                                    $stmtChave->execute(["chave_nfe" => $chaveNfe]);
                                                    $nfeRow = $stmtChave->fetch();
                                                    if ($nfeRow) {
                                                        // Tentar diferentes campos
                                                        $cnpjDest = $nfeRow["cnpj_destinatario"] ?? $nfeRow["destinatario_cnpj"] ?? null;
                                                        if (!empty($cnpjDest)) {
                                                            $cnpjDestinatarioResNFe = preg_replace("/\D/", "", $cnpjDest);
                                                            error_log("🔍 CNPJ do destinatário encontrado no banco de dados (nfe_recebidas): {$cnpjDestinatarioResNFe}");
                                                        }
                                                    }
                                                } catch (\Exception $e) {
                                                    error_log("⚠️ Erro ao buscar CNPJ do destinatário no banco: " . $e->getMessage());
                                                }
                                            }

                                            // Se ainda não encontrou e temos a chave, tentar buscar empresas que não sejam o emitente
                                            // e que tenham certificado cadastrado (pode ser o destinatário)
                                            if (empty($cnpjDestinatarioResNFe) && $db) {
                                                try {
                                                    $cnpjEmitente = substr($chaveNfe, 6, 14);
                                                    $cnpjEmitenteLimpo = preg_replace("/\D/", "", $cnpjEmitente);

                                                    // Buscar empresas com certificado que não sejam o emitente
                                                    $stmtEmpresas = $db->prepare("
    SELECT document, name
    FROM companies
    WHERE certificado_path IS NOT NULL
    AND certificado_path != ''
    AND REPLACE(REPLACE(REPLACE(REPLACE(document, '.', ''), '/', ''), '-', ''), ' ', '') != :cnpj_emitente
    LIMIT 10
    ");
                                                    $stmtEmpresas->execute(["cnpj_emitente" => $cnpjEmitenteLimpo]);
                                                    $empresasComCertificado = $stmtEmpresas->fetchAll();

                                                    if (count($empresasComCertificado) === 1) {
                                                        // Se há apenas uma empresa com certificado que não é o emitente, provavelmente é o destinatário
                                                        $empresaUnica = $empresasComCertificado[0];
                                                        $cnpjDestinatarioResNFe = preg_replace("/\D/", "", $empresaUnica["document"]);
                                                        error_log("🔍 Assumindo que a única empresa com certificado (que não é emitente) é o destinatário:
    {$cnpjDestinatarioResNFe}");
                                                    } elseif (count($empresasComCertificado) > 1) {
                                                        error_log("⚠️ Múltiplas empresas com certificado encontradas. Não é possível determinar qual é o destinatário
    automaticamente.");
                                                    }
                                                } catch (\Exception $e) {
                                                    error_log("⚠️ Erro ao buscar empresas alternativas: " . $e->getMessage());
                                                }
                                            }

                                            if (!empty($cnpjDestinatarioResNFe)) {
                                                error_log("🔍 CNPJ do destinatário extraído do resNFe: {$cnpjDestinatarioResNFe}");

                                                // Tentar buscar empresa do destinatário no banco
                                                if ($db) {
                                                    try {
                                                        $stmtDest = $db->prepare("
    SELECT * FROM companies
    WHERE REPLACE(REPLACE(REPLACE(REPLACE(document, '.', ''), '/', ''), '-', ''), ' ', '') = :cnpj
    AND certificado_path IS NOT NULL
    AND certificado_path != ''
    LIMIT 1
    ");
                                                        $stmtDest->execute(["cnpj" => $cnpjDestinatarioResNFe]);
                                                        $empresaDestinatario = $stmtDest->fetch();

                                                        if ($empresaDestinatario && isset($empresaDestinatario["senha_certificado"])) {
                                                            error_log("✅ Empresa do destinatário encontrada! Tentando download novamente com certificado do destinatário...");

                                                            // Ajustar campos da empresa
                                                            if (!isset($empresaDestinatario["razao_social"]) && isset($empresaDestinatario["name"])) {
                                                                $empresaDestinatario["razao_social"] = $empresaDestinatario["name"];
                                                            }
                                                            if (!isset($empresaDestinatario["cnpj"]) && isset($empresaDestinatario["document"])) {
                                                                $empresaDestinatario["cnpj"] = $empresaDestinatario["document"];
                                                            }

                                                            // Tentar download novamente com certificado do destinatário
                                                            $certificadoPathDest = \ROOT_PATH . $empresaDestinatario["certificado_path"];
                                                            if (file_exists($certificadoPathDest)) {
                                                                $certificadoConteudoDest = file_get_contents($certificadoPathDest);
                                                                $senhaCertificadoDest = $empresaDestinatario["senha_certificado"];
                                                                $ambienteDest = ($empresaDestinatario["ambiente_nfe"] ?? "producao") === "producao" ? 1 : 2;

                                                                $configDest = [
                                                                    "atualizacao" => date("Y-m-d H:i:s"),
                                                                    "tpAmb" => $ambienteDest,
                                                                    "razaosocial" => $empresaDestinatario["razao_social"] ?? "",
                                                                    "cnpj" => preg_replace("/\D/", "", $empresaDestinatario["cnpj"] ?? ""),
                                                                    "siglaUF" => "PE",
                                                                    "schemes" => "PL_009_V4",
                                                                    "versao" => "4.00",
                                                                    "tokenIBPT" => "",
                                                                    "CSC" => "",
                                                                    "CSCid" => "",
                                                                ];

                                                                $certificateDest = \NFePHP\Common\Certificate::readPfx(
                                                                    $certificadoConteudoDest,
                                                                    $senhaCertificadoDest
                                                                );
                                                                $toolsDest = new \NFePHP\NFe\Tools(json_encode($configDest), $certificateDest);

                                                                error_log("🔄 Tentando download novamente com certificado do destinatário...");
                                                                $responseDest = $toolsDest->sefazDownload($chaveNfe);

                                                                // Processar resposta
                                                                $stDest = new \NFePHP\NFe\Common\Standardize($responseDest);
                                                                $stdDest = $stDest->toStd();
                                                                $cStatDest = $stdDest->cStat ?? "";

                                                                if ($cStatDest === "138") {
                                                                    $domDest = new \DOMDocument();
                                                                    $domDest->loadXML($responseDest);

                                                                    // Tentar extrair procNFe da nova resposta
                                                                    $procNFeDest = $domDest->getElementsByTagName("procNFe")->item(0);
                                                                    if ($procNFeDest) {
                                                                        $xmlTesteDest = $domDest->saveXML($procNFeDest);
                                                                        $validacaoDest = self::validarTipoXml($xmlTesteDest);
                                                                        if ($validacaoDest["valido"] && $validacaoDest["tipo"] !== "resNFe") {
                                                                            $xmlCompleto = $xmlTesteDest;
                                                                            error_log("✅✅✅ XML completo encontrado usando certificado do destinatário!");
                                                                        }
                                                                    }

                                                                    // Se não encontrou em procNFe direto, tentar docZip
                                                                    if (!$xmlCompleto) {
                                                                        $docZipsDest = $domDest->getElementsByTagName("docZip");
                                                                        for ($j = 0; $j < $docZipsDest->length; $j++) {
                                                                            $docZipDest = $docZipsDest->item($j);
                                                                            $schemaDest = trim($docZipDest->getAttribute("schema") ?? "");
                                                                            if (stripos($schemaDest, "resNFe") !== false) {
                                                                                continue;
                                                                            }
                                                                            $conteudoDest = $docZipDest->nodeValue ?? "";
                                                                            if (!empty($conteudoDest)) {
                                                                                $xmlComprimidoDest = base64_decode($conteudoDest);
                                                                                $xmlTesteDest = @gzdecode($xmlComprimidoDest);
                                                                                if ($xmlTesteDest === false) {
                                                                                    $xmlTesteDest = $xmlComprimidoDest;
                                                                                }
                                                                                $validacaoDest = self::validarTipoXml($xmlTesteDest);
                                                                                if ($validacaoDest["valido"] && $validacaoDest["tipo"] !== "resNFe" && $validacaoDest["tem_itens"]) {
                                                                                    $xmlCompleto = $xmlTesteDest;
                                                                                    error_log("✅✅✅ XML completo encontrado em docZip usando certificado do destinatário!");
                                                                                    break;
                                                                                }
                                                                            }
                                                                        }
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    } catch (\Exception $e) {
                                                        error_log("⚠️ Erro ao buscar empresa do destinatário: " . $e->getMessage());
                                                    }
                                                }
                                            }
                                        }
                                    } catch (\Exception $e) {
                                        error_log("⚠️ Erro ao extrair CNPJ do destinatário do resNFe: " . $e->getMessage());
                                    }
                                }
                            }
                        } catch (\Exception $e) {
                            error_log(
                                "⚠️ Erro ao extrair NSU do resNFe: " .
                                $e->getMessage()
                            );
                        }
                    }

                    // Se encontrou XML completo com certificado do destinatário, pular busca via DistDFe
                    if ($xmlCompleto) {
                        error_log("✅ XML completo obtido com certificado do destinatário. Pulando busca via sefazDistDFe.");
                    } else {
                        error_log(
                            "⚠️ Apenas resNFe foi encontrado. Tentando buscar procNFe..."
                        );

                        // Buscar procNFe via sefazDistDFe
                        // O procNFe só estará disponível se a NF-e foi manifestada (Ciência/Confirmação)
                        $nsuParaBusca = $nsuDoResNFe ?? 0;
                        error_log(
                            "🔄 Buscando procNFe completo via sefazDistDFe..."
                        );
                        try {
                            // Estratégia 1: Buscar documentos A PARTIR do NSU do resNFe
                            // O procNFe é disponibilizado com NSU MAIOR que o resNFe após manifestação
                            if ($nsuParaBusca > 0) {
                                error_log(
                                    "🔍 Tentativa 1: Buscando documentos com NSU > {$nsuParaBusca}"
                                );

                                try {
                                    // ultNSU = NSU do resNFe, busca documentos NOVOS (NSU > ultNSU)
                                    $responseDist = $tools->sefazDistDFe((int) $nsuParaBusca, 0, null);
                                    $stDist = new \NFePHP\NFe\Common\Standardize($responseDist);
                                    $stdDist = $stDist->toStd();

                                    error_log("🔍 cStat busca por NSU: " . ($stdDist->cStat ?? "null"));
                                    error_log("🔍 xMotivo: " . ($stdDist->xMotivo ?? "null"));

                                    // Processar se encontrou documentos
                                    if (isset($stdDist->loteDistDFeInt) && isset($stdDist->loteDistDFeInt->docZip)) {
                                        $docsDist = is_array($stdDist->loteDistDFeInt->docZip)
                                            ? $stdDist->loteDistDFeInt->docZip
                                            : [$stdDist->loteDistDFeInt->docZip];

                                        error_log("🔍 Total de documentos novos encontrados: " . count($docsDist));

                                        foreach ($docsDist as $idxDoc => $docDist) {
                                            $conteudoDist = "";
                                            $schemaDist = "";

                                            if (is_object($docDist)) {
                                                // Extrair schema
                                                if (isset($docDist->{'@attributes'})) {
                                                    $schemaDist = $docDist->{'@attributes'}["schema"] ?? "";
                                                } elseif (isset($docDist->schema)) {
                                                    $schemaDist = $docDist->schema;
                                                }

                                                if (isset($docDist->{'$value'})) {
                                                    $conteudoDist = $docDist->{'$value'};
                                                } else {
                                                    $conteudoDist = (string) $docDist;
                                                }
                                            } else {
                                                $conteudoDist = (string) $docDist;
                                            }

                                            error_log("🔍 Doc #{$idxDoc} - Schema: {$schemaDist}");

                                            if (!empty($conteudoDist)) {
                                                $xmlDist = @gzdecode(base64_decode($conteudoDist));
                                                if ($xmlDist === false) {
                                                    $xmlDist = base64_decode($conteudoDist);
                                                }

                                                // Verificar se é procNFe E contém a chave que buscamos
                                                if (
                                                    !empty($xmlDist) &&
                                                    stripos($xmlDist, "<resNFe") === false &&
                                                    strpos($xmlDist, $chaveNfe) !== false &&
                                                    (stripos($xmlDist, "<nfeProc") !== false || stripos($xmlDist, "<det ") !== false)
                                                ) {
                                                    error_log("✅ procNFe encontrado via busca desde NSU!");
                                                    $xmlCompleto = $xmlDist;
                                                    break;
                                                }
                                            }
                                        }
                                    }
                                } catch (\Exception $e) {
                                    error_log("⚠️ Erro na busca por NSU: " . $e->getMessage());
                                }
                            }

                            // Estratégia 2: Se não encontrou, buscar por chave
                            if (!$xmlCompleto) {
                                error_log(
                                    "🔍 Tentativa 2: Buscando via CHAVE: {$chaveNfe}"
                                );

                                try {
                                    $responseDist = $tools->sefazDistDFe(0, 0, $chaveNfe);
                                    $stDist = new \NFePHP\NFe\Common\Standardize(
                                        $responseDist
                                    );
                                    $stdDist = $stDist->toStd();

                                    error_log(
                                        "🔍 cStat da busca DistDFe por chave: " .
                                        ($stdDist->cStat ?? "null")
                                    );
                                    error_log(
                                        "🔍 xMotivo: " .
                                        ($stdDist->xMotivo ?? "null")
                                    );

                                    // Processar documentos retornados
                                    if (
                                        isset($stdDist->loteDistDFeInt) &&
                                        isset($stdDist->loteDistDFeInt->docZip)
                                    ) {
                                        $docsDist = is_array(
                                            $stdDist->loteDistDFeInt->docZip
                                        )
                                            ? $stdDist->loteDistDFeInt->docZip
                                            : [$stdDist->loteDistDFeInt->docZip];

                                        error_log(
                                            "🔍 Total de documentos encontrados na busca por CHAVE: " .
                                            count($docsDist)
                                        );

                                        foreach ($docsDist as $index => $docDist) {
                                            $conteudoDist = "";
                                            $schemaDist = "";

                                            if (is_object($docDist)) {
                                                if (isset($docDist->{'@attributes'})) {
                                                    $schemaDist = $docDist->{'@attributes'}["schema"] ?? "";
                                                } elseif (isset($docDist->schema)) {
                                                    $schemaDist = $docDist->schema;
                                                }

                                                if (isset($docDist->{'$value'})) {
                                                    $conteudoDist = $docDist->{'$value'};
                                                } elseif (method_exists($docDist, "__toString")) {
                                                    $conteudoDist = (string) $docDist;
                                                } else {
                                                    $conteudoDist = (string) $docDist;
                                                }
                                            } else {
                                                $conteudoDist = (string) $docDist;
                                            }

                                            // PULAR resNFe - apenas processar procNFe
                                            if (stripos($schemaDist, "resNFe") !== false) {
                                                error_log("⏭️ Pulando documento #{$index}: É resNFe - buscando procNFe");
                                                continue;
                                            }

                                            error_log("🔍 Processando documento #{$index} - Schema: {$schemaDist}");

                                            if (!empty($conteudoDist)) {
                                                try {
                                                    $xmlDist = @gzdecode(base64_decode($conteudoDist));
                                                    if ($xmlDist === false) {
                                                        $xmlDist = base64_decode($conteudoDist);
                                                    }

                                                    if (empty($xmlDist)) {
                                                        continue;
                                                    }

                                                    // Rejeitar se for resNFe
                                                    if (
                                                        stripos($xmlDist, "<resNFe") !== false ||
                                                        stripos($xmlDist, "resNFe") !== false
                                                    ) {
                                                        error_log("❌ Pulando documento #{$index}: Detectado resNFe no conteúdo");
                                                        continue;
                                                    }

                                                    // Verificar se é a NF-e que buscamos
                                                    if (strpos($xmlDist, $chaveNfe) !== false) {
                                                        error_log("✅ Chave da NF-e encontrada no documento #{$index}!");

                                                        $validacaoDist = self::validarTipoXml($xmlDist);
                                                        error_log("🔍 Validação - Tipo: {$validacaoDist['tipo']}, Válido: " .
                                                            ($validacaoDist['valido'] ? 'sim' : 'não') .
                                                            ", Tem itens: " . ($validacaoDist['tem_itens'] ? 'sim' : 'não'));

                                                        if (
                                                            $validacaoDist['valido'] &&
                                                            $validacaoDist['tipo'] !== 'resNFe' &&
                                                            $validacaoDist['tem_itens']
                                                        ) {
                                                            $xmlCompleto = $xmlDist;
                                                            error_log("✅✅✅ procNFe COMPLETO encontrado via sefazDistDFe por CHAVE!");
                                                            break;
                                                        } else {
                                                            error_log("⚠️ Documento não é procNFe válido ou não tem itens");
                                                        }
                                                    }
                                                } catch (\Exception $e) {
                                                    error_log("⚠️ Erro ao processar documento #{$index}: " . $e->getMessage());
                                                }
                                            }
                                        }
                                    } else {
                                        error_log("⚠️ Nenhum documento encontrado na busca por CHAVE");
                                    }
                                } catch (\Exception $e) {
                                    error_log("⚠️ Erro na busca por CHAVE via DistDFe: " . $e->getMessage());
                                }
                            }
                        } catch (\Exception $e) {
                            error_log("⚠️ Erro na busca de procNFe via sefazDistDFe: " . $e->getMessage());
                        }

                        // Se não encontrou o procNFe
                        if (!$xmlCompleto) {
                            error_log("❌ procNFe não encontrado - NF-e precisa de manifestação");

                            return [
                                "sucesso" => false,
                                "erro" => "O XML completo (procNFe) não está disponível. " .
                                    "Para importar esta NF-e, é necessário fazer a MANIFESTAÇÃO primeiro.\n\n" .
                                    "Acesse o Monitor de NF-e e clique no botão de 'Ciência' (👁️) ou 'Confirmar' (✔️) para manifestar a NF-e.\n" .
                                    "Após a manifestação, aguarde alguns segundos e tente importar novamente.",
                                "codigo_erro" => "MANIFESTACAO_NECESSARIA",
                                "requer_manifestacao" => true,
                            ];
                        }
                    }

                    // Se chegou aqui, XML foi encontrado via sefazDownload
                    // Continuar com validação final

                    // VALIDAÇÃO FINAL: Verificar novamente que o XML encontrado NÃO é resNFe
                    $validacaoFinal = self::validarTipoXml($xmlCompleto);

                    if (
                        !$validacaoFinal["valido"] ||
                        $validacaoFinal["tipo"] === "resNFe"
                    ) {
                        error_log(
                            "❌ VALIDAÇÃO FINAL: XML encontrado é resNFe ou inválido. Rejeitando..."
                        );
                        error_log(
                            "🔍 Tipo detectado: {$validacaoFinal["tipo"]}"
                        );

                        return [
                            "sucesso" => false,
                            "erro" => "O XML retornado é resNFe ou inválido. O sistema NÃO processa resNFe - APENAS procNFe (XML
                completo) é aceito.",
                            "codigo_erro" => "RESNFE_REJEITADO",
                            "limite_sefaz" => true,
                        ];
                    }

                    if (!$validacaoFinal["tem_itens"]) {
                        error_log(
                            "⚠️ AVISO: XML parece ser procNFe mas não contém itens (det). Pode estar incompleto."
                        );
                    } else {
                        error_log("✅ VALIDAÇÃO FINAL: XML completo (procNFe) validado com sucesso - tipo:
                {$validacaoFinal["tipo"]},
                contém itens: sim");
                    }

                    // Extrair dados da NF-e
                    $domNFe = new \DOMDocument();
                    $cnpjFornecedor = "";
                    $razaoSocialFornecedor = "";
                    $numeroNFe = "";
                    $serieNFe = "";
                    $dataEmissao = "";
                    $valorTotal = 0;

                    $dadosEmissor = self::extrairDadosEmissor($xmlCompleto);
                    $cnpjFornecedor = $dadosEmissor["cnpj"];
                    $razaoSocialFornecedor = $dadosEmissor["razao_social"];

                    // Extrair dados do destinatário e mostrar
                    $dadosDestinatario = self::extrairDadosDestinatario(
                        $xmlCompleto
                    );
                    $cnpjCertificado = preg_replace(
                        "/\D/",
                        "",
                        $empresa["cnpj"] ?? ""
                    );
                    $cnpjDestinatario = preg_replace(
                        "/\D/",
                        "",
                        $dadosDestinatario["cnpj"] ?? ""
                    );

                    error_log(
                        "════════════════════════════════════════════════════════════"
                    );
                    error_log(
                        "📋 DADOS DO DESTINATÁRIO (tag <dest>) - VALIDAÇÃO FINAL:"
                    );
                    error_log(
                        "════════════════════════════════════════════════════════════"
                    );
                    error_log(
                        "CNPJ/CPF do Destinatário (somente números): {$cnpjDestinatario}"
                    );
                    error_log(
                        "CNPJ/CPF do Destinatário (original): " .
                        ($dadosDestinatario["cnpj"] ?? "NÃO ENCONTRADO")
                    );
                    error_log(
                        "Razão Social/Nome do Destinatário: " .
                        ($dadosDestinatario["razao_social"] ??
                            "NÃO
                    ENCONTRADO")
                    );
                    error_log(
                        "════════════════════════════════════════════════════════════"
                    );
                    error_log(
                        "🔐 CNPJ DO CERTIFICADO DIGITAL (somente números): {$cnpjCertificado}"
                    );
                    error_log(
                        "🔐 CNPJ DO CERTIFICADO DIGITAL (original): " .
                        ($empresa["cnpj"] ?? "NÃO INFORMADO")
                    );

                    if (!empty($cnpjCertificado) && !empty($cnpjDestinatario)) {
                        if ($cnpjCertificado === $cnpjDestinatario) {
                            error_log(
                                "✅✅✅ CONFIRMADO: CNPJ do certificado CORRESPONDE ao destinatário! ✅✅✅"
                            );
                        } else {
                            error_log(
                                "⚠️⚠️⚠️ CNPJ do certificado NÃO corresponde ao destinatário ⚠️⚠️⚠️"
                            );
                            error_log(" Certificado: {$cnpjCertificado}");
                            error_log(" Destinatário: {$cnpjDestinatario}");
                        }
                    } else {
                        if (empty($cnpjDestinatario)) {
                            error_log(
                                "❌ AVISO: Não foi possível extrair CNPJ do destinatário da tag <dest>"
                            );
                        }
                    }
                    error_log(
                        "════════════════════════════════════════════════════════════"
                    );

                    if ($domNFe->loadXML($xmlCompleto)) {
                        $total = $domNFe
                            ->getElementsByTagName("total")
                            ->item(0);
                        $ide = $domNFe->getElementsByTagName("ide")->item(0);

                        $numeroNFe = $ide
                            ? $ide->getElementsByTagName("nNF")->item(0)
                                ->nodeValue ?? ""
                            : "";
                        $serieNFe = $ide
                            ? $ide->getElementsByTagName("serie")->item(0)
                                ->nodeValue ?? ""
                            : "";
                        $dataEmissao = $ide
                            ? $ide->getElementsByTagName("dhEmi")->item(0)
                                ->nodeValue ?? ""
                            : "";

                        $vTotal = $total
                            ? $total->getElementsByTagName("vNF")->item(0)
                            : null;
                        $valorTotal = $vTotal ? (float) $vTotal->nodeValue : 0;

                        error_log("✅ Dados extraídos do XML completo");
                    }

                    error_log(
                        "🔍 Fornecedor extraído: {$razaoSocialFornecedor} - CNPJ: {$cnpjFornecedor}"
                    );

                    // EXTRAIR CHAVE COMPLETA DO XML (44 dígitos) - CRÍTICO!
                    $chaveNfeCompleta = "";
                    try {
                        $domChave = new \DOMDocument();
                        if ($domChave->loadXML($xmlCompleto)) {
                            // PRIORIDADE 1: Atributo Id da tag <NFe>
                            $nfeNode = $domChave->getElementsByTagName("NFe")->item(0);
                            if ($nfeNode) {
                                $idNFe = $nfeNode->getAttribute("Id") ?? "";
                                if (!empty($idNFe) && strpos($idNFe, 'NFe') === 0) {
                                    $chaveTemp = str_replace("NFe", "", $idNFe);
                                    if (strlen($chaveTemp) === 44) {
                                        $chaveNfeCompleta = $chaveTemp;
                                        error_log("✅ Chave completa extraída do XML (NFe->Id): {$chaveNfeCompleta}");
                                    }
                                }
                            }

                            // PRIORIDADE 2: infProt->Id
                            if (empty($chaveNfeCompleta) || strlen($chaveNfeCompleta) !== 44) {
                                $infProt = $domChave->getElementsByTagName("infProt")->item(0);
                                if ($infProt) {
                                    $idProt = $infProt->getAttribute("Id") ?? "";
                                    if (!empty($idProt) && strpos($idProt, 'NFe') === 0) {
                                        $chaveTemp = str_replace("NFe", "", $idProt);
                                        if (strlen($chaveTemp) === 44) {
                                            $chaveNfeCompleta = $chaveTemp;
                                            error_log("✅ Chave completa extraída do XML (infProt->Id): {$chaveNfeCompleta}");
                                        }
                                    }
                                }
                            }

                            // PRIORIDADE 3: Tag <chNFe>
                            if (empty($chaveNfeCompleta) || strlen($chaveNfeCompleta) !== 44) {
                                $chNFeNode = $domChave->getElementsByTagName("chNFe")->item(0);
                                if ($chNFeNode && strlen($chNFeNode->nodeValue) === 44) {
                                    $chaveNfeCompleta = preg_replace('/\D/', '', $chNFeNode->nodeValue);
                                    if (strlen($chaveNfeCompleta) === 44) {
                                        error_log("✅ Chave completa extraída do XML (chNFe): {$chaveNfeCompleta}");
                                    }
                                }
                            }
                        }
                    } catch (\Exception $e) {
                        error_log("⚠️ Erro ao extrair chave do XML: " . $e->getMessage());
                    }

                    // Se não conseguiu extrair do XML, usar a chave conhecida APENAS se tiver 44 dígitos
                    if (empty($chaveNfeCompleta) || strlen($chaveNfeCompleta) !== 44) {
                        $chaveLimpa = preg_replace('/\D/', '', $chaveNfe);
                        if (strlen($chaveLimpa) === 44) {
                            $chaveNfeCompleta = $chaveLimpa;
                            error_log("✅ Usando chave conhecida (44 dígitos): {$chaveNfeCompleta}");
                        } else {
                            error_log("❌ ERRO: Não foi possível extrair chave completa de 44 dígitos do XML. Chave conhecida tem apenas " . strlen($chaveLimpa) . " dígitos: {$chaveLimpa}");
                            // Continuar mesmo assim, mas vai dar erro na manifestação
                            $chaveNfeCompleta = $chaveLimpa;
                        }
                    }

                    // Usar a chave completa extraída
                    $chaveNfe = $chaveNfeCompleta;

                    // Determinar company_id do contexto
                    $stmtCompany = $db->prepare(
                        "SELECT id FROM companies LIMIT 1"
                    );
                    $stmtCompany->execute();
                    $companyRow = $stmtCompany->fetch();
                    $companyId = $companyRow ? $companyRow["id"] : 1;

                    // Salvar no banco
                    try {
                        $stmt = $db->prepare("
                        INSERT INTO nfe_recebidas (
                        company_id, chave_nfe, nsu, cnpj_fornecedor, razao_social_fornecedor,
                        numero_nfe, serie_nfe, data_emissao, valor_total,
                        tipo_documento, status_manifesto, xml_completo, created_at, updated_at
                        ) VALUES (
                        :company_id, :chave_nfe, :nsu, :cnpj_fornecedor, :razao_social_fornecedor,
                        :numero_nfe, :serie_nfe, :data_emissao, :valor_total,
                        :tipo_documento, :status_manifesto, :xml_completo, NOW(), NOW()
                        ) ON DUPLICATE KEY UPDATE
                        xml_completo = COALESCE(VALUES(xml_completo), xml_completo),
                        chave_nfe = COALESCE(NULLIF(VALUES(chave_nfe), ''), chave_nfe),
                        cnpj_fornecedor = COALESCE(NULLIF(VALUES(cnpj_fornecedor), ''), NULLIF(cnpj_fornecedor, ''),
                        VALUES(cnpj_fornecedor)),
                        razao_social_fornecedor = COALESCE(NULLIF(VALUES(razao_social_fornecedor), ''),
                        NULLIF(razao_social_fornecedor, ''), VALUES(razao_social_fornecedor)),
                        updated_at = NOW()
                        ");

                        $stmt->execute([
                            "company_id" => $companyId,
                            "chave_nfe" => $chaveNfe,
                            "nsu" => 0,
                            "cnpj_fornecedor" => $cnpjFornecedor,
                            "razao_social_fornecedor" => $razaoSocialFornecedor,
                            "numero_nfe" => $numeroNFe,
                            "serie_nfe" => $serieNFe,
                            "data_emissao" => $dataEmissao,
                            "valor_total" => $valorTotal,
                            "tipo_documento" => "NFe",
                            "status_manifesto" => "pendente",
                            "xml_completo" => $xmlCompleto,
                        ]);

                        error_log("NF-e salva no banco com sucesso");
                        error_log("✅ Retornando resultado com XML completo");

                        return [
                            "sucesso" => true,
                            "xml_completo" => $xmlCompleto,
                            "nfe" => [
                                "chave_nfe" => $chaveNfe,
                                "cnpj_fornecedor" => $cnpjFornecedor,
                                "razao_social_fornecedor" => $razaoSocialFornecedor,
                                "numero_nfe" => $numeroNFe,
                                "serie_nfe" => $serieNFe,
                                "valor_total" => $valorTotal,
                                "data_emissao" => $dataEmissao,
                            ],
                        ];
                    } catch (\Exception $e) {
                        error_log(
                            "Erro ao salvar NF-e no banco: " . $e->getMessage()
                        );
                        return [
                            "sucesso" => false,
                            "erro" =>
                                "Erro ao salvar NF-e no banco: " .
                                $e->getMessage(),
                        ];
                    }
                }
            }
        } catch (\Exception $e) {
            error_log("Erro no download manual: " . $e->getMessage());
            error_log("Stack trace: " . $e->getTraceAsString());
            return [
                "sucesso" => false,
                "erro" => "Erro ao fazer download: " . $e->getMessage(),
            ];
        }
    }
}