<?php
/**
 * Backend PayPal - Checkout Pro 2025
 * Processamento de pagamento via PayPal (usando cURL direto, sem SDK)
 */

// Conexão com o banco de dados
require __DIR__ . '/../config/config_db.php'; 

// Helper de gateway
require_once __DIR__ . '/gateway_helper.php';

// Helper de financeiro
require_once __DIR__ . '/financeiro_helper.php';

// Configuração de email
require_once __DIR__ . '/../config_email/email_config.php';

// Defina o cabeçalho da resposta como JSON
header('Content-Type: application/json');

// Configurar credenciais do PayPal
$paypal_client_id = get_gateway_config('paypal', 'client_id');
$paypal_client_secret = get_gateway_config('paypal', 'client_secret');
$paypal_mode = get_gateway_config('paypal', 'mode') ?: 'sandbox';

if (empty($paypal_client_id) || empty($paypal_client_secret)) {
    echo json_encode(['status' => 'error', 'message' => 'PayPal não configurado. Configure as credenciais no dashboard.']);
    exit;
}

// URLs base do PayPal
$paypal_base_url = ($paypal_mode === 'live') 
    ? 'https://api-m.paypal.com' 
    : 'https://api-m.sandbox.paypal.com';

// Função para obter access token do PayPal
function getPayPalAccessToken($client_id, $client_secret, $base_url) {
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $base_url . '/v1/oauth2/token');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_USERPWD, $client_id . ':' . $client_secret);
    curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');
    curl_setopt($ch, CURLOPT_HTTPHEADER, ['Accept: application/json', 'Accept-Language: en_US']);
    
    $response = curl_exec($ch);
    $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
    $curl_error = curl_error($ch);
    curl_close($ch);
    
    if ($curl_error) {
        error_log("Erro cURL ao obter access token PayPal: $curl_error");
        return null;
    }
    
    if ($http_code === 200) {
        $data = json_decode($response, true);
        return $data['access_token'] ?? null;
    }
    
    error_log("Erro ao obter access token PayPal: HTTP $http_code - $response");
    return null;
}

// Se for uma requisição GET com order_id, significa que é o retorno do PayPal
if ($_SERVER['REQUEST_METHOD'] === 'GET' && isset($_GET['order_id']) && isset($_GET['token'])) {
    $order_id = $_GET['order_id'];
    $token = $_GET['token'];
    
    try {
        // Obter access token
        $access_token = getPayPalAccessToken($paypal_client_id, $paypal_client_secret, $paypal_base_url);
        if (!$access_token) {
            throw new Exception('Erro ao obter access token do PayPal');
        }
        
        // Capturar o pagamento via API REST
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $paypal_base_url . '/v2/checkout/orders/' . $order_id . '/capture');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $access_token,
            'Prefer: return=representation'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, '{}');
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);
        
        if ($curl_error) {
            throw new Exception("Erro cURL ao capturar pagamento PayPal: $curl_error");
        }
        
        $response_data = json_decode($response, true);
        
        if ($http_code === 201 && isset($response_data['status']) && $response_data['status'] === 'COMPLETED') {
            // Buscar transação pelo token
            $sql = "SELECT * FROM transacoes WHERE external_reference = :token AND gateway = 'paypal' LIMIT 1";
            $stmt = $pdo->prepare($sql);
            $stmt->execute([':token' => $token]);
            $transaction = $stmt->fetch(PDO::FETCH_ASSOC);
            
            if ($transaction) {
                // Atualizar transação como aprovada
                $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Aprovado', payment_id = :payment_id WHERE id = :id");
                $stmt->execute([
                    ':payment_id' => $order_id,
                    ':id' => $transaction['id']
                ]);
                
                // Calcular e registrar comissões (verificando duplicidade)
                if (!empty($transaction['produto_id']) && !empty($transaction['produtor_id'])) {
                    // Verificar se já existe comissão registrada para evitar duplicação
                    try {
                        $sql_check = "SELECT id FROM vendas_comissoes WHERE transacao_id = :transacao_id LIMIT 1";
                        $stmt_check = $pdo->prepare($sql_check);
                        $stmt_check->execute([':transacao_id' => $transaction['id']]);
                        $comissao_existe = $stmt_check->fetch(PDO::FETCH_ASSOC);
                        
                        if (!$comissao_existe) {
                            calcular_e_registrar_comissoes(
                                $transaction['id'],
                                intval($transaction['produto_id']),
                                intval($transaction['produtor_id']),
                                !empty($transaction['afiliado_id']) ? intval($transaction['afiliado_id']) : null,
                                floatval($transaction['valor'])
                            );
                        }
                    } catch (PDOException $e) {
                        error_log("Erro ao verificar comissão duplicada em process_payment_paypal: " . $e->getMessage());
                    }
                }
                
                // Enviar email de confirmação
                if (function_exists('enviarEmailProdutoDigital')) {
                    enviarEmailProdutoDigital(
                        $transaction['email'],
                        $transaction['nome'],
                        $transaction['sobrenome'],
                        $transaction['descricao'],
                        $transaction['link_entregavel']
                    );
                }
                
                // Redirecionar para página de sucesso
                header("Location: /views/aprovado.php?transaction_id=" . $transaction['id']);
                exit;
            } else {
                error_log("Transação PayPal não encontrada para token: $token");
                header("Location: /views/reprovado.php?reason=Transação não encontrada");
                exit;
            }
        } else {
            error_log("Captura PayPal não concluída. HTTP $http_code - " . json_encode($response_data));
            header("Location: /views/reprovado.php?reason=Pagamento PayPal não aprovado");
            exit;
        }
        
    } catch (Exception $e) {
        error_log("Erro ao capturar pagamento PayPal: " . $e->getMessage());
        header("Location: /views/reprovado.php?reason=" . urlencode($e->getMessage()));
        exit;
    }
}

