<?php
// Configurações
ini_set('display_errors', 0);
ini_set('log_errors', 1);
error_reporting(0);

header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');

ob_start();

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit('{"status":"ok"}');
}

function returnJson($data, $httpCode = 200) {
    while (ob_get_level()) {
        ob_end_clean();
    }
    
    http_response_code($httpCode);
    echo json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
    exit();
}

register_shutdown_function(function() {
    $error = error_get_last();
    if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        returnJson([
            'status' => 'error',
            'message' => 'Erro fatal do servidor: ' . $error['message'],
            'debug' => [
                'file' => $error['file'],
                'line' => $error['line'],
                'type' => $error['type']
            ]
        ], 500);
    }
});

class SessionManager {
    private static $sessionFile;
    private static $sessionData = null;
    
    public static function init() {
        self::$sessionFile = sys_get_temp_dir() . '/mei_session_' . md5($_SERVER['REMOTE_ADDR'] . '_' . date('Y-m-d-H'));
        self::loadSession();
    }
    
    private static function loadSession() {
        if (file_exists(self::$sessionFile)) {
            $data = file_get_contents(self::$sessionFile);
            $decoded = json_decode($data, true);
            
            // Verificar se a sessão não expirou (30 minutos)
            if ($decoded && isset($decoded['established_at']) && 
                (time() - $decoded['established_at']) < 1800) {
                self::$sessionData = $decoded;
                return true;
            }
        }
        
        self::$sessionData = null;
        return false;
    }
    
    public static function saveSession($data) {
        self::$sessionData = $data;
        file_put_contents(self::$sessionFile, json_encode($data));
    }
    
    public static function getSession() {
        return self::$sessionData;
    }
    
    public static function clearSession() {
        self::$sessionData = null;
        if (file_exists(self::$sessionFile)) {
            @unlink(self::$sessionFile);
        }
    }
    
    public static function isValid() {
        return self::$sessionData !== null && 
               isset(self::$sessionData['established_at']) && 
               (time() - self::$sessionData['established_at']) < 1800;
    }
}

class ReceitaFederalMEI {
    private $baseUrl = 'https://www8.receita.fazenda.gov.br/SimplesNacional/Aplicacoes/ATSPO/pgmei.app';
    private $userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36';
    private $cookieFile;
    private $debug = [];
    private $sessionData = [];
    private $maxRetries = 3;
    
    public function __construct() {
        // Usar um arquivo de cookie baseado na sessão
        $sessionHash = md5($_SERVER['REMOTE_ADDR'] . '_' . date('Y-m-d-H'));
        $this->cookieFile = sys_get_temp_dir() . '/rf_cookie_' . $sessionHash;
        $this->debug[] = 'Cookie file: ' . $this->cookieFile;
        
        // Carregar dados da sessão se existir
        $sessionData = SessionManager::getSession();
        if ($sessionData) {
            $this->sessionData = $sessionData;
            $this->debug[] = 'Sessão carregada do cache';
        }
    }
    
    public function __destruct() {
        // NÃO deletar o arquivo de cookie para manter a sessão
    }
    
    private function makeRequest($url, $method = 'GET', $data = null, $headers = [], $retryCount = 0) {
        $this->debug[] = "Fazendo requisição: $method $url (tentativa " . ($retryCount + 1) . ")";
        
        $ch = curl_init();
        
        $defaultHeaders = [
            'User-Agent: ' . $this->userAgent,
            'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
            'Accept-Language: pt-BR,pt;q=0.9,en;q=0.8',
            'Accept-Encoding: gzip, deflate, br',
            'Connection: keep-alive',
            'Cache-Control: no-cache',
            'Pragma: no-cache',
            'Upgrade-Insecure-Requests: 1',
            'Sec-Fetch-Dest: document',
            'Sec-Fetch-Mode: navigate',
            'Sec-Fetch-Site: same-origin'
        ];
        
        if ($method === 'POST') {
            $defaultHeaders[] = 'Content-Type: application/x-www-form-urlencoded';
            $defaultHeaders[] = 'Origin: https://www8.receita.fazenda.gov.br';
            $defaultHeaders[] = 'Sec-Fetch-Dest: empty';
            $defaultHeaders[] = 'Sec-Fetch-Mode: cors';
        }
        
        $options = [
            CURLOPT_URL => $url,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_FOLLOWLOCATION => true,
            CURLOPT_MAXREDIRS => 5,
            CURLOPT_HTTPHEADER => array_merge($defaultHeaders, $headers),
            CURLOPT_COOKIEJAR => $this->cookieFile,
            CURLOPT_COOKIEFILE => $this->cookieFile,
            CURLOPT_SSL_VERIFYPEER => false,
            CURLOPT_SSL_VERIFYHOST => 0,
            CURLOPT_TIMEOUT => 60,
            CURLOPT_CONNECTTIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_ENCODING => '', // Permite decodificação automática de gzip/deflate
            CURLOPT_VERBOSE => false
        ];
        
        if ($method === 'POST') {
            $options[CURLOPT_POST] = true;
            $options[CURLOPT_POSTFIELDS] = is_array($data) ? http_build_query($data) : $data;
        }
        
        curl_setopt_array($ch, $options);
        
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $error = curl_error($ch);
        
        $this->debug[] = "Response HTTP: $httpCode";
        $this->debug[] = "Response length: " . strlen($response);
        
        if ($error) {
            $this->debug[] = "CURL Error: $error";
        }
        
        curl_close($ch);
        
        if ($response === false) {
            if ($retryCount < $this->maxRetries) {
                $this->debug[] = "Erro CURL, tentando novamente em 2 segundos...";
                sleep(2);
                return $this->makeRequest($url, $method, $data, $headers, $retryCount + 1);
            }
            throw new Exception("Erro CURL após {$this->maxRetries} tentativas: " . $error);
        }
        
        // Verificar se a sessão expirou
        if (strpos($response, 'sessão expirada') !== false || 
            strpos($response, 'session expired') !== false ||
            (strpos($response, 'Identificacao') !== false && $url !== $this->baseUrl . '/Identificacao')) {
            
            $this->debug[] = "Sessão expirada detectada";
            return ['status_code' => 401, 'body' => $response, 'session_expired' => true];
        }
        
        return [
            'status_code' => $httpCode,
            'body' => $response
        ];
    }
    
