<?php
require_once __DIR__.'/../includes/db.php';
require_once __DIR__.'/../includes/auth.php';
require_once __DIR__.'/../includes/helpers.php';
require_once __DIR__.'/../includes/config.php';
require_admin();

if ($_SERVER['REQUEST_METHOD'] !== 'POST') { header('Location: approvals.php'); exit; }
if (($_POST['csrf'] ?? '') !== ($_SESSION['csrf'] ?? '')) { http_response_code(400); exit('Bad token'); }

$id  = (int)($_POST['id'] ?? 0);
$do  = $_POST['do'] ?? '';

try {
  if ($do === 'reject') {
    $st = $pdo->prepare("UPDATE transactions SET status='rejected', approved_at=NOW(), approved_by=:aid WHERE id=:id AND status='pending'");
    $st->execute([':aid'=>(int)$_SESSION['uid'], ':id'=>$id]);
    header('Location: approvals.php'); exit;
  }

  if ($do === 'approve') {
    // Fetch the pending debit row and lock it
    $t = $pdo->prepare("SELECT * FROM transactions WHERE id=:id FOR UPDATE");
    $pdo->beginTransaction();
    $t->execute([':id'=>$id]);
    $tx = $t->fetch();
    if (!$tx) throw new Exception('Transaction not found');
    if ($tx['status'] !== 'pending' || $tx['kind'] !== 'debit') throw new Exception('Not approvable');

    // Sender (lock)
    $s = $pdo->prepare("SELECT id,balance_cents,account_number FROM users WHERE id=:id FOR UPDATE");
    $s->execute([':id'=>$tx['user_id']]);
    $sender = $s->fetch();
    if (!$sender) throw new Exception('Sender missing');

    // Recipient (lock)
    $r = $pdo->prepare("SELECT id,balance_cents,account_number FROM users WHERE account_number=:a FOR UPDATE");
    $r->execute([':a'=>$tx['counterparty_acct']]);
    $rcv = $r->fetch();
    if (!$rcv) throw new Exception('Recipient missing');
    if ($rcv['id'] == $sender['id']) throw new Exception('Self transfer');

    $amt = (int)$tx['amount_cents'];
    if ($sender['balance_cents'] < $amt) throw new Exception('Insufficient funds');

    // Post money
    $new_s = $sender['balance_cents'] - $amt;
    $pdo->prepare("UPDATE users SET balance_cents=:b WHERE id=:id")
        ->execute([':b'=>$new_s, ':id'=>$sender['id']]);

    $new_r = $rcv['balance_cents'] + $amt;
    $pdo->prepare("UPDATE users SET balance_cents=:b WHERE id=:id")
        ->execute([':b'=>$new_r, ':id'=>$rcv['id']]);

    // Update original debit row → posted
    $upd = $pdo->prepare("
      UPDATE transactions
      SET status='posted', approved_at=NOW(), approved_by=:aid, balance_after_cents=:bal
      WHERE id=:id
    ");
    $upd->execute([':aid'=>(int)$_SESSION['uid'], ':bal'=>$new_s, ':id'=>$tx['id']]);

    // Insert recipient credit row (posted)
    $ins = $pdo->prepare("
      INSERT INTO transactions
        (user_id, kind, amount_cents, balance_after_cents, reference, note, counterparty_acct, status, approved_at, approved_by)
      VALUES
        (:uid,'credit',:amt,:bal,:ref,:note,:cp,'posted',NOW(),:aid)
    ");
    $ins->execute([
      ':uid'=>$rcv['id'], ':amt'=>$amt, ':bal'=>$new_r,
      ':ref'=>$tx['reference'], ':note'=>$tx['note'],
      ':cp'=>$sender['account_number'], ':aid'=>(int)$_SESSION['uid']
    ]);

    $pdo->commit();

    // Optional admin -> user emails
    if (function_exists('send_mail_html')) {
      @send_mail_html('admin@example.com', 'Transfer approved', '<p>Reference: '.$tx['reference'].'</p>');
    }

    header('Location: approvals.php'); exit;
  }

  header('Location: approvals.php'); exit;

} catch (Throwable $e) {
  if ($pdo->inTransaction()) $pdo->rollBack();
  http_response_code(400);
  echo 'Approval error: '.sanitize($e->getMessage());
}
