<?php
/**
 * transfer_balance.php
 * Move funds between a user's internal wallets (USD, TON, SUI, REF).
 * Schema-tolerant: only updates columns that exist, and rejects unsupported wallets.
 */

// Define TONSUI_LOADED constant to prevent direct access to session_init.php
if (!defined('TONSUI_LOADED')) {
  define('TONSUI_LOADED', true);
}

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

header('Content-Type: application/json');
// Critical: Add cache control headers
header('Cache-Control: no-cache, no-store, must-revalidate');
header('Pragma: no-cache');
header('Expires: 0');
// CRITICAL: Allow origin with credentials
$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');

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
  http_response_code(200);
  exit;
}

// Require user authentication
requireLogin(true);

require_once __DIR__ . '/db.php';

function respond($success, $message, $data = null, $code = 200) {
  if ($code !== 200) http_response_code($code);
  $res = ['success' => $success, 'message' => $message];
  if ($data !== null) $res['data'] = $data;
  echo json_encode($res);
  exit;
}

try {
  if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
    respond(false, 'Method not allowed', null, 405);
  }

  $input = json_decode(file_get_contents('php://input'), true) ?: [];
  $from = strtoupper(trim($input['from_wallet'] ?? ''));
  $to = strtoupper(trim($input['to_wallet'] ?? ''));
  $toAmount = isset($input['amount']) ? (float)$input['amount'] : 0.0; // amount to credit to target wallet
  $fromAmount = isset($input['from_amount']) ? (float)$input['from_amount'] : 0.0; // amount to debit from source wallet

  $valid = ['USD','TON','SUI','REF'];
  if (!in_array($from, $valid, true) || !in_array($to, $valid, true)) {
    respond(false, 'Invalid wallet selection', null, 400);
  }
  if ($from === $to) {
    respond(false, 'Cannot transfer to the same wallet', null, 400);
  }
  if ($toAmount <= 0 || $fromAmount <= 0) {
    respond(false, 'Invalid amount', null, 400);
  }

  $userId = isset($_SESSION['user_id']) ? (int)$_SESSION['user_id'] : 0;
  if ($userId <= 0) {
    respond(false, 'Unauthorized', null, 401);
  }

  // Map wallet -> column names
  $walletCols = [
    'USD' => 'balance',
    'TON' => 'ton_balance',
    'SUI' => 'sui_balance',
    'REF' => 'referral_balance',
  ];

  // Detect available columns
  $available = [];
  try {
    $cols = $pdo->query('SHOW COLUMNS FROM users');
    while ($c = $cols->fetch(PDO::FETCH_ASSOC)) {
      $available[$c['Field']] = true;
    }
  } catch (Exception $e) {}

  $fromCol = $walletCols[$from] ?? null;
  $toCol = $walletCols[$to] ?? null;

  // Validate schema support
  if (!$fromCol || !($fromCol === 'balance' || isset($available[$fromCol]))) {
    respond(false, "Wallet $from not supported in current schema", null, 400);
  }
  if (!$toCol || !($toCol === 'balance' || isset($available[$toCol]))) {
    respond(false, "Wallet $to not supported in current schema", null, 400);
  }

  // Load user row
  $stmt = $pdo->prepare('SELECT * FROM users WHERE id = ?');
  $stmt->execute([$userId]);
  $user = $stmt->fetch(PDO::FETCH_ASSOC);
  if (!$user) {
    respond(false, 'User not found', null, 404);
  }

  // Current balances with defaults
  $currentFrom = 0.0;
  if ($fromCol === 'balance') $currentFrom = (float)($user['balance'] ?? 0);
  else $currentFrom = (float)($user[$fromCol] ?? 0);

  if ($currentFrom < $fromAmount - 1e-8) {
    respond(false, 'Insufficient balance in source wallet', null, 400);
  }

  // Perform atomic update
  $pdo->beginTransaction();

  // Build dynamic SET parts
  $sets = [];
  $params = [];

  // Debit source
  $sets[] = "$fromCol = $fromCol - ?";
  $params[] = $fromAmount;

  // Credit target
  $sets[] = "$toCol = $toCol + ?";
  $params[] = $toAmount;

  if (in_array('updated_at', array_keys($available), true)) {
    $sets[] = 'updated_at = NOW()';
  }

  $sql = 'UPDATE users SET ' . implode(', ', $sets) . ' WHERE id = ?';
  $params[] = $userId;

  $update = $pdo->prepare($sql);
  $update->execute($params);

  // Security log
  try {
    $pdo->exec("CREATE TABLE IF NOT EXISTS security_logs (
      id INT AUTO_INCREMENT PRIMARY KEY,
      action VARCHAR(100) NOT NULL,
      user_id INT NOT NULL,
      ip_address VARCHAR(45) DEFAULT NULL,
      user_agent TEXT,
      details TEXT,
      created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci");

    $log = $pdo->prepare('INSERT INTO security_logs (action, user_id, ip_address, user_agent, details, created_at) VALUES (?, ?, ?, ?, ?, NOW())');
    $log->execute([
      'transfer_balance',
      $userId,
      $_SERVER['REMOTE_ADDR'] ?? 'unknown',
      $_SERVER['HTTP_USER_AGENT'] ?? 'unknown',
      json_encode([
        'from' => $from,
        'to' => $to,
        'from_amount' => $fromAmount,
        'to_amount' => $toAmount,
      ]),
    ]);
  } catch (Exception $e) { /* ignore */ }

  $pdo->commit();

  respond(true, 'Transfer completed successfully', [
    'from' => $from,
    'to' => $to,
    'from_amount' => $fromAmount,
    'to_amount' => $toAmount,
  ]);

} catch (Exception $e) {
  if (isset($pdo) && $pdo->inTransaction()) { try { $pdo->rollBack(); } catch (Exception $ie) {} }
  respond(false, 'Failed to transfer funds: ' . $e->getMessage(), null, 500);
}
