<?php
/**
 * Backend Stripe - Checkout Pro 2025
 * Processamento de pagamento via Stripe (Cartão de Crédito)
 */

// Autoload do Composer
require __DIR__ . '/../vendor/autoload.php'; 

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

// Imports do Stripe
use Stripe\Stripe;
use Stripe\PaymentIntent;
use Stripe\Exception\ApiErrorException;

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

// Configurar a chave secreta do Stripe
$stripe_secret_key = get_gateway_config('stripe', 'secret_key');

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

try {
    Stripe::setApiKey($stripe_secret_key);
} catch (Exception $e) {
    echo json_encode(['status' => 'error', 'message' => 'Erro na configuração do Stripe: ' . $e->getMessage()]);
    exit;
}

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

    if (!isset($data['payment_method_id']) && !isset($data['payment_intent_id'])) {
        throw new Exception('Payment Method ID ou Payment Intent ID não foi fornecido.');
    }

    // 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('stripe_', 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 = $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 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());
            }
        }
    }

    // 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 inicialmente)
    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' => $data['description'],
            ':status' => 'Pendente',
            ':tipo_pagamento' => 'Cartão de Crédito',
            ':gateway' => 'stripe',
            ':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) {
        // 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' => $data['description'],
                    ':status' => 'Pendente',
                    ':tipo_pagamento' => 'Cartão de Crédito',
                    ':gateway' => 'stripe',
                    ':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: 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 || strpos($e2->getMessage(), 'gateway') !== 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'] : null,
                        ':valor' => round((float)$data['transaction_amount'], 2),
                        ':descricao' => $data['description'],
                        ':status' => 'Pendente',
                        ':tipo_pagamento' => 'Cartão de Crédito',
                        ':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;
        }
    }

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

    // Inserir cada produto adicional na tabela `transacoes_adicionais`
    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)
        ]);
    }

    // Criar Payment Intent no Stripe
    $amount_in_cents = round((float)$data['transaction_amount'] * 100); // Stripe usa centavos

    try {
        $paymentIntent = PaymentIntent::create([
            'amount' => $amount_in_cents,
            'currency' => 'brl',
            'payment_method' => $data['payment_method_id'],
            'confirmation_method' => 'manual',
            'confirm' => true,
            'description' => $data['description'],
            'metadata' => [
                'transaction_id' => $transaction_id,
                'external_reference' => $external_reference,
                'email' => $data['payer']['email']
            ]
        ]);

        if ($paymentIntent->status === 'succeeded') {
            // Atualizar transação como aprovada
            $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Aprovado', payment_id = :payment_id WHERE id = :id");
            $stmt->execute([
                ':payment_id' => $paymentIntent->id,
                ':id' => $transaction_id
            ]);

            // Calcular e registrar comissões (verificando duplicidade)
            if ($produto_id && $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,
                            $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_stripe: " . $e->getMessage());
                }
            }

            // Enviar email de confirmação (reusar função do Mercado Pago se existir)
            if (function_exists('enviarEmailProdutoDigital')) {
                enviarEmailProdutoDigital(
                    $data['payer']['email'],
                    $first_name,
                    $last_name,
                    $data['description'],
                    $data['product']['link_entregavel']
                );
            }

            echo json_encode([
                'status' => 'success',
                'payment_id' => $paymentIntent->id,
                'message' => 'Pagamento aprovado com sucesso!'
            ]);
        } else {
            // Pagamento requer ação adicional (3D Secure, etc.)
            echo json_encode([
                'status' => 'requires_action',
                'payment_intent_id' => $paymentIntent->id,
                'client_secret' => $paymentIntent->client_secret
            ]);
        }
    } catch (ApiErrorException $e) {
        // Erro do Stripe
        $error_message = 'Erro ao processar pagamento: ' . $e->getMessage();
        error_log("Erro Stripe: " . $e->getMessage());

        $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Falha', erro = :erro WHERE id = :id");
        $stmt->execute([
            ':erro' => $e->getMessage(),
            ':id' => $transaction_id
        ]);

        echo json_encode(['status' => 'failure', 'message' => $error_message]);
    } catch (Exception $e) {
        error_log("Erro geral no Stripe: " . $e->getMessage());
        
        $stmt = $pdo->prepare("UPDATE transacoes SET status = 'Erro', erro = :erro WHERE id = :id");
        $stmt->execute([
            ':erro' => $e->getMessage(),
            ':id' => $transaction_id
        ]);

        echo json_encode(['status' => 'error', 'message' => 'Erro ao processar pagamento. Tente novamente.']);
    }
} catch (Exception $e) {
    error_log("Erro fatal no Stripe: " . $e->getMessage());
    echo json_encode(['status' => 'error', 'message' => 'Erro ao processar solicitação.']);
}
?>


