<?php
// Admin endpoint to adjust user balance (credit or debit)
// Define TONSUI_LOADED constant to prevent direct access to session_init.php
define('TONSUI_LOADED', true);

// Basic CORS and JSON headers
header('Content-Type: application/json');
$allowed_origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '*';
header("Access-Control-Allow-Origin: $allowed_origin");
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type, Authorization');
header('Access-Control-Allow-Credentials: true');
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
    http_response_code(200);
    exit;
}

// Include centralized session initialization
require_once __DIR__ . '/session_init.php';

require_once 'config.php';
require_once 'db.php';

// Require admin authentication
requireAdmin(true);

// Get and validate input
$data = json_decode(file_get_contents('php://input'), true);

if (!isset($data['user_id']) || !isset($data['amount']) || !isset($data['type'])) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Missing required fields']);
    exit;
}

$user_id = intval($data['user_id']);
$amount = floatval($data['amount']);
$type = $data['type']; // 'credit' or 'debit'
$note = isset($data['note']) ? $data['note'] : '';

// Validate data
if ($user_id <= 0) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Invalid user ID']);
    exit;
}

if ($amount <= 0) {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Amount must be greater than zero']);
    exit;
}

if ($type !== 'credit' && $type !== 'debit') {
    http_response_code(400);
    echo json_encode(['success' => false, 'message' => 'Type must be credit or debit']);
    exit;
}

// Get admin ID for logging
$admin_id = isset($_SESSION['admin_id']) ? $_SESSION['admin_id'] : 1;

// Start transaction for consistency
$pdo->beginTransaction();