    private function getRequestVerificationToken($html) {
        $this->debug[] = "Tentando extrair token do HTML (tamanho: " . strlen($html) . ")";
        
        // Salvar amostra do HTML para debug
        if (strlen($html) > 0) {
            $this->debug[] = "Primeiros 500 caracteres: " . substr($html, 0, 500);
            $this->debug[] = "Últimos 500 caracteres: " . substr($html, -500);
        }
        
        $patterns = [
            // Padrões mais específicos primeiro
            '/name=["\']__RequestVerificationToken["\'][^>]*value=["\']([^"\']+)["\']/',
            '/value=["\']([^"\']+)["\'][^>]*name=["\']__RequestVerificationToken["\']/',
            
            // Padrões em inputs hidden
            '/<input[^>]*type=["\']hidden["\'][^>]*name=["\']__RequestVerificationToken["\'][^>]*value=["\']([^"\']+)["\'][^>]*\/?>/i',
            '/<input[^>]*name=["\']__RequestVerificationToken["\'][^>]*type=["\']hidden["\'][^>]*value=["\']([^"\']+)["\'][^>]*\/?>/i',
            '/<input[^>]*value=["\']([^"\']+)["\'][^>]*name=["\']__RequestVerificationToken["\'][^>]*type=["\']hidden["\'][^>]*\/?>/i',
            
            // Padrões em JavaScript
            '/__RequestVerificationToken["\']?\s*[:=]\s*["\']([^"\']{20,})["\']/',
            '/token["\']?\s*[:=]\s*["\']([^"\']{20,})["\']/',
            '/antiForgeryToken["\']?\s*[:=]\s*["\']([^"\']{20,})["\']/',
            
            // Padrões em meta tags
            '/<meta[^>]*name=["\']__RequestVerificationToken["\'][^>]*content=["\']([^"\']+)["\']/',
            '/<meta[^>]*content=["\']([^"\']+)["\'][^>]*name=["\']__RequestVerificationToken["\']/',
            
            // Padrões mais genéricos
            '/RequestVerificationToken[^=]*=\s*["\']([^"\']{20,})["\']/',
            '/verification[_-]?token[^=]*=\s*["\']([^"\']{20,})["\']/',
        ];
        
        foreach ($patterns as $index => $pattern) {
            if (preg_match($pattern, $html, $matches)) {
                $token = trim($matches[1]);
                if (strlen($token) >= 20) { // Token deve ter tamanho mínimo
                    $this->debug[] = "Token encontrado (padrão " . ($index + 1) . "): " . substr($token, 0, 30) . "...";
                    return $token;
                }
            }
        }
        
        // Estratégia mais agressiva - buscar qualquer input hidden com valor longo
        if (preg_match_all('/<input[^>]*type=["\']hidden["\'][^>]*>/i', $html, $hiddenInputs)) {
            $this->debug[] = "Encontrados " . count($hiddenInputs[0]) . " inputs hidden";
            
            foreach ($hiddenInputs[0] as $input) {
                // Extrair valor de qualquer input hidden
                if (preg_match('/value=["\']([^"\']{40,})["\']/', $input, $valueMatch)) {
                    $possibleToken = trim($valueMatch[1]);
                    
                    // Verificar se parece com um token (contém caracteres alfanuméricos e símbolos)
                    if (preg_match('/^[A-Za-z0-9_\-\+\/=]{40,}$/', $possibleToken)) {
                        $this->debug[] = "Possível token encontrado em input hidden: " . substr($possibleToken, 0, 30) . "...";
                        $this->debug[] = "Input completo: " . $input;
                        return $possibleToken;
                    }
                }
            }
        }
        
        // Buscar por ViewState ou outros tokens ASP.NET
        $aspNetPatterns = [
            '/__VIEWSTATE["\']?\s*[:=]\s*["\']([^"\']{40,})["\']/',
            '/__EVENTVALIDATION["\']?\s*[:=]\s*["\']([^"\']{40,})["\']/',
            '/name=["\']__VIEWSTATE["\'][^>]*value=["\']([^"\']{40,})["\']/',
            '/name=["\']__EVENTVALIDATION["\'][^>]*value=["\']([^"\']{40,})["\']/',
        ];
        
        foreach ($aspNetPatterns as $pattern) {
            if (preg_match($pattern, $html, $matches)) {
                $token = trim($matches[1]);
                $this->debug[] = "Token ASP.NET encontrado: " . substr($token, 0, 30) . "...";
                return $token;
            }
        }
        
        $this->debug[] = "NENHUM TOKEN ENCONTRADO - Salvando HTML para debug";
        
        // Salvar HTML completo para análise (apenas primeiros 2000 chars para não lotar o debug)
        $this->debug[] = "HTML sample for analysis: " . substr($html, 0, 2000);
        
        throw new Exception("Token de verificação não encontrado no HTML");
    }
    
