<?php
/**
 * Backend Pagar.me - Checkout Pro 2025
 * Processamento de pagamento via Pagar.me (Cartão de Crédito e PIX)
 * 
 * TODO: Implementar chamada real à API Pagar.me V5
 * Por enquanto, este é um MOCK para testes do Frontend
 */

// 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';

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

// Garantir que sempre retorne JSON, mesmo em caso de erro fatal
register_shutdown_function(function() {
    $error = error_get_last();
    if ($error !== NULL && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) {
        http_response_code(500);
        echo json_encode([
            'status' => 'error',
            'message' => 'Erro interno do servidor. Por favor, tente novamente.'
        ]);
    }
});

// Configurar credenciais do Pagar.me
$pagarme_api_key = get_gateway_config('pagarme', 'api_key');

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

try {
    // Recebe os dados enviados pelo front-end (JSON)
    $data = json_decode(file_get_contents('php://input'), true);

    if (!isset($data['transaction_amount']) || !isset($data['payer']['email'])) {
        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('pagarme_', true);

    // 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);

    // 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']);
        
        // Validar se o afiliado é válido para este produto
        if ($cookie_produto_id == $produto_id && $cookie_afiliado_id > 0) {
            try {
                $sql_afiliado = "SELECT id FROM usuarios WHERE id = :afiliado_id AND nivel = 'afiliado' LIMIT 1";
                $stmt_afiliado = $pdo->prepare($sql_afiliado);
                $stmt_afiliado->execute([':afiliado_id' => $cookie_afiliado_id]);
                $afiliado = $stmt_afiliado->fetch(PDO::FETCH_ASSOC);
                if ($afiliado) {
                    $afiliado_id = $cookie_afiliado_id;
                }
            } catch (PDOException $e) {
                error_log("Erro ao buscar afiliado: " . $e->getMessage());
            }
        }
    }

    // Determinar tipo de pagamento (cartão ou PIX)
    $tipo_pagamento = 'Cartão de Crédito';
    $is_pix = isset($data['payment_method']) && $data['payment_method'] === 'pix';
    if ($is_pix) {
        $tipo_pagamento = 'Pix';
    }
    
    // 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
    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'] : null,
            ':valor' => round((float)$data['transaction_amount'], 2),
            ':descricao' => isset($data['description']) ? $data['description'] : 'Pagamento via Pagar.me',
            ':status' => 'Pendente',
            ':tipo_pagamento' => $tipo_pagamento,
            ':gateway' => 'pagarme',
            ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
            ':external_reference' => $external_reference,
            ':metadados' => json_encode(isset($data['additional_products']) ? $data['additional_products'] : []),
            ':link_entregavel' => isset($data['link_entregavel']) ? $data['link_entregavel'] : (isset($data['product']['link_entregavel']) ? $data['product']['link_entregavel'] : ''),
            ':endereco_json' => $safeEnderecoJson,
            ':frete_cobrado' => $safeFreteCobrado,
            ':status_entrega' => $safeStatusEntrega
        ]);
    } catch (PDOException $e) {
        // Se falhar por colunas novas, tentar sem elas
        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'] : null,
                    ':valor' => round((float)$data['transaction_amount'], 2),
                    ':descricao' => isset($data['description']) ? $data['description'] : 'Pagamento via Pagar.me',
                    ':status' => 'Pendente',
                    ':tipo_pagamento' => $tipo_pagamento,
                    ':gateway' => 'pagarme',
                    ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
                    ':external_reference' => $external_reference,
                    ':metadados' => json_encode(isset($data['additional_products']) ? $data['additional_products'] : []),
                    ':link_entregavel' => isset($data['link_entregavel']) ? $data['link_entregavel'] : (isset($data['product']['link_entregavel']) ? $data['product']['link_entregavel'] : '')
                ]);
            } catch (PDOException $e2) {
                // Retrocompatibilidade: se as colunas principais não existirem
                if (strpos($e2->getMessage(), 'produto_id') !== 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, gateway, device_id, external_reference, metadados, link_entregavel) 
                                           VALUES (:nome, :sobrenome, :email, :telefone, :cpf, :device_ip, :valor, :descricao, :status, :tipo_pagamento, :gateway, :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'] : null,
                        ':valor' => round((float)$data['transaction_amount'], 2),
                        ':descricao' => isset($data['description']) ? $data['description'] : 'Pagamento via Pagar.me',
                        ':status' => 'Pendente',
                        ':tipo_pagamento' => $tipo_pagamento,
                        ':gateway' => 'pagarme',
                        ':device_id' => isset($data['device_id']) ? $data['device_id'] : null,
                        ':external_reference' => $external_reference,
                        ':metadados' => json_encode(isset($data['additional_products']) ? $data['additional_products'] : []),
                        ':link_entregavel' => isset($data['link_entregavel']) ? $data['link_entregavel'] : (isset($data['product']['link_entregavel']) ? $data['product']['link_entregavel'] : '')
                    ]);
                } else {
                    throw $e2;
                }
            }
        } else {
            throw $e;
        }
    }

    // Obtém o último ID inserido no banco de dados
    $transaction_id = $pdo->lastInsertId();

    // Inserir cada produto adicional na tabela `transacoes_adicionais`
    if (isset($data['additional_products']) && is_array($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)
            ]);
        }
    }

    // ============ MOCK: SIMULAÇÃO DE PAGAMENTO PAGAR.ME ============
    // TODO: Implementar chamada real à API Pagar.me V5
    // Por enquanto, retorna sucesso simulado para testar o Frontend
    
    // Simulação: 90% de chance de sucesso, 10% de falha (para testes)
    $simular_erro = (rand(1, 100) > 90);
    
    if ($simular_erro) {
        // Simular erro
        $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Falha', erro = :erro WHERE id = :id");
        $stmt->execute([
            ':erro' => 'Erro simulado para testes',
            ':id' => $transaction_id
        ]);
        
        echo json_encode([
            'status' => 'failure',
            'message' => 'Pagamento recusado. Tente novamente.'
        ]);
        exit;
    }
    
    // Simular sucesso
    $mock_payment_id = 'pagarme_' . uniqid() . '_' . time();
    
    // Se for PIX, simular QR Code
    if ($is_pix) {
        $mock_qr_code = '00020126330014BR.GOV.BCB.PIX0114+55119999999995204000053039865802BR5913PAGARME TEST6009SAO PAULO62070503***6304' . strtoupper(dechex(crc32('pagarme_test_' . $transaction_id)));
        $mock_qr_code_base64 = base64_encode($mock_qr_code);
        
        // Atualiza a transação com QR Code simulado
        $stmt = $pdo->prepare("UPDATE transacoes SET qr_code = :qr_code, qr_code_base64 = :qr_code_base64, payment_id = :payment_id, status = 'Pendente' WHERE id = :id");
        $stmt->execute([
            ':qr_code' => $mock_qr_code,
            ':qr_code_base64' => $mock_qr_code_base64,
            ':payment_id' => $mock_payment_id,
            ':id' => $transaction_id
        ]);
        
        echo json_encode([
            'status' => 'success',
            'qr_code_base64' => $mock_qr_code_base64,
            'qr_code' => $mock_qr_code,
            'transaction_id' => $transaction_id,
            'payment_id' => $mock_payment_id
        ]);
    } else {
        // Pagamento com cartão aprovado
        $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Aprovado', payment_id = :payment_id WHERE id = :id");
        $stmt->execute([
            ':payment_id' => $mock_payment_id,
            ':id' => $transaction_id
        ]);
        
        // Calcular e registrar comissões
        if ($produto_id && $produtor_id) {
            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,
                        $produto_id,
                        $produtor_id,
                        $afiliado_id,
                        round((float)$data['transaction_amount'], 2)
                    );
                }
            } catch (PDOException $e) {
                error_log("Erro ao verificar comissão duplicada em process_payment_pagarme: " . $e->getMessage());
            }
        }
        
        echo json_encode([
            'status' => 'success',
            'payment_id' => $mock_payment_id,
            'transaction_id' => $transaction_id,
            'fbq_event' => [
                'value' => $data['transaction_amount'],
                'currency' => 'BRL'
            ]
        ]);
    }
    
} catch (Exception $e) {
    // Log do erro
    error_log('Erro no pagamento Pagar.me: ' . $e->getMessage());

    // Atualiza a transação com o status de erro
    if (isset($transaction_id)) {
        try {
            $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Erro', erro = :erro WHERE id = :id");
            $stmt->execute([
                ':erro' => $e->getMessage(),
                ':id' => $transaction_id
            ]);
        } catch (PDOException $pdo_error) {
            error_log("Erro ao atualizar transação com erro: " . $pdo_error->getMessage());
        }
    }

    // Retorna o erro em formato JSON
    echo json_encode(['status' => 'error', 'message' => 'Erro ao processar pagamento Pagar.me: ' . $e->getMessage()]);
}
?>