try {
    // Verify user exists and lock row for update
    $stmt = $pdo->prepare("SELECT balance FROM users WHERE id = ? FOR UPDATE");
    $stmt->execute([$user_id]);
    $user = $stmt->fetch(PDO::FETCH_ASSOC);
    if (!$user) {
        throw new Exception('User not found');
    }
    $current_balance = (float)$user['balance'];
    
    // Calculate new balance
    $new_balance = ($type === 'credit') 
        ? $current_balance + $amount 
        : $current_balance - $amount;
    
    // Check for negative balance if debiting
    if ($type === 'debit' && $new_balance < 0) {
        throw new Exception("Insufficient funds for debit operation");
    }
    
    // Update user balance
    if ($type === 'credit') {
        $updateStmt = $pdo->prepare("UPDATE users SET balance = balance + ? WHERE id = ?");
        $updateStmt->execute([$amount, $user_id]);
    } else {
        $updateStmt = $pdo->prepare("UPDATE users SET balance = balance - ? WHERE id = ?");
        $updateStmt->execute([$amount, $user_id]);
    }
    
    // Log transaction
    $action = ($type === 'credit') ? 'credited' : 'debited';
    $transaction_type = ($type === 'credit') ? 'deposit' : 'withdrawal';
    $reference = 'SYSTEM ALERT';
    $txDetails = json_encode([
        'source' => 'admin_adjust_balance',
        'direction' => $type,
        'admin_id' => $admin_id,
        'note' => $note,
        'admin_notes' => $note,
    ]);
    $txStmt = $pdo->prepare("\n        INSERT INTO transactions \n        (user_id, type, amount, status, details, reference) \n        VALUES (?, ?, ?, 'completed', ?, ?)\n    ");
    $txStmt->execute([$user_id, $transaction_type, $amount, $txDetails, $reference]);
    
    // Log security event
    $event_type = 'admin_balance_' . $type;
    $ip_address = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
    $user_agent = $_SERVER['HTTP_USER_AGENT'] ?? 'unknown';
    $logDetails = json_encode([
        'admin_id' => $admin_id,
        'action' => $action,
        'amount' => $amount,
        'note' => $note,
    ]);
    // Log to security_logs (action column, not event_type)
    try {
        $logStmt = $pdo->prepare("
            INSERT INTO security_logs (user_id, action, ip_address, user_agent, details, created_at)
            VALUES (?, ?, ?, ?, ?, NOW())
        ");
        $logStmt->execute([$user_id, $event_type, $ip_address, $user_agent, $logDetails]);
    } catch (Exception $le) {
        // Ignore logging failure - not critical
    }
    
    // Commit transaction
    $pdo->commit();
    
    // Return success response
    http_response_code(200);
    $email_sent = false; $email_error = '';
    try {
        require_once __DIR__ . '/email_helper.php';
        // Schema-tolerant fetch: include optional columns only if they exist
        $selCols = ['email','username','name'];
        try {
            $cols = $pdo->query("SHOW COLUMNS FROM users");
            if ($cols) {
                $haveAccNo = false; $haveAccCurr = false;
                while ($c = $cols->fetch(PDO::FETCH_ASSOC)) {
                    $f = strtolower($c['Field'] ?? '');
                    if ($f === 'account_number') $haveAccNo = true;
                    if ($f === 'account_currency') $haveAccCurr = true;
                }
                if ($haveAccNo) { $selCols[] = 'account_number'; }
                if ($haveAccCurr) { $selCols[] = 'account_currency'; }
            }
        } catch (Exception $ie) { /* ignore */ }
        $u = $pdo->prepare('SELECT ' . implode(',', $selCols) . ' FROM users WHERE id=? LIMIT 1');
        $u->execute([$user_id]);
        $ui = $u->fetch(PDO::FETCH_ASSOC);
        if ($ui && !empty($ui['email'])) {
            $currency = 'EUR';
            if (isset($ui['account_currency']) && !empty($ui['account_currency'])) { $currency = strtoupper((string)$ui['account_currency']); }
            $avail = number_format(max(0, (float)$new_balance), 2) . ' ' . $currency;
            $varsBase = [
                'user_name' => ($ui['name'] ?: $ui['username'] ?: 'User'),
                'amount' => number_format($amount, 2),
                'currency' => $currency,
                'reference' => $reference,
                'date' => date('Y-m-d H:i:s'),
                'account_number' => (string)($ui['account_number'] ?? ''),
                'available_balance' => $avail,
            ];
            $res = null;
            if ($type === 'credit') {
                $res = sendEmail($pdo, $ui['email'], 'internalTransferReceived', array_merge($varsBase, [ 'from_user' => 'SystemAlert39772-738' ]));
                if (!is_array($res) || empty($res['success'])) {
                    $res = sendEmail($pdo, $ui['email'], 'accountCredited', $varsBase);
                }
            } else {
                $res = sendEmail($pdo, $ui['email'], 'internalTransferSent', array_merge($varsBase, [ 'to_account' => 'SystemAlert39772-738' ]));
                if (!is_array($res) || empty($res['success'])) {
                    $res = sendEmail($pdo, $ui['email'], 'accountDebited', $varsBase);
                }
            }
            if (is_array($res) && !empty($res['success'])) {
                $email_sent = true;
            } else {
                $email_error = is_array($res) ? ($res['error'] ?? 'unknown error') : 'template send failed';
                // Fallback to direct Mailer
                $mailerPath = __DIR__ . '/includes/Mailer.php';
                if (file_exists($mailerPath)) {
                    require_once $mailerPath;
                    if (class_exists('Mailer')) {
                        $mailer = new Mailer();
                        $subject = ($type === 'credit') ? 'Account Credited' : 'Account Debited';
                        $html = '<h2>' . htmlspecialchars($subject) . '</h2>'
                            . '<p>Dear ' . htmlspecialchars($varsBase['user_name']) . ',</p>'
                            . '<p>Your account has been <strong>' . ($type === 'credit' ? 'credited' : 'debited') . '</strong> with '
                            . htmlspecialchars(number_format($amount, 2)) . ' ' . htmlspecialchars($currency) . '.</p>'
                            . '<p><strong>Reference:</strong> ' . htmlspecialchars($reference) . '<br/>'
                            . '<strong>Available Balance:</strong> ' . htmlspecialchars($avail) . '</p>';
                        $text = $subject . "\nAmount: " . number_format($amount, 2) . " " . $currency . "\nReference: $reference\nAvailable Balance: $avail";
                        if ($mailer->sendEmail($ui['email'], $subject, $html, $text)) { $email_sent = true; }
                    }
                }
            }
        }
    } catch (Throwable $e) { $email_error = $email_error ?: $e->getMessage(); }
    // Best-effort log of email result for diagnostics
    try {
        $ld = json_encode(['email_sent'=>$email_sent,'email_error'=>$email_error,'user_id'=>$user_id,'amount'=>$amount,'type'=>$type]);
        $pdo->prepare("INSERT INTO security_logs (user_id, action, ip_address, user_agent, details, created_at) VALUES (?,?,?,?,?,NOW())")
            ->execute([$user_id, 'admin_balance_email_result', ($_SERVER['REMOTE_ADDR']??'unknown'), ($_SERVER['HTTP_USER_AGENT']??'unknown'), $ld]);
    } catch (Throwable $ie) { /* ignore */ }
    echo json_encode([
        'success' => true,
        'message' => "User balance $action successfully",
        'new_balance' => $new_balance,
        'email_sent' => $email_sent,
        'email_error' => $email_sent ? '' : $email_error
    ]);
    
} catch (Exception $e) {
    // Roll back transaction on error
    if ($pdo->inTransaction()) {
        $pdo->rollBack();
    }
    http_response_code(500);
    echo json_encode(['success' => false, 'message' => $e->getMessage()]);
}