// Se for POST, criar ordem de pagamento
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    try {
        $data = json_decode(file_get_contents('php://input'), true);
        
        if (!isset($data['transaction_amount']) || !isset($data['description'])) {
            throw new Exception('Dados obrigatórios não foram fornecidos.');
        }
        
        // Separar nome completo
        $full_name = isset($data['payer']['full_name']) ? $data['payer']['full_name'] : '';
        $name_parts = explode(' ', trim($full_name));
        $first_name = array_shift($name_parts);
        $last_name = implode(' ', $name_parts);
        
        // Criar uma referência externa única
        $external_reference = uniqid('paypal_', true);
        
        // Buscar produto_id e produtor_id
        $produto_id = isset($data['product']['id']) ? intval($data['product']['id']) : null;
        $produtor_id = null;
        $afiliado_id = null;
        
        if ($produto_id) {
            try {
                $sql_produto = "SELECT usuario_id FROM produtos WHERE id = :produto_id LIMIT 1";
                $stmt_produto = $pdo->prepare($sql_produto);
                $stmt_produto->execute([':produto_id' => $produto_id]);
                $produto = $stmt_produto->fetch(PDO::FETCH_ASSOC);
                if ($produto) {
                    $produtor_id = intval($produto['usuario_id']);
                }
            } catch (PDOException $e) {
                error_log("Erro ao buscar produtor: " . $e->getMessage());
            }
        }
        
        // Buscar afiliado do cookie
        if (isset($_COOKIE['affiliate_id']) && isset($_COOKIE['affiliate_produto_id'])) {
            $cookie_afiliado_id = intval($_COOKIE['affiliate_id']);
            $cookie_produto_id = intval($_COOKIE['affiliate_produto_id']);
            
            if ($cookie_produto_id == $produto_id && $cookie_afiliado_id > 0) {
                try {
                    $sql_afiliado = "SELECT usuario_id FROM afiliacoes WHERE id = :afiliado_id AND produto_id = :produto_id AND status = 'ativo' LIMIT 1";
                    $stmt_afiliado = $pdo->prepare($sql_afiliado);
                    $stmt_afiliado->execute([':afiliado_id' => $cookie_afiliado_id, ':produto_id' => $produto_id]);
                    $afiliado = $stmt_afiliado->fetch(PDO::FETCH_ASSOC);
                    if ($afiliado) {
                        $afiliado_id = intval($afiliado['usuario_id']);
                    }
                } catch (PDOException $e) {
                    error_log("Erro ao buscar afiliado: " . $e->getMessage());
                }
            }
        }
        
        // Concatena código do país e número de telefone
        $country_code = isset($data['payer']['phone']['country_code']) ? $data['payer']['phone']['country_code'] : '';
        $area_code = isset($data['payer']['phone']['area_code']) ? $data['payer']['phone']['area_code'] : '';
        $phone_number = isset($data['payer']['phone']['number']) ? $data['payer']['phone']['number'] : '';
        $full_phone_number = trim($country_code . ' ' . $area_code . ' ' . $phone_number);
        
        // ENDEREÇO E FRETE (Produtos Físicos)
        $safeEnderecoJson = null;
        $safeFreteCobrado = 0;
        $safeStatusEntrega = null;
        
        if (isset($data['endereco_json']) && !empty($data['endereco_json'])) {
            $endereco_array = json_decode($data['endereco_json'], true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($endereco_array)) {
                if (!empty($endereco_array['cep']) && !empty($endereco_array['rua']) && 
                    !empty($endereco_array['numero']) && !empty($endereco_array['bairro']) && 
                    !empty($endereco_array['cidade']) && !empty($endereco_array['estado'])) {
                    $safeEnderecoJson = $data['endereco_json'];
                    $safeStatusEntrega = 'preparando';
                }
            }
        }
        
        if (isset($data['frete_cobrado']) && is_numeric($data['frete_cobrado'])) {
            $safeFreteCobrado = max(0, floatval($data['frete_cobrado']));
        }
        
        // Insere a transação no banco de dados (status Pendente)
        try {
            $stmt = $pdo->prepare("INSERT INTO transacoes (produto_id, produtor_id, afiliado_id, nome, sobrenome, email, telefone, cpf, device_ip, valor, descricao, status, tipo_pagamento, gateway, device_id, external_reference, metadados, link_entregavel, endereco_json, frete_cobrado, status_entrega) 
                                   VALUES (:produto_id, :produtor_id, :afiliado_id, :nome, :sobrenome, :email, :telefone, :cpf, :device_ip, :valor, :descricao, :status, :tipo_pagamento, :gateway, :device_id, :external_reference, :metadados, :link_entregavel, :endereco_json, :frete_cobrado, :status_entrega)");
            $stmt->execute([
                ':produto_id' => $produto_id,
                ':produtor_id' => $produtor_id,
                ':afiliado_id' => $afiliado_id,
                ':nome' => $first_name,
                ':sobrenome' => $last_name,
                ':email' => $data['payer']['email'],
                ':telefone' => $full_phone_number,
                ':cpf' => isset($data['payer']['identification']['number']) ? $data['payer']['identification']['number'] : null,
                ':device_ip' => isset($data['client_ip']) ? $data['client_ip'] : $_SERVER['REMOTE_ADDR'],
                ':valor' => round((float)$data['transaction_amount'], 2),
                ':descricao' => $data['description'],
                ':status' => 'Pendente',
                ':tipo_pagamento' => 'PayPal',
                ':gateway' => 'paypal',
                ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
                ':external_reference' => $external_reference,
                ':metadados' => json_encode($data['additional_products'] ?? []),
                ':link_entregavel' => $data['product']['link_entregavel'] ?? '',
                ':endereco_json' => $safeEnderecoJson,
                ':frete_cobrado' => $safeFreteCobrado,
                ':status_entrega' => $safeStatusEntrega
            ]);
        } catch (PDOException $e) {
            // Retrocompatibilidade
            if (strpos($e->getMessage(), 'endereco_json') !== false || strpos($e->getMessage(), 'frete_cobrado') !== false || strpos($e->getMessage(), 'status_entrega') !== false) {
                try {
                    $stmt = $pdo->prepare("INSERT INTO transacoes (produto_id, produtor_id, afiliado_id, nome, sobrenome, email, telefone, cpf, device_ip, valor, descricao, status, tipo_pagamento, gateway, device_id, external_reference, metadados, link_entregavel) 
                                           VALUES (:produto_id, :produtor_id, :afiliado_id, :nome, :sobrenome, :email, :telefone, :cpf, :device_ip, :valor, :descricao, :status, :tipo_pagamento, :gateway, :device_id, :external_reference, :metadados, :link_entregavel)");
                    $stmt->execute([
                        ':produto_id' => $produto_id,
                        ':produtor_id' => $produtor_id,
                        ':afiliado_id' => $afiliado_id,
                        ':nome' => $first_name,
                        ':sobrenome' => $last_name,
                        ':email' => $data['payer']['email'],
                        ':telefone' => $full_phone_number,
                        ':cpf' => isset($data['payer']['identification']['number']) ? $data['payer']['identification']['number'] : null,
                        ':device_ip' => isset($data['client_ip']) ? $data['client_ip'] : $_SERVER['REMOTE_ADDR'],
                        ':valor' => round((float)$data['transaction_amount'], 2),
                        ':descricao' => $data['description'],
                        ':status' => 'Pendente',
                        ':tipo_pagamento' => 'PayPal',
                        ':gateway' => 'paypal',
                        ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
                        ':external_reference' => $external_reference,
                        ':metadados' => json_encode($data['additional_products'] ?? []),
                        ':link_entregavel' => $data['product']['link_entregavel'] ?? ''
                    ]);
                } catch (PDOException $e2) {
                    // Retrocompatibilidade completa
                    if (strpos($e2->getMessage(), 'produto_id') !== false || strpos($e2->getMessage(), 'gateway') !== false || strpos($e2->getMessage(), 'produtor_id') !== false || strpos($e2->getMessage(), 'afiliado_id') !== false) {
                        $stmt = $pdo->prepare("INSERT INTO transacoes (nome, sobrenome, email, telefone, cpf, device_ip, valor, descricao, status, tipo_pagamento, device_id, external_reference, metadados, link_entregavel) 
                                               VALUES (:nome, :sobrenome, :email, :telefone, :cpf, :device_ip, :valor, :descricao, :status, :tipo_pagamento, :device_id, :external_reference, :metadados, :link_entregavel)");
                        $stmt->execute([
                            ':nome' => $first_name,
                            ':sobrenome' => $last_name,
                            ':email' => $data['payer']['email'],
                            ':telefone' => $full_phone_number,
                            ':cpf' => isset($data['payer']['identification']['number']) ? $data['payer']['identification']['number'] : null,
                            ':device_ip' => isset($data['client_ip']) ? $data['client_ip'] : $_SERVER['REMOTE_ADDR'],
                            ':valor' => round((float)$data['transaction_amount'], 2),
                            ':descricao' => $data['description'],
                            ':status' => 'Pendente',
                            ':tipo_pagamento' => 'PayPal',
                            ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
                            ':external_reference' => $external_reference,
                            ':metadados' => json_encode($data['additional_products'] ?? []),
                            ':link_entregavel' => $data['product']['link_entregavel'] ?? ''
                        ]);
                    } else {
                        throw $e2;
                    }
                }
            } else {
                throw $e;
            }
        }
        
        $transaction_id = $pdo->lastInsertId();
        
        // Inserir produtos adicionais
        if (isset($data['additional_products'])) {
            foreach ($data['additional_products'] as $produto) {
                $stmt = $pdo->prepare("INSERT INTO transacoes_adicionais (transacao_id, produto_id, nome, preco) 
                                       VALUES (:transacao_id, :produto_id, :nome, :preco)");
                $stmt->execute([
                    ':transacao_id' => $transaction_id,
                    ':produto_id' => $produto['id'],
                    ':nome' => $produto['nome'],
                    ':preco' => round((float)$produto['preco'], 2)
                ]);
            }
        }
        
        // Obter access token
        $access_token = getPayPalAccessToken($paypal_client_id, $paypal_client_secret, $paypal_base_url);
        if (!$access_token) {
            throw new Exception('Erro ao obter access token do PayPal');
        }
        
        // Criar ordem PayPal via API REST
        $order_data = [
            "intent" => "CAPTURE",
            "purchase_units" => [[
                "reference_id" => $external_reference,
                "description" => $data['description'],
                "amount" => [
                    "currency_code" => "BRL",
                    "value" => number_format((float)$data['transaction_amount'], 2, '.', '')
                ]
            ]],
            "application_context" => [
                "brand_name" => "Checkout Pro",
                "landing_page" => "BILLING",
                "user_action" => "PAY_NOW",
                "return_url" => "https://" . $_SERVER['HTTP_HOST'] . "/backend/process_payment_paypal.php?order_id={ORDER_ID}&token=" . $external_reference,
                "cancel_url" => "https://" . $_SERVER['HTTP_HOST'] . "/views/reprovado.php?reason=Cancelado pelo usuário"
            ]
        ];
        
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $paypal_base_url . '/v2/checkout/orders');
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_HTTPHEADER, [
            'Content-Type: application/json',
            'Authorization: Bearer ' . $access_token,
            'Prefer: return=representation'
        ]);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($order_data));
        
        $response = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        $curl_error = curl_error($ch);
        curl_close($ch);
        
        if ($curl_error) {
            throw new Exception("Erro cURL ao criar ordem PayPal: $curl_error");
        }
        
        if ($http_code === 201) {
            $response_data = json_decode($response, true);
            $order_id = $response_data['id'] ?? null;
            $approval_url = null;
            
            if (isset($response_data['links'])) {
                foreach ($response_data['links'] as $link) {
                    if ($link['rel'] === 'approve') {
                        $approval_url = $link['href'];
                        break;
                    }
                }
            }
            
            if ($approval_url && $order_id) {
                echo json_encode([
                    'status' => 'success',
                    'approval_url' => $approval_url,
                    'order_id' => $order_id
                ]);
            } else {
                throw new Exception('URL de aprovação não encontrada na resposta do PayPal.');
            }
        } else {
            error_log("Erro ao criar ordem PayPal: HTTP $http_code - $response");
            throw new Exception('Erro ao criar ordem PayPal. Verifique as credenciais.');
        }
        
    } catch (Exception $e) {
        error_log("Erro no PayPal: " . $e->getMessage());
        echo json_encode(['status' => 'error', 'message' => $e->getMessage()]);
    }
} else {
    echo json_encode(['status' => 'error', 'message' => 'Método não permitido.']);
}
?>