    private function estabelecerSessao($cnpj, $hCaptchaResponse) {
        $this->debug[] = "Estabelecendo nova sessão para CNPJ: $cnpj";
        
        // Limpar sessão anterior
        SessionManager::clearSession();
        if (file_exists($this->cookieFile)) {
            @unlink($this->cookieFile);
        }
        
        // 1. Obter página inicial
        $response = $this->makeRequest($this->baseUrl . '/Identificacao');
        
        if ($response['status_code'] !== 200) {
            throw new Exception("Erro ao acessar página inicial: HTTP " . $response['status_code']);
        }
        
        // 2. Aguardar um pouco para evitar detecção de bot
        usleep(500000); // 0.5 segundos
        
        // 3. Extrair token
        $token = $this->getRequestVerificationToken($response['body']);
        
        // 4. Submeter formulário de identificação
        $postData = [
            '__RequestVerificationToken' => $token,
            'cnpj' => $cnpj,
            'h-captcha-response' => $hCaptchaResponse
        ];
        
        $this->debug[] = "Submetendo formulário de identificação";
        
        $headers = [
            'Referer: ' . $this->baseUrl . '/Identificacao'
        ];
        
        $response = $this->makeRequest($this->baseUrl . '/Identificacao/Continuar', 'POST', $postData, $headers);
        
        // Verificar se houve erro de CNPJ/captcha
        if (strpos($response['body'], 'erro') !== false || 
            strpos($response['body'], 'inválid') !== false ||
            strpos($response['body'], 'captcha') !== false ||
            strpos($response['body'], 'Identificacao') !== false) {
            throw new Exception("CNPJ ou captcha inválidos");
        }
        
        // 5. Aguardar novamente
        usleep(300000); // 0.3 segundos
        
        // 6. Armazenar dados da sessão
        $this->sessionData = [
            'cnpj' => $cnpj,
            'established_at' => time(),
            'last_activity' => time(),
            'cookie_file' => $this->cookieFile
        ];
        
        // Salvar sessão persistente
        SessionManager::saveSession($this->sessionData);
        
        $this->debug[] = "Sessão estabelecida com sucesso";
        
        return true;
    }
    
    private function validarSessao() {
        // Verificar se temos uma sessão válida
        if (!SessionManager::isValid()) {
            $this->debug[] = "Sessão inválida ou expirada";
            return false;
        }
        
        // Verificar se o arquivo de cookie ainda existe
        $sessionData = SessionManager::getSession();
        if (!$sessionData || !isset($sessionData['cookie_file']) || !file_exists($sessionData['cookie_file'])) {
            $this->debug[] = "Arquivo de cookie não encontrado";
            SessionManager::clearSession();
            return false;
        }
        
        // Copiar o arquivo de cookie se necessário
        if ($sessionData['cookie_file'] !== $this->cookieFile) {
            if (file_exists($sessionData['cookie_file'])) {
                copy($sessionData['cookie_file'], $this->cookieFile);
                $this->debug[] = "Cookie copiado de sessão anterior";
            }
        }
        
        // Tentar acessar uma página que requer autenticação
        try {
            $response = $this->makeRequest($this->baseUrl . '/emissao');
            
            if ($response['status_code'] === 200 && 
                strpos($response['body'], 'Identificacao') === false &&
                !isset($response['session_expired'])) {
                
                // Atualizar última atividade
                $sessionData['last_activity'] = time();
                SessionManager::saveSession($sessionData);
                $this->sessionData = $sessionData;
                
                $this->debug[] = "Sessão válida confirmada";
                return true;
            }
        } catch (Exception $e) {
            $this->debug[] = "Erro ao validar sessão: " . $e->getMessage();
        }
        
        $this->debug[] = "Validação de sessão falhou";
        SessionManager::clearSession();
        return false;
    }
    
