<?php
// envio.php (SISTEMA DE PAGAMENTO BLINDADO)

// 1. SEGURANÇA E CONEXÃO
require_once '../conexao.php';
require '../config_seguranca.php'; // Inicia sessão segura

// Configuração de erro segura
ini_set('display_errors', 0); 

// 2. VERIFICAÇÕES INICIAIS
if (!isset($_SESSION['user_id']) || !isset($_SESSION['user_wallet'])) {
    header("Location: ../login.php");
    exit();
}

$remetente_id = $_SESSION['user_id'];
$remetente_wallet = $_SESSION['user_wallet'];
$csrf_token = $_SESSION['csrf_token'];

// Apenas POST
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    die("Acesso inválido.");
}

// 3. BARREIRA CSRF
verificarTokenCSRF();

// --- DADOS DO FORMULÁRIO ---
// Sanitização agressiva no destinatário (apenas alfanumérico)
$destinatario = preg_replace('/[^a-zA-Z0-9]/', '', $_POST['destinatario'] ?? '');
$valor_post = $_POST['valor'] ?? '0';
$pin_digitado = $_POST['pin'] ?? '';

// Tratamento monetário (Brasil -> EUA)
if (strpos($valor_post, ',') !== false) {
    $valor_post = str_replace('.', '', $valor_post); // Remove milhar
    $valor_post = str_replace(',', '.', $valor_post); // Vírgula vira ponto
}

// Formata para BCMath ("10.50")
$valor = number_format((float)$valor_post, 2, '.', '');

try {
    // A. Validações Básicas
    // Valor deve ser maior que 0.00
    if (bccomp($valor, '0.00', 2) <= 0) {
        throw new Exception("Valor inválido ou zerado.");
    }

    if ($destinatario === $remetente_wallet) {
        throw new Exception("Não é permitido enviar para si mesmo.");
    }

    if (empty($pin_digitado)) {
        throw new Exception("O PIN é obrigatório.");
    }

    // B. Validação do PIN (Direto do Banco - Anti-Hijacking)
    $stmtPin = $pdo->prepare("SELECT pin FROM usersblock WHERE id = ? LIMIT 1");
    $stmtPin->execute([$remetente_id]);
    $hash_real = $stmtPin->fetchColumn();
    
    if (!$hash_real || !password_verify($pin_digitado, $hash_real)) {
        // Log de erro de segurança (opcional, mas recomendado)
        // $stmtLog = $pdo->prepare("INSERT INTO tentativas_pin ...");
        sleep(1);
        throw new Exception("PIN incorreto.");
    }

    // --- INÍCIO DA TRANSAÇÃO FINANCEIRA ---
    $pdo->beginTransaction();

    // C. Verifica Destinatário
    $stmtDest = $pdo->prepare("SELECT wallet FROM usersblock WHERE wallet = ? LIMIT 1");
    $stmtDest->execute([$destinatario]);
    
    if (!$stmtDest->fetch()) {
        throw new Exception("Carteira de destino não encontrada.");
    }

    // D. Verifica e Trava Saldo (FOR UPDATE)
    // O FOR UPDATE impede que o saldo seja lido/gasto por outra requisição simultânea
    $stmtSaldo = $pdo->prepare("SELECT saldo FROM carteiras_saldos WHERE wallet = ? LIMIT 1 FOR UPDATE");
    $stmtSaldo->execute([$remetente_wallet]);
    $saldo_atual = $stmtSaldo->fetchColumn();

    // Se a carteira não existe na tabela de saldos, cria com 0 (prevenção)
    if ($saldo_atual === false) {
        $stmtIns = $pdo->prepare("INSERT INTO carteiras_saldos (wallet, saldo) VALUES (?, 0.00)");
        $stmtIns->execute([$remetente_wallet]);
        $saldo_atual = '0.00';
    }

    // Verifica se tem dinheiro (BCMath)
    // Se saldo (-1) for menor que valor
    if (bccomp($saldo_atual, $valor, 2) === -1) {
        throw new Exception("Saldo insuficiente.");
    }

    // Trava carteira Destino também (evita conflito de update lá)
    $stmtLockDest = $pdo->prepare("SELECT saldo FROM carteiras_saldos WHERE wallet = ? LIMIT 1 FOR UPDATE");
    $stmtLockDest->execute([$destinatario]);
    if ($stmtLockDest->fetchColumn() === false) {
        $stmtIns = $pdo->prepare("INSERT INTO carteiras_saldos (wallet, saldo) VALUES (?, 0.00)");
        $stmtIns->execute([$destinatario]);
    }

    // E. Executa a Transferência (Atomic Swap)
    $stmtUpdRem = $pdo->prepare("UPDATE carteiras_saldos SET saldo = saldo - ? WHERE wallet = ?");
    $stmtUpdRem->execute([$valor, $remetente_wallet]);

    $stmtUpdDest = $pdo->prepare("UPDATE carteiras_saldos SET saldo = saldo + ? WHERE wallet = ?");
    $stmtUpdDest->execute([$valor, $destinatario]);

    // F. Gera Histórico (Mempool e Infossistema)
    $hash = hash('sha256', $destinatario . $remetente_wallet . $valor . microtime());
    $link = bin2hex(random_bytes(25));
    
    $valor_formatado = number_format($valor, 2, ',', '.'); 
    
    // Texto solicitado: "A carteira $remetente enviou R$ X para a carteira $destinatario"
    $referencia = "A carteira $remetente_wallet enviou R$ $valor_formatado para a carteira $destinatario";

    // Mempool (Log Financeiro Oficial)
    $stmtMempool = $pdo->prepare("INSERT INTO mempool (destinatario, remetente, dataehora, valor, hash, link, referencia) VALUES (?, ?, NOW(), ?, ?, ?, ?)");
    $stmtMempool->execute([$destinatario, $remetente_wallet, $valor, $hash, $link, $referencia]);

    // Infossistema (Log Geral / Blockchain Visual)
    $stmtInfo = $pdo->prepare("INSERT INTO infossistema (informacao, p1, p2, origem, dataehora) VALUES (?, ?, ?, 'Envio de dinheiro', NOW())");
    // P1 e P2 = Wallets (para busca)
    $stmtInfo->execute([$referencia, $remetente_wallet, $destinatario]);

    // G. Finaliza
    $pdo->commit();

    // Mensagem de Sucesso
    $_SESSION['mensagem'] = "Transação de R$ " . $valor_formatado . " enviada com sucesso<br>Para a carteira:<br> $destinatario";
    // Opcional: passar o link para recibo
    // $_SESSION['linkhash'] = $link; 
    
    header('Location: mercado.php');
    exit;

} catch (Exception $e) {
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    $_SESSION['mensagem'] = "Erro: " . $e->getMessage();
    header('Location: mercado.php');
    exit;
}
?>