<?php
/**
 * API para Liberação Manual de Acesso
 * Permite que produtores liberem acesso a produtos sem transação financeira
 * (para vendas via WhatsApp, PIX direto, etc.)
 */

// OUTPUT BUFFERING: Capturar e descartar qualquer HTML/echo dos includes
ob_start();

// HEADER JSON (deve ser o primeiro, antes de qualquer output)
header('Content-Type: application/json');

// Registrar função de shutdown para garantir JSON mesmo em erro fatal
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error !== NULL && in_array($error['type'], [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE])) {
        ob_end_clean();
        http_response_code(500);
        echo json_encode([
            'status' => 'error',
            'message' => 'Erro fatal no servidor'
        ]);
    }
});

// Função para retornar erro JSON de forma segura (limpa buffer antes)
function retornarErroJson($mensagem, $codigoHttp = 400) {
    // Garantir que buffer está limpo
    if (ob_get_level() > 0) {
        ob_end_clean();
    }
    http_response_code($codigoHttp);
    echo json_encode([
        'status' => 'error',
        'message' => $mensagem
    ], JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

// Função para retornar sucesso JSON (limpa buffer antes)
function retornarSucessoJson($mensagem, $dados = []) {
    // Garantir que buffer está limpo
    if (ob_get_level() > 0) {
        ob_end_clean();
    }
    http_response_code(200);
    echo json_encode(array_merge([
        'status' => 'success',
        'message' => $mensagem
    ], $dados), JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES);
    exit;
}

// Envolver TUDO em try-catch para capturar qualquer erro fatal
try {
    // Verificar se é POST
    if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
        retornarErroJson('Método não permitido', 405);
    }
    
    // Carregar configurações (qualquer output será descartado pelo ob_end_clean)
    $config_db_path = __DIR__ . '/../config/config_db.php';
    if (!file_exists($config_db_path)) {
        error_log("ERRO: Arquivo config_db.php não encontrado em: $config_db_path");
        retornarErroJson('Erro de configuração do servidor', 500);
    }
    
    require_once $config_db_path;
    
    // Limpar qualquer output dos includes imediatamente
    if (ob_get_level() > 0) {
        ob_end_clean();
        ob_start(); // Reiniciar buffer para capturar qualquer output futuro
    }
    
    // Verificar se $pdo foi criado
    if (!isset($pdo) || !$pdo) {
        error_log("ERRO: Conexão PDO não foi estabelecida");
        retornarErroJson('Erro de conexão com o banco de dados', 500);
    }
    
    // Validar entrada
    $produto_id = isset($_POST['produto_id']) ? intval($_POST['produto_id']) : 0;
    $email = isset($_POST['email']) ? trim($_POST['email']) : '';
    $nome = isset($_POST['nome']) ? trim($_POST['nome']) : '';
    
    if ($produto_id <= 0) {
        retornarErroJson('ID do produto inválido');
    }
    
    if (empty($email) || !filter_var($email, FILTER_VALIDATE_EMAIL)) {
        retornarErroJson('E-mail inválido');
    }
    
    if (empty($nome)) {
        retornarErroJson('Nome é obrigatório');
    }
    
    // Buscar dados do produto
    try {
        $stmt = $pdo->prepare("
            SELECT 
                id, nome, tipo_entrega, usuario_id,
                preco_atual, preco,
                link_entregavel,
                entrega_dados_titulo,
                entrega_dados_descricao,
                entrega_dados_acesso,
                entrega_dados_botao_texto,
                entrega_dados_botao_link
            FROM produtos 
            WHERE id = :id
            LIMIT 1
        ");
        $stmt->execute([':id' => $produto_id]);
        $produto = $stmt->fetch(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("ERRO ao buscar produto: " . $e->getMessage());
        retornarErroJson('Erro ao buscar produto', 500);
    }
    
    if (!$produto) {
        retornarErroJson('Produto não encontrado');
    }
    
    $tipo_entrega = $produto['tipo_entrega'] ?? 'link';
    
    // Buscar ou criar usuário pelo email
    try {
        $stmt_user = $pdo->prepare("SELECT id FROM usuarios WHERE email = :email LIMIT 1");
        $stmt_user->execute([':email' => $email]);
        $usuario = $stmt_user->fetch(PDO::FETCH_ASSOC);
    } catch (PDOException $e) {
        error_log("ERRO ao buscar usuário: " . $e->getMessage());
        retornarErroJson('Erro ao buscar usuário', 500);
    }
    
    $usuario_id = null;
    if ($usuario) {
        // Usuário já existe
        $usuario_id = intval($usuario['id']);
        error_log("Usuário existente encontrado: ID $usuario_id para email $email");
    } else {
        // Criar usuário novo
        error_log("Criando novo usuário para email: $email");
        
        // Senha padrão: hash de 'mudar123'
        $senha_padrao = 'mudar123';
        $senha_hash = password_hash($senha_padrao, PASSWORD_DEFAULT);
        
        try {
            // Tentar com schema moderno primeiro (senha_hash, tipo)
            $stmt_insert_user = $pdo->prepare("
                INSERT INTO usuarios (nome, email, senha_hash, tipo, status, created_at)
                VALUES (:nome, :email, :senha_hash, 'usuario', 'ativo', NOW())
            ");
            
            $stmt_insert_user->execute([
                ':nome' => $nome,
                ':email' => $email,
                ':senha_hash' => $senha_hash
            ]);
            
            $usuario_id = intval($pdo->lastInsertId());
            error_log("Usuário criado com sucesso (schema moderno): ID $usuario_id");
            
        } catch (PDOException $e) {
            // Se falhar, tentar com schema antigo (retrocompatibilidade)
            if (strpos($e->getMessage(), 'senha_hash') !== false || strpos($e->getMessage(), 'tipo') !== false || strpos($e->getMessage(), 'status') !== false) {
                try {
                    error_log("Tentando criar usuário com schema antigo (senha, nivel)");
                    $stmt_insert_user = $pdo->prepare("
                        INSERT INTO usuarios (nome, email, senha, nivel, data_cadastro)
                        VALUES (:nome, :email, :senha, 'cliente', NOW())
                    ");
                    
                    $stmt_insert_user->execute([
                        ':nome' => $nome,
                        ':email' => $email,
                        ':senha' => $senha_hash
                    ]);
                    
                    $usuario_id = intval($pdo->lastInsertId());
                    error_log("Usuário criado com sucesso (schema antigo): ID $usuario_id");
                    
                } catch (PDOException $e2) {
                    error_log("ERRO ao criar usuário (ambas tentativas falharam): " . $e2->getMessage());
                    retornarErroJson('Erro ao criar usuário', 500);
                }
            } else {
                error_log("ERRO ao criar usuário: " . $e->getMessage());
                retornarErroJson('Erro ao criar usuário', 500);
            }
        }
    }
    
    if (!$usuario_id || $usuario_id <= 0) {
        retornarErroJson('Erro ao obter ID do usuário', 500);
    }
    
    // Obter produtor_id diretamente do produto (já buscado acima)
    $produtor_id = isset($produto['usuario_id']) ? intval($produto['usuario_id']) : null;
    
    // Separar nome e sobrenome
    $nome_parts = explode(' ', trim($nome), 2);
    $first_name = $nome_parts[0] ?? 'Cliente';
    $last_name = $nome_parts[1] ?? '';
    
    // Liberar acesso baseado no tipo de entrega
    if ($tipo_entrega == 'area_membros') {
        // Verificar se já existe matrícula
        try {
            $stmt_mat_check = $pdo->prepare("
                SELECT id FROM matriculas 
                WHERE usuario_id = :usuario_id AND produto_id = :produto_id 
                LIMIT 1
            ");
            $stmt_mat_check->execute([
                ':usuario_id' => $usuario_id,
                ':produto_id' => $produto_id
            ]);
            $matricula_existe = $stmt_mat_check->fetch(PDO::FETCH_ASSOC);
            
            if (!$matricula_existe) {
                // Criar nova matrícula
                error_log("Criando nova matrícula para usuario_id=$usuario_id, produto_id=$produto_id");
                $stmt_mat = $pdo->prepare("
                    INSERT INTO matriculas (usuario_id, produto_id, data_inicio, data_expiracao, status)
                    VALUES (:usuario_id, :produto_id, NOW(), NULL, 'ativo')
                ");
                $stmt_mat->execute([
                    ':usuario_id' => $usuario_id,
                    ':produto_id' => $produto_id
                ]);
                error_log("Matrícula criada com sucesso");
            } else {
                // Atualizar matrícula existente
                error_log("Atualizando matrícula existente ID: " . $matricula_existe['id']);
                $stmt_mat_update = $pdo->prepare("
                    UPDATE matriculas 
                    SET status = 'ativo', data_inicio = NOW() 
                    WHERE id = :id
                ");
                $stmt_mat_update->execute([':id' => $matricula_existe['id']]);
                error_log("Matrícula atualizada com sucesso");
            }
        } catch (PDOException $e) {
            error_log("ERRO ao criar/atualizar matrícula: " . $e->getMessage());
            retornarErroJson('Erro ao criar matrícula', 500);
        }
        
        // Criar transação manual para aparecer em "Minhas Compras"
        try {
            $stmt_check_trans = $pdo->prepare("
                SELECT id FROM transacoes 
                WHERE produto_id = :produto_id 
                AND email = :email 
                AND status = 'Aprovado'
                LIMIT 1
            ");
            $stmt_check_trans->execute([
                ':produto_id' => $produto_id,
                ':email' => $email
            ]);
            $transacao_existe = $stmt_check_trans->fetch(PDO::FETCH_ASSOC);
            
            if (!$transacao_existe) {
                error_log("Criando transação manual para aparecer em Minhas Compras (area_membros)");
                $stmt_trans = $pdo->prepare("
                    INSERT INTO transacoes (
                        produto_id, produtor_id, usuario_id, nome, sobrenome, email, 
                        valor, descricao, status, tipo_pagamento, gateway, 
                        link_entregavel, data_criacao
                    ) VALUES (
                        :produto_id, :produtor_id, :usuario_id, :nome, :sobrenome, :email,
                        :valor, :descricao, 'Aprovado', 'Liberação Manual', 'manual',
                        :link_entregavel, NOW()
                    )
                ");
                $preco_produto = floatval($produto['preco_atual'] ?? $produto['preco'] ?? 0);
                $stmt_trans->execute([
                    ':produto_id' => $produto_id,
                    ':produtor_id' => $produtor_id,
                    ':usuario_id' => $usuario_id,
                    ':nome' => $first_name,
                    ':sobrenome' => $last_name,
                    ':email' => $email,
                    ':valor' => $preco_produto,
                    ':descricao' => $produto['nome'] ?? 'Produto',
                    ':link_entregavel' => $produto['link_entregavel'] ?? ''
                ]);
                error_log("Transação manual criada com sucesso");
            }
        } catch (PDOException $e) {
            // Se falhar por colunas não existentes, tentar versão simplificada
            if (strpos($e->getMessage(), 'produto_id') !== false || strpos($e->getMessage(), 'produtor_id') !== false || strpos($e->getMessage(), 'usuario_id') !== false) {
                try {
                    $stmt_trans = $pdo->prepare("
                        INSERT INTO transacoes (
                            nome, sobrenome, email, valor, descricao, status, 
                            tipo_pagamento, gateway, link_entregavel, data_criacao
                        ) VALUES (
                            :nome, :sobrenome, :email, :valor, :descricao, 'Aprovado',
                            'Liberação Manual', 'manual', :link_entregavel, NOW()
                        )
                    ");
                    $preco_produto = floatval($produto['preco_atual'] ?? $produto['preco'] ?? 0);
                    $stmt_trans->execute([
                        ':nome' => $first_name,
                        ':sobrenome' => $last_name,
                        ':email' => $email,
                        ':valor' => $preco_produto,
                        ':descricao' => $produto['nome'] ?? 'Produto',
                        ':link_entregavel' => $produto['link_entregavel'] ?? ''
                    ]);
                    error_log("Transação manual criada com sucesso (versão simplificada)");
                } catch (PDOException $e2) {
                    error_log("AVISO: Falha ao criar transação manual (não bloqueia): " . $e2->getMessage());
                }
            } else {
                error_log("AVISO: Falha ao criar transação manual (não bloqueia): " . $e->getMessage());
            }
        }
        
        // Enviar email de boas-vindas (tentativa, não bloqueia se falhar)
        try {
            $link_acesso = "https://" . $_SERVER['HTTP_HOST'] . "/dashboard/pages_usuario/curso_player.php?produto_id=" . $produto_id;
            enviarEmailAcessoManual($email, $nome, $produto['nome'], $link_acesso, 'area_membros');
        } catch (Exception $e) {
            error_log("AVISO: Falha ao enviar email (não bloqueia): " . $e->getMessage());
            // Não retorna erro, apenas loga
        }
        
    } else {
        // Para link e dados_acesso, criar transação manual para aparecer em "Minhas Compras"
        try {
            $stmt_check_trans = $pdo->prepare("
                SELECT id FROM transacoes 
                WHERE produto_id = :produto_id 
                AND email = :email 
                AND status = 'Aprovado'
                LIMIT 1
            ");
            $stmt_check_trans->execute([
                ':produto_id' => $produto_id,
                ':email' => $email
            ]);
            $transacao_existe = $stmt_check_trans->fetch(PDO::FETCH_ASSOC);
            
            if (!$transacao_existe) {
                error_log("Criando transação manual para aparecer em Minhas Compras (tipo: $tipo_entrega)");
                $stmt_trans = $pdo->prepare("
                    INSERT INTO transacoes (
                        produto_id, produtor_id, usuario_id, nome, sobrenome, email, 
                        valor, descricao, status, tipo_pagamento, gateway, 
                        link_entregavel, data_criacao
                    ) VALUES (
                        :produto_id, :produtor_id, :usuario_id, :nome, :sobrenome, :email,
                        :valor, :descricao, 'Aprovado', 'Liberação Manual', 'manual',
                        :link_entregavel, NOW()
                    )
                ");
                $preco_produto = floatval($produto['preco_atual'] ?? $produto['preco'] ?? 0);
                $link_entregavel = ($tipo_entrega == 'dados_acesso') 
                    ? ($produto['entrega_dados_botao_link'] ?? '') 
                    : ($produto['link_entregavel'] ?? '');
                $stmt_trans->execute([
                    ':produto_id' => $produto_id,
                    ':produtor_id' => $produtor_id,
                    ':usuario_id' => $usuario_id,
                    ':nome' => $first_name,
                    ':sobrenome' => $last_name,
                    ':email' => $email,
                    ':valor' => $preco_produto,
                    ':descricao' => $produto['nome'] ?? 'Produto',
                    ':link_entregavel' => $link_entregavel
                ]);
                error_log("Transação manual criada com sucesso");
            }
        } catch (PDOException $e) {
            // Se falhar por colunas não existentes, tentar versão simplificada
            if (strpos($e->getMessage(), 'produto_id') !== false || strpos($e->getMessage(), 'produtor_id') !== false || strpos($e->getMessage(), 'usuario_id') !== false) {
                try {
                    $stmt_trans = $pdo->prepare("
                        INSERT INTO transacoes (
                            nome, sobrenome, email, valor, descricao, status, 
                            tipo_pagamento, gateway, link_entregavel, data_criacao
                        ) VALUES (
                            :nome, :sobrenome, :email, :valor, :descricao, 'Aprovado',
                            'Liberação Manual', 'manual', :link_entregavel, NOW()
                        )
                    ");
                    $preco_produto = floatval($produto['preco_atual'] ?? $produto['preco'] ?? 0);
                    $link_entregavel = ($tipo_entrega == 'dados_acesso') 
                        ? ($produto['entrega_dados_botao_link'] ?? '') 
                        : ($produto['link_entregavel'] ?? '');
                    $stmt_trans->execute([
                        ':nome' => $first_name,
                        ':sobrenome' => $last_name,
                        ':email' => $email,
                        ':valor' => $preco_produto,
                        ':descricao' => $produto['nome'] ?? 'Produto',
                        ':link_entregavel' => $link_entregavel
                    ]);
                    error_log("Transação manual criada com sucesso (versão simplificada)");
                } catch (PDOException $e2) {
                    error_log("AVISO: Falha ao criar transação manual (não bloqueia): " . $e2->getMessage());
                }
            } else {
                error_log("AVISO: Falha ao criar transação manual (não bloqueia): " . $e->getMessage());
            }
        }
        
        if ($tipo_entrega == 'dados_acesso') {
            // Enviar dados de acesso por email
            try {
                $dados_texto = ($produto['entrega_dados_titulo'] ?? 'Dados de Acesso') . "\n\n";
                $dados_texto .= ($produto['entrega_dados_descricao'] ?? '') . "\n\n";
                $dados_texto .= "Dados de Acesso:\n" . ($produto['entrega_dados_acesso'] ?? '');
                
                enviarEmailAcessoManual(
                    $email, 
                    $nome, 
                    $produto['nome'], 
                    $dados_texto, 
                    'dados_acesso',
                    $produto['entrega_dados_botao_texto'] ?? 'Acessar',
                    $produto['entrega_dados_botao_link'] ?? ''
                );
            } catch (Exception $e) {
                error_log("AVISO: Falha ao enviar email (não bloqueia): " . $e->getMessage());
                // Não retorna erro, apenas loga
            }
        } else {
            // Link simples
            try {
                $link = $produto['link_entregavel'] ?? '';
                enviarEmailAcessoManual($email, $nome, $produto['nome'], $link, 'link');
            } catch (Exception $e) {
                error_log("AVISO: Falha ao enviar email (não bloqueia): " . $e->getMessage());
                // Não retorna erro, apenas loga
            }
        }
    }
    
    retornarSucessoJson('Acesso liberado com sucesso! E-mail enviado para ' . $email);
    
} catch (Throwable $e) {
    // Captura QUALQUER tipo de erro (Exception, Error, etc.)
    error_log("ERRO FATAL em liberar_acesso_manual.php: " . $e->getMessage());
    error_log("Stack trace: " . $e->getTraceAsString());
    error_log("Arquivo: " . $e->getFile() . " Linha: " . $e->getLine());
    retornarErroJson('Erro interno do servidor', 500);
}

/**
 * Função auxiliar para enviar email de acesso manual
 * Retorna true se sucesso, false se falhar (não lança exceção)
 */
function enviarEmailAcessoManual($email, $nome, $produtoNome, $conteudo, $tipo = 'link', $botaoTexto = '', $botaoLink = '') {
    try {
        // Tentar carregar configuração de email (se existir)
        $email_config_path = __DIR__ . '/../config_email/email_config.php';
        if (!file_exists($email_config_path)) {
            error_log("AVISO: Arquivo email_config.php não encontrado. Email não será enviado.");
            return false;
        }
        
        // Usar output buffering para capturar qualquer output do include
        ob_start();
        require_once $email_config_path;
        ob_end_clean();
        
        // Verificar se PHPMailer está disponível
        $vendor_autoload = __DIR__ . '/../vendor/autoload.php';
        if (!file_exists($vendor_autoload)) {
            error_log("AVISO: vendor/autoload.php não encontrado. Email não será enviado.");
            return false;
        }
        
        ob_start();
        require_once $vendor_autoload;
        ob_end_clean();
        
        // Verificar se constantes de email estão definidas
        if (!defined('EMAIL_HOST') || !defined('EMAIL_USERNAME') || !defined('EMAIL_PASSWORD')) {
            error_log("AVISO: Constantes de email não configuradas. Email não será enviado.");
            return false;
        }
        
        // Usar namespace completo (não usar 'use' dentro de função - causa erro fatal)
        $mail = new \PHPMailer\PHPMailer\PHPMailer(true);
        
        $mail->isSMTP();
        $mail->Host = EMAIL_HOST;
        $mail->SMTPAuth = true;
        $mail->Username = EMAIL_USERNAME;
        $mail->Password = EMAIL_PASSWORD;
        $mail->SMTPSecure = defined('EMAIL_SMTP_SECURE') ? EMAIL_SMTP_SECURE : \PHPMailer\PHPMailer\PHPMailer::ENCRYPTION_STARTTLS;
        $mail->Port = defined('EMAIL_PORT') ? EMAIL_PORT : 587;
        
        $mail->setFrom(
            defined('EMAIL_FROM') ? EMAIL_FROM : EMAIL_USERNAME,
            defined('EMAIL_FROM_NAME') ? EMAIL_FROM_NAME : 'Sistema'
        );
        $mail->addAddress($email, $nome);
        
        $mail->isHTML(true);
        $mail->Subject = "Acesso liberado ao $produtoNome";
        
        // Montar corpo do email baseado no tipo
        $emailBody = "<h2>Olá, " . htmlspecialchars($nome) . "!</h2>";
        $emailBody .= "<p>Seu acesso ao produto <strong>" . htmlspecialchars($produtoNome) . "</strong> foi liberado.</p>";
        
        if ($tipo == 'area_membros') {
            $emailBody .= "<p><a href='" . htmlspecialchars($conteudo) . "' style='background: #10b981; color: white; padding: 15px 30px; text-decoration: none; border-radius: 8px; display: inline-block;'>Acessar Área de Membros</a></p>";
        } elseif ($tipo == 'dados_acesso') {
            $emailBody .= "<div style='background: #f7fafc; padding: 20px; border-radius: 8px; margin: 20px 0;'>";
            $emailBody .= "<pre style='white-space: pre-wrap; font-family: Arial;'>" . htmlspecialchars($conteudo) . "</pre>";
            $emailBody .= "</div>";
            if (!empty($botaoLink)) {
                $emailBody .= "<p><a href='" . htmlspecialchars($botaoLink) . "' style='background: #10b981; color: white; padding: 15px 30px; text-decoration: none; border-radius: 8px; display: inline-block;'>" . htmlspecialchars($botaoTexto) . "</a></p>";
            }
        } else {
            $emailBody .= "<p><a href='" . htmlspecialchars($conteudo) . "' style='background: #10b981; color: white; padding: 15px 30px; text-decoration: none; border-radius: 8px; display: inline-block;'>Acessar Produto</a></p>";
        }
        
        $mail->Body = $emailBody;
        $mail->send();
        
        error_log("Email enviado com sucesso para: $email");
        return true;
    } catch (Throwable $e) {
        error_log("ERRO ao enviar email de acesso manual: " . $e->getMessage());
        // Retorna false mas não lança exceção (não bloqueia o processo)
        return false;
    }
}
?>