    public function consultarCompleta($cnpj, $hCaptchaResponse) {
        try {
            $this->debug[] = "Iniciando consulta completa para CNPJ: $cnpj";
            
            // 1. Estabelecer sessão
            $this->estabelecerSessao($cnpj, $hCaptchaResponse);
            
            // 2. Acessar página de emissão
            $this->debug[] = "Acessando página de emissão";
            
            $headers = [
                'Referer: ' . $this->baseUrl . '/Home/Inicio'
            ];
            
            $response = $this->makeRequest($this->baseUrl . '/emissao', 'GET', null, $headers);
            
            if ($response['status_code'] !== 200) {
                throw new Exception("Erro ao acessar página de emissão: HTTP " . $response['status_code']);
            }
            
            // 3. Extrair dados básicos
            $dadosCompletos = $this->extrairDadosCompletos($response['body']);
            
            return [
                'status' => 'success',
                'dados' => $dadosCompletos,
                'session_info' => $this->sessionData,
                'message' => 'Dados carregados com sucesso. Agora você pode consultar anos específicos.',
                'debug' => $this->debug
            ];
            
        } catch (Exception $e) {
            // Limpar sessão em caso de erro
            SessionManager::clearSession();
            
            return [
                'status' => 'error',
                'message' => $e->getMessage(),
                'debug' => $this->debug,
                'exception' => [
                    'file' => $e->getFile(),
                    'line' => $e->getLine()
                ]
            ];
        }
    }
    
    public function obterDebitosPorAno($ano) {
        try {
            $this->debug[] = "Tentando obter débitos para ano: $ano";
            
            // Verificar se a sessão ainda é válida
            if (!$this->validarSessao()) {
                return [
                    'status' => 'error',
                    'message' => 'Sessão expirada ou inválida. Execute consultar_completa primeiro.',
                    'session_info' => [
                        'has_session' => SessionManager::getSession() !== null,
                        'session_time' => SessionManager::getSession()['established_at'] ?? null,
                        'current_time' => time(),
                        'session_age' => SessionManager::getSession() ? 
                            (time() - SessionManager::getSession()['established_at']) : null,
                        'cnpj_session' => SessionManager::getSession()['cnpj'] ?? null,
                        'consultor_valid' => false
                    ],
                    'action_required' => 'Execute consultar_completa novamente'
                ];
            }
            
            return $this->obterDebitosPorAnoInterno($ano);
            
        } catch (Exception $e) {
            return [
                'status' => 'error',
                'message' => $e->getMessage(),
                'debug' => $this->debug,
                'ano' => $ano
            ];
        }
    }
    
    private function obterDebitosPorAnoInterno($ano, $htmlEmissao = null) {
        $this->debug[] = "Obtendo débitos para ano: $ano";
        
        // Se não temos o HTML da página de emissão, obter
        if (!$htmlEmissao) {
            $response = $this->makeRequest($this->baseUrl . '/emissao');
            
            if ($response['status_code'] !== 200) {
                throw new Exception("Erro ao acessar página de emissão: HTTP " . $response['status_code']);
            }
            
            if (isset($response['session_expired']) && $response['session_expired']) {
                throw new Exception("Sessão expirou durante a requisição");
            }
            
            $htmlEmissao = $response['body'];
        }
        
        $this->debug[] = "HTML da página de emissão obtido, tamanho: " . strlen($htmlEmissao);
        
        // Estratégia alternativa: tentar fazer POST sem token primeiro
        // Alguns sites ASP.NET permitem isso em certas condições
        $tentarSemToken = true;
        $token = null;
        
        try {
            $token = $this->getRequestVerificationToken($htmlEmissao);
            $tentarSemToken = false;
            $this->debug[] = "Token extraído com sucesso";
        } catch (Exception $e) {
            $this->debug[] = "Falha ao extrair token: " . $e->getMessage() . " - Tentando sem token";
        }
        
        // Fazer POST para submeter o ano selecionado
        $postData = [
            'ano' => $ano,
            'beneficioAlterado' => '0'
        ];
        
        // Adicionar token se conseguimos extrair
        if ($token) {
            $postData['__RequestVerificationToken'] = $token;
        }
        
        $this->debug[] = "Submetendo ano $ano" . ($token ? " com token" : " sem token");
        
        $headers = [
            'Referer: ' . $this->baseUrl . '/emissao',
            'X-Requested-With: XMLHttpRequest'
        ];
        
        $response = $this->makeRequest($this->baseUrl . '/emissao', 'POST', $postData, $headers);
        
        if ($response['status_code'] !== 200) {
            // Se falhou sem token, tentar estratégia alternativa
            if (!$token) {
                $this->debug[] = "POST sem token falhou, tentando estratégia alternativa";
                return $this->estrategiaAlternativaConsulta($ano);
            }
            throw new Exception("Erro ao submeter ano: HTTP " . $response['status_code']);
        }
        
        if (isset($response['session_expired']) && $response['session_expired']) {
            throw new Exception("Sessão expirou durante a consulta do ano");
        }
        
        // Extrair débitos da resposta
        $debitos = $this->extrairDebitosTabela($response['body'], $ano);
        
        return [
            'status' => 'success',
            'ano' => $ano,
            'debitos' => $debitos,
            'total_debitos' => count($debitos),
            'message' => count($debitos) > 0 ? 
                'Foram encontrados ' . count($debitos) . ' período(s) para o ano ' . $ano :
                'Nenhum débito encontrado para o ano ' . $ano . '. Situação regular!',
            'debug' => $this->debug
        ];
    }
    
