<?php
require_once __DIR__ . '/../../app/helpers/functions.php';
require_once __DIR__ . '/../../app/helpers/csrf.php';
require_once __DIR__ . '/../../app/helpers/crypto_tools.php';
require_once __DIR__ . '/../../app/middleware/auth.php';

$conn = require __DIR__ . '/../../app/config/database.php';

require_login();
csrf_verify();
$admin = current_user();

$userId  = (int)($_POST['user_id'] ?? 0);
$assetId = (int)($_POST['asset_id'] ?? 0);
$amount  = (float)($_POST['amount'] ?? 0);
$mode    = trim($_POST['mode'] ?? 'credit'); // credit | debit
$source  = trim($_POST['source'] ?? 'platform'); // platform | cold
$note    = trim($_POST['note'] ?? '');

if ($userId < 1 || $assetId < 1 || $amount <= 0) {
  flash('err', 'Invalid input.');
  redirect('crypto_admin_dashboard.php');
}

if (!in_array($mode, ['credit','debit'], true)) {
  flash('err', 'Invalid mode.');
  redirect('crypto_admin_dashboard.php');
}

try {
  $conn->begin_transaction();

  ensure_wallet($conn, $userId, $assetId);

  // Lock wallet row
  $st = $conn->prepare("
    SELECT balance, locked_balance
    FROM crypto_wallets
    WHERE user_id=? AND asset_id=?
    FOR UPDATE
  ");
  $st->bind_param("ii", $userId, $assetId);
  $st->execute();
  $w = $st->get_result()->fetch_assoc();

  $bal    = (float)($w['balance'] ?? 0);
  $locked = (float)($w['locked_balance'] ?? 0);
  $available = $bal - $locked;

  // Optional cold reserve lock
  if ($source === 'cold') {
    cold_reserve_ensure($conn, $assetId);

    $st2 = $conn->prepare("SELECT balance FROM crypto_cold_reserve WHERE asset_id=? FOR UPDATE");
    $st2->bind_param("i", $assetId);
    $st2->execute();
    $cr = $st2->get_result()->fetch_assoc();
    $coldBal = (float)($cr['balance'] ?? 0);

    if ($mode === 'credit' && $coldBal < $amount) {
      $conn->rollback();
      throw new Exception('Cold reserve insufficient.');
    }

    // Adjust cold reserve: credit to user reduces cold reserve; debit from user increases reserve (optional)
    if ($mode === 'credit') {
      $newCold = $coldBal - $amount;
    } else {
      $newCold = $coldBal + $amount;
    }

    $upC = $conn->prepare("UPDATE crypto_cold_reserve SET balance=? WHERE asset_id=?");
    $upC->bind_param("di", $newCold, $assetId);
    $upC->execute();
  }

  if ($mode === 'credit') {
    $newBal = $bal + $amount;

  } else { // debit (burn)
    // Burn only from AVAILABLE funds
    if ($available < $amount) {
      $conn->rollback();
      throw new Exception('User available balance insufficient (some funds may be locked).');
    }
    $newBal = $bal - $amount;
  }

  $up = $conn->prepare("UPDATE crypto_wallets SET balance=? WHERE user_id=? AND asset_id=?");
  $up->bind_param("dii", $newBal, $userId, $assetId);
  $up->execute();

  // Record txn
  $ref = now_ref($mode === 'credit' ? 'ADMCR' : 'ADMDB');
  $type = ($mode === 'credit') ? 'admin_credit' : 'admin_debit';

  $st3 = $conn->prepare("
    INSERT INTO crypto_txn
      (ref,user_id,asset_id,type,amount,fee,total_debit,status,destination,created_at)
    VALUES
      (?,?,?, ?, ?, 0, 0, 'approved', ?, NOW())
  ");
  $dest = ($mode === 'debit')
    ? ('BURN' . ($note ? ' - '.$note : ''))
    : ('ADMIN_TOPUP' . ($note ? ' - '.$note : ''));

  $st3->bind_param("siisds", $ref, $userId, $assetId, $type, $amount, $dest);
  $st3->execute();

  // Audit
  $meta = json_encode([
    'user_id'=>$userId,'asset_id'=>$assetId,'amount'=>$amount,'mode'=>$mode,'source'=>$source,'note'=>$note
  ]);
  $ip = client_ip();

  $st4 = $conn->prepare("
    INSERT INTO audit_logs (actor_id, action, meta, ip)
    VALUES (?, 'ADMIN_CRYPTO_ADJUST', ?, ?)
  ");
  $st4->bind_param("iss", $admin['id'], $meta, $ip);
  $st4->execute();

  $conn->commit();

  flash('msg', $mode === 'credit' ? 'Wallet credited.' : 'Wallet debited (burned).');
  redirect('crypto_admin_dashboard.php');

} catch (Throwable $e) {
  $conn->rollback();
  flash('err', $e->getMessage());
  redirect('crypto_admin_dashboard.php');
}
