<?php
declare(strict_types=1);
session_start();
ini_set('display_errors', '1'); error_reporting(E_ALL);

require_once __DIR__ . '/../includes/db.php';
require_once __DIR__ . '/../includes/auth.php';
require_once __DIR__ . '/../includes/helpers.php';
require_once __DIR__ . '/../includes/config.php';

// Check if user is logged in
if (!isset($_SESSION['uid'])) { header('Location: login.php'); exit; }

$tx_id = (int)($_GET['tx_id'] ?? 0);
$uid = (int)($_SESSION['uid'] ?? 0);
$pin_input = '';
$error = '';
$amount_display = 'N/A'; // Default display amount

try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    // --- PART A: LOAD PENDING TRANSACTION AND DISPLAY PIN FORM ---
    if ($_SERVER['REQUEST_METHOD'] === 'GET') {
        if ($tx_id <= 0) throw new RuntimeException('Invalid transaction ID.');

        // Fetch transaction and sender data
        $stmt = $pdo->prepare("
            SELECT t.amount_cents, u.account_number, u.balance_cents
            FROM transactions t
            JOIN users u ON t.user_id = u.id
            WHERE t.id = ? AND t.user_id = ? AND t.status = 'PENDING_AUTH'
        ");
        $stmt->execute([$tx_id, $uid]);
        $tx_data = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$tx_data) throw new RuntimeException('Transaction not found or already processed.');
        
        $amount_cents = (int)$tx_data['amount_cents'];
        $amount_display = number_format($amount_cents / 100, 2);

        // --- HTML for PIN INPUT ---
        // Display the PIN input form to the user
        ?>
        <!DOCTYPE html>
        <html>
        <head>
            <title>Secure Transaction Portal</title>
            <link rel="stylesheet" href="path/to/your/styles.css"> </head>
        <body>
            <h1>Secure Transaction Portal</h1>
            <?php if (!empty($_SESSION['flash_error'])) { echo '<p style="color:red;">' . htmlspecialchars($_SESSION['flash_error']) . '</p>'; unset($_SESSION['flash_error']); } ?>
            <?php if (!empty($_SESSION['flash_info'])) { echo '<p style="color:blue;">' . htmlspecialchars($_SESSION['flash_info']) . '</p>'; unset($_SESSION['flash_info']); } ?>

            <p>Please confirm the details and enter your Transaction PIN to authorize the transfer.</p>
            <p><strong>Amount:</strong> ₦<?php echo $amount_display; ?></p>
            
            <form method="POST" action="<?php echo url('transfer_authorize.php'); ?>">
                <input type="hidden" name="tx_id" value="<?php echo $tx_id; ?>">
                <input type="hidden" name="csrf" value="<?php echo htmlspecialchars($_SESSION['csrf']); ?>">
                <label for="pin_input">Transaction PIN (4-6 digits):</label>
                <input type="password" id="pin_input" name="pin_input" maxlength="6" required>
                <button type="submit">Authorize ₦<?php echo $amount_display; ?></button>
            </form>
            <p><a href="<?php echo url('dashboard.php'); ?>">Cancel Transfer</a></p>
        </body>
        </html>
        <?php
        exit;
    } 
    // --- PART B: PROCESS PIN SUBMISSION ---
    else if ($_SERVER['REQUEST_METHOD'] === 'POST') {
        $tx_id = (int)($_POST['tx_id'] ?? 0);
        $pin_input = trim($_POST['pin_input'] ?? '');

        // Basic validation for ID and PIN format
        if ($tx_id <= 0 || !preg_match('/^\d{4,6}$/', $pin_input)) { 
            throw new RuntimeException('Invalid PIN or request.');
        }

        // CSRF Check
        if (empty($_POST['csrf']) || !hash_equals($_SESSION['csrf'] ?? '', $_POST['csrf'])) {
            throw new RuntimeException('Invalid request token');
        }

        $pdo->beginTransaction();

        // 1. Lock sender and fetch security data (PIN hash, attempts)
        $stmt = $pdo->prepare("
            SELECT id, account_number, balance_cents, transaction_pin_hash, pin_attempts, is_locked 
            FROM users 
            WHERE id = ? FOR UPDATE
        ");
        $stmt->execute([$uid]);
        $sender = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$sender || (int)$sender['is_locked'] === 1) {
            throw new RuntimeException('Account access denied or locked.');
        }

        // 2. Fetch PENDING transaction details
        $stmt = $pdo->prepare("
            SELECT * FROM transactions 
            WHERE id = ? AND user_id = ? AND status = 'PENDING_AUTH' FOR UPDATE
        ");
        $stmt->execute([$tx_id, $uid]);
        $pending_tx = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$pending_tx) {
            throw new RuntimeException('Pending transfer not found or already processed.');
        }
        
        $amount_cents = (int)$pending_tx['amount_cents'];
        $sender_before = (int)$sender['balance_cents'];
        $sender_after = $sender_before - $amount_cents;

        // 3. Verify PIN
        if (!password_verify($pin_input, $sender['transaction_pin_hash'])) {
            // PIN failed: Increment attempt counter and re-check lock status
            $new_attempts = (int)$sender['pin_attempts'] + 1;
            $is_locked = ($new_attempts >= 5) ? 1 : 0; // Lock after 5 attempts (customize this)

            $pdo->prepare("UPDATE users SET pin_attempts = ?, is_locked = ? WHERE id = ?")
                ->execute([$new_attempts, $is_locked, $uid]);
            
            // Rollback only if the lock logic is the last thing we do before the failure
            $pdo->commit(); // Commit the lock update

            if ($is_locked) {
                $_SESSION['flash_error'] = 'PIN failed. Account locked. Contact support.';
            } else {
                $attempts_left = 5 - $new_attempts;
                $_SESSION['flash_error'] = "Invalid PIN. {$attempts_left} attempts remaining.";
            }
            header('Location: ' . url('dashboard.php'));
            exit;
        }

        // PIN SUCCESSFUL: Reset attempts
        $pdo->prepare("UPDATE users SET pin_attempts = 0 WHERE id = ?")->execute([$uid]);
        
        // 4. EXECUTE TRANSFER AND LOG
        
        // A. Find Recipient (must be done after PIN is successful)
        // Note: The recipient account number is stored in the PENDING transaction's 'note' field for simplicity.
        $rec_acct_from_note = trim(explode('|', $pending_tx['note'])[0] ?? ''); // Extracts "Transfer to XXXXXX"
        $rec_acct = preg_replace('/[^0-9]/', '', $rec_acct_from_note); // Gets just the account number

        $stmt = $pdo->prepare("
            SELECT id, balance_cents 
            FROM users 
            WHERE account_number = ? FOR UPDATE
        ");
        $stmt->execute([$rec_acct]);
        $rec = $stmt->fetch(PDO::FETCH_ASSOC);

        if (!$rec) {
            throw new RuntimeException('Recipient account could not be found for execution.');
        }

        $rec_before = (int)$rec['balance_cents'];
        $rec_after = $rec_before + $amount_cents;
        
        // B. Update Balances
        $pdo->prepare("UPDATE users SET balance_cents = ? WHERE id = ?")
            ->execute([$sender_after, $sender['id']]);
        $pdo->prepare("UPDATE users SET balance_cents = ? WHERE id = ?")
            ->execute([$rec_after, $rec['id']]);

        // C. Update PENDING transaction (Sender Debit) to COMPLETED
        $pdo->prepare("
            UPDATE transactions 
            SET status = 'COMPLETED', balance_before_cents = ?, balance_after_cents = ?, reference = ?
            WHERE id = ?
        ")->execute([
            $sender_before, 
            $sender_after, 
            $pending_tx['reference'] . '-D', 
            $tx_id
        ]);

        // D. Insert CREDIT transaction (Recipient)
        $full_note_credit = 'Transfer from ' . $sender['account_number'];
        $pdo->prepare("
            INSERT INTO transactions 
            (user_id, kind, amount_cents, balance_before_cents, balance_after_cents, reference, note, status, created_at)
            VALUES (?, 'credit', ?, ?, ?, ?, ?, 'COMPLETED', NOW())
        ")->execute([
            $rec['id'],
            $amount_cents,
            $rec_before,
            $rec_after,
            $pending_tx['reference'] . '-C',
            $full_note_credit,
        ]);
        
        $pdo->commit();
        
        $_SESSION['flash_success'] = 'Transfer successfully authorized and completed.';
        header('Location: ' . url('dashboard.php'));
        exit;

    }

} catch (Throwable $e) {
    if ($pdo->inTransaction()) $pdo->rollBack();
    
    $_SESSION['flash_error'] = 'Authorization failed. Error: ' . htmlspecialchars($e->getMessage());
    header('Location: ' . url('dashboard.php'));
    exit;
}
?>