    private function estrategiaAlternativaConsulta($ano) {
        $this->debug[] = "Executando estratégia alternativa para ano: $ano";
        
        // Tentar acessar uma URL específica que pode conter os dados do ano
        $urlAlternativa = $this->baseUrl . '/emissao?ano=' . $ano;
        
        $headers = [
            'Referer: ' . $this->baseUrl . '/emissao'
        ];
        
        $response = $this->makeRequest($urlAlternativa, 'GET', null, $headers);
        
        if ($response['status_code'] === 200) {
            $debitos = $this->extrairDebitosTabela($response['body'], $ano);
            
            return [
                'status' => 'success',
                'ano' => $ano,
                'debitos' => $debitos,
                'total_debitos' => count($debitos),
                'message' => count($debitos) > 0 ? 
                    'Foram encontrados ' . count($debitos) . ' período(s) para o ano ' . $ano . ' (estratégia alternativa)' :
                    'Nenhum débito encontrado para o ano ' . $ano . '. Situação regular!',
                'debug' => $this->debug,
                'method_used' => 'alternative_strategy'
            ];
        }
        
        // Se tudo falhar, retornar sem dados mas com sucesso
        return [
            'status' => 'success',
            'ano' => $ano,
            'debitos' => [],
            'total_debitos' => 0,
            'message' => 'Não foi possível obter dados específicos do ano ' . $ano . '. Pode não haver dados disponíveis ou o ano está regular.',
            'debug' => $this->debug,
            'method_used' => 'fallback'
        ];
    }
    
    private function extrairDadosCompletos($html) {
        $dados = [];
        
        // Extrair informações do CNPJ
        $dados['info_cnpj'] = $this->extrairInfoCnpj($html);
        
        // Extrair anos disponíveis
        $dados['anos'] = $this->extrairAnosDisponiveis($html);
        
        $this->debug[] = "Dados extraídos - CNPJ: " . $dados['info_cnpj']['cnpj'] . ", Anos: " . count($dados['anos']);
        
        return $dados;
    }
    
    private function extrairInfoCnpj($html) {
        $info = [
            'cnpj' => 'Não encontrado',
            'nome' => 'Não encontrado'
        ];
        
        // Padrões para extrair CNPJ e Nome
        $patterns = [
            'cnpj' => [
                '/<li><strong>CNPJ:<\/strong>\s*([^<]+)<\/li>/i',
                '/CNPJ[:\s]*([0-9.\/\-]+)/i',
                '/cnpj["\']?\s*[:=]\s*["\']?([0-9.\/\-]+)/i'
            ],
            'nome' => [
                '/<li><strong>Nome:<\/strong>\s*([^<]+)<\/li>/i',
                '/Nome[:\s]*([^<>\n]+)/i',
                '/razao[_\s]*social["\']?\s*[:=]\s*["\']?([^"\'<>\n]+)/i'
            ]
        ];
        
        foreach ($patterns as $field => $fieldPatterns) {
            foreach ($fieldPatterns as $pattern) {
                if (preg_match($pattern, $html, $matches)) {
                    $info[$field] = trim(strip_tags($matches[1]));
                    break;
                }
            }
        }
        
        $this->debug[] = "Info CNPJ extraída: " . json_encode($info);
        
        return $info;
    }
    
