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

$conn = require __DIR__ . '/../../app/config/database.php';
require_login();
csrf_verify();

$admin = current_user();
$ref = trim($_POST['ref'] ?? '');
$do  = trim($_POST['do'] ?? '');
$txHash = trim($_POST['tx_hash'] ?? '');

if (!$ref || !in_array($do, ['approve','reject'], true)) {
  flash('err','Invalid request');
  redirect('crypto_txn_review.php');
}

try {
  $conn->begin_transaction();

  // Lock txn row
  $st = $conn->prepare("
    SELECT ref,user_id,asset_id,amount,fee,total_debit,status
    FROM crypto_txn
    WHERE ref=? AND type='send'
    FOR UPDATE
  ");
  $st->bind_param("s", $ref);
  $st->execute();
  $t = $st->get_result()->fetch_assoc();

  if (!$t || $t['status'] !== 'awaiting_admin') {
    $conn->rollback();
    throw new Exception('Transaction not in awaiting_admin state.');
  }

  $userId = (int)$t['user_id'];
  $assetId = (int)$t['asset_id'];
  $totalDebit = (float)$t['total_debit'];

  // 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);

  if ($locked < $totalDebit) {
    $conn->rollback();
    throw new Exception('Locked balance inconsistent (cannot settle).');
  }

  if ($do === 'approve') {
    // Settle: reduce balance AND release lock
    if ($bal < $totalDebit) {
      $conn->rollback();
      throw new Exception('Wallet balance insufficient to approve (data inconsistency).');
    }
    $newBal = $bal - $totalDebit;
    $newLocked = $locked - $totalDebit;

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

    $up2 = $conn->prepare("
      UPDATE crypto_txn
      SET status='approved', decision='approved', reviewed_by=?, reviewed_at=NOW(), tx_hash=?
      WHERE ref=? AND type='send'
    ");
    $up2->bind_param("iss", $admin['id'], $txHash, $ref);
    $up2->execute();

    $meta = json_encode(['ref'=>$ref,'total_debit'=>$totalDebit,'tx_hash'=>$txHash]);
    $ip = client_ip();
    $ev = $conn->prepare("INSERT INTO crypto_txn_events (txn_ref,actor_id,event,meta,ip) VALUES (?,?, 'CRYPTO_SEND_APPROVED', ?, ?)");
    $ev->bind_param("siss", $ref, $admin['id'], $meta, $ip);
    $ev->execute();

    flash('msg', 'Approved and settled (locked funds deducted).');

  } else {
    // Reject: release lock only, balance stays
    $newLocked = $locked - $totalDebit;

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

    $up2 = $conn->prepare("
      UPDATE crypto_txn
      SET status='rejected', decision='rejected', reviewed_by=?, reviewed_at=NOW()
      WHERE ref=? AND type='send'
    ");
    $up2->bind_param("is", $admin['id'], $ref);
    $up2->execute();

    $meta = json_encode(['ref'=>$ref,'total_debit'=>$totalDebit]);
    $ip = client_ip();
    $ev = $conn->prepare("INSERT INTO crypto_txn_events (txn_ref,actor_id,event,meta,ip) VALUES (?,?, 'CRYPTO_SEND_REJECTED', ?, ?)");
    $ev->bind_param("siss", $ref, $admin['id'], $meta, $ip);
    $ev->execute();

    flash('msg', 'Rejected and funds unlocked.');
  }

  $conn->commit();
  redirect('crypto_txn_review.php');

} catch (Throwable $e) {
  if ($conn->errno) { /* ignore */ }
  flash('err', $e->getMessage());
  redirect('crypto_txn_review.php');
}