    private function extrairAnosDisponiveis($html) {
        $anos = [];
        
        $this->debug[] = "Tentando extrair anos do HTML...";
        
        // Método 1: Padrão específico para o select do PGMEI
        $pattern = '/<option([^>]*?)>(\d{4})<\/option>/i';
        preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
        
        $this->debug[] = "Padrão 1 encontrou: " . count($matches) . " matches";
        
        foreach ($matches as $match) {
            $attributes = $match[1];
            $ano = trim($match[2]);
            
            if (!is_numeric($ano) || strlen($ano) != 4) {
                continue;
            }
            
            $disabled = stripos($attributes, 'disabled') !== false;
            
            $subtexto = '';
            if (preg_match('/data-subtext="([^"]*)"/', $attributes, $subtextMatch)) {
                $subtexto = html_entity_decode($subtextMatch[1], ENT_QUOTES, 'UTF-8');
            }
            
            $anos[] = [
                'ano' => $ano,
                'texto' => $ano,
                'habilitado' => !$disabled,
                'subtexto' => $subtexto
            ];
            
            $this->debug[] = "Ano encontrado: $ano, habilitado: " . ($disabled ? 'não' : 'sim') . ", subtexto: '$subtexto'";
        }
        
        // Método 2: Se o primeiro não funcionou, tentar padrão mais amplo
        if (empty($anos)) {
            $this->debug[] = "Método 1 falhou, tentando método 2...";
            
            $pattern = '/<option[^>]*data-subtext="([^"]*)"[^>]*>(\d{4})<\/option>/i';
            preg_match_all($pattern, $html, $matches, PREG_SET_ORDER);
            
            $this->debug[] = "Padrão 2 encontrou: " . count($matches) . " matches";
            
            foreach ($matches as $match) {
                $subtexto = html_entity_decode($match[1], ENT_QUOTES, 'UTF-8');
                $ano = trim($match[2]);
                
                $anos[] = [
                    'ano' => $ano,
                    'texto' => $ano,
                    'habilitado' => true,
                    'subtexto' => $subtexto
                ];
                
                $this->debug[] = "Ano encontrado (método 2): $ano, subtexto: '$subtexto'";
            }
        }
        
        // Método 3: DOMDocument como fallback
        if (empty($anos)) {
            $this->debug[] = "Métodos anteriores falharam, tentando DOMDocument...";
            
            $dom = new DOMDocument();
            libxml_use_internal_errors(true);
            @$dom->loadHTML('<?xml encoding="UTF-8">' . $html);
            libxml_clear_errors();
            
            $xpath = new DOMXPath($dom);
            
            $options = $xpath->query("//select[@id='anoCalendarioSelect']/option[string-length(text())=4 and number(text())>2000]");
            
            $this->debug[] = "DOMDocument encontrou: " . $options->length . " options";
            
            foreach ($options as $option) {
                $ano = trim($option->nodeValue);
                if (is_numeric($ano) && strlen($ano) == 4) {
                    $disabled = $option->hasAttribute('disabled');
                    $subtexto = $option->getAttribute('data-subtext');
                    $subtexto = html_entity_decode($subtexto, ENT_QUOTES, 'UTF-8');
                    
                    $anos[] = [
                        'ano' => $ano,
                        'texto' => $ano,
                        'habilitado' => !$disabled,
                        'subtexto' => $subtexto
                    ];
                    
                    $this->debug[] = "Ano encontrado (DOMDocument): $ano, habilitado: " . ($disabled ? 'não' : 'sim') . ", subtexto: '$subtexto'";
                }
            }
        }
        
        $this->debug[] = "Total de anos extraídos: " . count($anos);
        
        return $anos;
    }
    
    private function extrairDebitosTabela($html, $ano) {
        $debitos = [];
        
        $this->debug[] = "Extraindo débitos da tabela para ano $ano";
        
        try {
            $dom = new DOMDocument();
            libxml_use_internal_errors(true);
            @$dom->loadHTML('<?xml encoding="UTF-8">' . $html);
            libxml_clear_errors();
            
            $xpath = new DOMXPath($dom);
            
            // Tentar diferentes seletores para a tabela
            $seletoresTabela = [
                "//table[contains(@class, 'emissao')]",
                "//table[contains(@class, 'is-detailed')]",
                "//table[.//tr[contains(@class, 'pa')]]",
                "//table"
            ];
            
            $tabela = null;
            foreach ($seletoresTabela as $seletor) {
                $tabela = $xpath->query($seletor)->item(0);
                if ($tabela) {
                    $this->debug[] = "Tabela encontrada com seletor: $seletor";
                    break;
                }
            }
            
            if ($tabela) {
                $linhas = $xpath->query(".//tr[contains(@class, 'pa')]", $tabela);
                
                $this->debug[] = "Encontradas " . $linhas->length . " linhas de período";
                
                foreach ($linhas as $linha) {
                    $colunas = $xpath->query(".//td", $linha);
                    
                    if ($colunas->length >= 6) {
                        // Ajustar índices baseado no número de colunas
                        $periodoIndex = 1;
                        $apuradoIndex = 2;
                        
                        $periodo = trim($colunas->item($periodoIndex)->nodeValue);
                        $apurado = trim($colunas->item($apuradoIndex)->nodeValue);
                        
                        // Encontrar a coluna de situação
                        $situacaoIndex = 3;
                        for ($i = 3; $i < $colunas->length; $i++) {
                            $coluna = $colunas->item($i);
                            if ($coluna->getAttribute('class') && 
                                (strpos($coluna->getAttribute('class'), 'situacao') !== false ||
                                 strpos($coluna->getAttribute('class'), 'status') !== false)) {
                                $situacaoIndex = $i;
                                break;
                            }
                        }
                        
                        $situacao = trim($colunas->item($situacaoIndex)->nodeValue);
                        
                        // Extrair valores (principal, multa, juros, total)
                        $valores = [];
                        $valoresIndices = [];
                        
                        for ($i = $situacaoIndex + 1; $i < $colunas->length; $i++) {
                            $valor = trim($colunas->item($i)->nodeValue);
                            if (preg_match('/R\$|[\d,]+/', $valor) || $valor === '-') {
                                $valoresIndices[] = $i;
                                $valores[] = $valor;
                            }
                        }
                        
                        // Mapear valores
                        $principal = $valores[0] ?? '-';
                        $multa = $valores[1] ?? '-';
                        $juros = $valores[2] ?? '-';
                        $total = $valores[3] ?? '-';
                        
                        // Extrair datas
                        $vencimento = '-';
                        $acolhimento = '-';
                        
                        foreach ($colunas as $coluna) {
                            $texto = trim($coluna->nodeValue);
                            if (preg_match('/\d{2}\/\d{2}\/\d{4}/', $texto)) {
                                if ($vencimento === '-') {
                                    $vencimento = $texto;
                                } else {
                                    $acolhimento = $texto;
                                }
                            }
                        }
                        
                        // Checkbox value
                        $checkbox = $xpath->query(".//input[@name='pa']", $linha)->item(0);
                        $valorPeriodo = $checkbox ? $checkbox->getAttribute('value') : '';
                        
                        // Detalhes de impostos
                        $detalhesImpostos = [];
                        foreach ($colunas as $coluna) {
                            $popoverContent = $coluna->getAttribute('data-content');
                            if ($popoverContent) {
                                $detalhesImpostos = array_merge(
                                    $detalhesImpostos, 
                                    $this->extrairDetalhesImpostos($popoverContent)
                                );
                            }
                        }
                        
                        $liquidado = (stripos($situacao, 'liquidado') !== false) || 
                                    (stripos($situacao, 'pago') !== false) ||
                                    ($principal === '-' && $total === '-');
                        
                        $debito = [
                            'periodo' => $periodo,
                            'periodo_codigo' => $valorPeriodo,
                            'apurado' => $apurado,
                            'situacao' => $situacao,
                            'valores' => [
                                'principal' => $principal,
                                'multa' => $multa,
                                'juros' => $juros,
                                'total' => $total
                            ],
                            'datas' => [
                                'vencimento' => $vencimento,
                                'acolhimento' => $acolhimento
                            ],
                            'detalhes_impostos' => $detalhesImpostos,
                            'liquidado' => $liquidado
                        ];
                        
                        $debitos[] = $debito;
                        
                        $this->debug[] = "Período extraído: $periodo - Situação: $situacao - Total: $total";
                    }
                }
            } else {
                $this->debug[] = "Tabela não encontrada, tentando extração por regex...";
                
                // Fallback para regex
                if (preg_match_all('/<tr[^>]*class="[^"]*pa[^"]*"[^>]*>.*?<\/tr>/si', $html, $linhasMatches)) {
                    $this->debug[] = "Encontradas " . count($linhasMatches[0]) . " linhas via regex";
                    
                    foreach ($linhasMatches[0] as $linhaHtml) {
                        if (preg_match('/<td[^>]*>([^<]+\/\d{4})<\/td>/', $linhaHtml, $periodoMatch)) {
                            $periodo = trim($periodoMatch[1]);
                            
                            preg_match('/class="[^"]*situacao[^"]*"[^>]*>([^<]+)<\/td>/', $linhaHtml, $situacaoMatch);
                            $situacao = $situacaoMatch ? trim($situacaoMatch[1]) : 'Não encontrado';
                            
                            preg_match_all('/R\$\s*[\d,\.]+/', $linhaHtml, $valoresMatch);
                            preg_match_all('/<td[^>]*>(0[1-9]|[12][0-9]|3[01])\/(0[1-9]|1[012])\/(19|20)\d{2}<\/td>/', $linhaHtml, $datasMatch);
                            
                            $debito = [
                                'periodo' => $periodo,
                                'situacao' => $situacao,
                                'valores' => [
                                    'principal' => $valoresMatch[0][0] ?? '-',
                                    'multa' => $valoresMatch[0][1] ?? '-',
                                    'juros' => $valoresMatch[0][2] ?? '-',
                                    'total' => $valoresMatch[0][3] ?? '-'
                                ],
                                'datas' => [
                                    'vencimento' => $datasMatch[0][0] ?? '-',
                                    'acolhimento' => $datasMatch[0][1] ?? '-'
                                ],
                                'liquidado' => (stripos($situacao, 'liquidado') !== false) || (stripos($situacao, 'pago') !== false),
                                'metodo_extracao' => 'regex'
                            ];
                            
                            // Tentar extrair detalhes de impostos
                            if (preg_match('/data-content="([^"]*)"[^>]*class="[^"]*principal[^"]*"/', $linhaHtml, $popoverMatch)) {
                                $debito['detalhes_impostos'] = $this->extrairDetalhesImpostos(html_entity_decode($popoverMatch[1], ENT_QUOTES, 'UTF-8'));
                            } else {
                                $debito['detalhes_impostos'] = [];
                            }
                            
                            $debitos[] = $debito;
                        }
                    }
                }
            }
        
        } catch (Exception $e) {
            $this->debug[] = "Erro ao extrair da tabela: " . $e->getMessage();
        }
        
        $this->debug[] = "Total de períodos extraídos: " . count($debitos);
        
        return $debitos;
    }
    
    private function extrairDetalhesImpostos($popoverContent) {
        $detalhes = [];
        
        if (!$popoverContent) {
            return $detalhes;
        }
        
        $content = html_entity_decode($popoverContent, ENT_QUOTES, 'UTF-8');
        
        // Padrões para extrair impostos
        $padroes = [
            'icms' => '/<strong>ICMS<\/strong>:\s*R\$\s*([\d,\.]+)/',
            'iss' => '/<strong>ISS<\/strong>:\s*R\$\s*([\d,\.]+)/',
            'inss' => '/<strong>INSS<\/strong>:\s*R\$\s*([\d,\.]+)/'
        ];
        
        foreach ($padroes as $imposto => $padrao) {
            if (preg_match($padrao, $content, $matches)) {
                $detalhes[$imposto] = 'R$ ' . $matches[1];
            }
        }
        
        // Descrição do INSS
        if (preg_match('/(\d+%\s*sobre\s*o\s*sal[^<]+)/', $content, $matches)) {
            $detalhes['inss_descricao'] = trim($matches[1]);
        }
        
        return $detalhes;
    }
}

// Inicializar gerenciador de sessão
SessionManager::init();

// Processar requisição
try {
    $action = $_POST['action'] ?? $_GET['action'] ?? null;
    $cnpj = $_POST['cnpj'] ?? $_GET['cnpj'] ?? null;
    $hCaptchaResponse = $_POST['h-captcha-response'] ?? $_GET['h-captcha-response'] ?? null;
    $ano = $_POST['ano'] ?? $_GET['ano'] ?? null;
    
    if (!$action) {
        returnJson([
            'status' => 'error',
            'message' => 'Parâmetro action é obrigatório',
            'valid_actions' => ['consultar_completa', 'obter_debitos']
        ], 400);
    }
    
    $consultor = new ReceitaFederalMEI();
    
    if ($action === 'consultar_completa') {
        if (!$cnpj) {
            returnJson([
                'status' => 'error',
                'message' => 'Parâmetro cnpj é obrigatório'
            ], 400);
        }
        
        if (!$hCaptchaResponse) {
            returnJson([
                'status' => 'error',
                'message' => 'Parâmetro h-captcha-response é obrigatório'
            ], 400);
        }
        
        $cnpj = preg_replace('/\D/', '', $cnpj);
        if (strlen($cnpj) !== 14) {
            returnJson([
                'status' => 'error',
                'message' => 'CNPJ deve conter exatamente 14 dígitos numéricos',
                'cnpj_fornecido' => $cnpj,
                'tamanho' => strlen($cnpj)
            ], 400);
        }
        
        $resultado = $consultor->consultarCompleta($cnpj, $hCaptchaResponse);
        
    } elseif ($action === 'obter_debitos') {
        if (!$ano) {
            returnJson([
                'status' => 'error',
                'message' => 'Parâmetro ano é obrigatório'
            ], 400);
        }
        
        if (!is_numeric($ano) || $ano < 2000 || $ano > date('Y')) {
            returnJson([
                'status' => 'error',
                'message' => 'Ano deve ser um número válido entre 2000 e ' . date('Y')
            ], 400);
        }
        
        $resultado = $consultor->obterDebitosPorAno($ano);
        
    } else {
        returnJson([
            'status' => 'error',
            'message' => 'Ação inválida: ' . $action,
            'valid_actions' => ['consultar_completa', 'obter_debitos']
        ], 400);
    }
    
    returnJson($resultado);
    
} catch (Exception $e) {
    returnJson([
        'status' => 'error',
        'message' => 'Erro interno: ' . $e->getMessage(),
        'debug' => [
            'file' => $e->getFile(),
            'line' => $e->getLine(),
            'trace' => explode("\n", $e->getTraceAsString())
        ]
    ], 500);
} catch (Error $e) {
    returnJson([
        'status' => 'error',
        'message' => 'Erro fatal: ' . $e->getMessage(),
        'debug' => [
            'file' => $e->getFile(),
            'line' => $e->getLine(),
            'type' => 'Fatal Error'
        ]
    ], 500);
}

returnJson([
    'status' => 'error',
    'message' => 'Erro desconhecido - código não deveria chegar aqui',
    'debug' => [
        'post' => $_POST,
        'get' => $_GET
    ]
], 500);
?>