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

session_boot();
require_login();

/* DB */
$conn = require __DIR__ . '/../../app/config/database.php';
require_admin($conn);

$admin = current_user();

/* ===============================
   AUDIT FALLBACK (PERMANENT FIX)
================================ */
if (!function_exists('audit')) {
    function audit(mysqli $conn, int $actorId, string $action, array $meta = []): void
    {
        $stmt = $conn->prepare("
            INSERT INTO audit_logs (actor_id, action, meta, ip)
            VALUES (?, ?, ?, ?)
        ");
        $json = json_encode($meta, JSON_UNESCAPED_UNICODE);
        $ip   = $_SERVER['REMOTE_ADDR'] ?? '0.0.0.0';
        $stmt->bind_param("isss", $actorId, $action, $json, $ip);
        $stmt->execute();
    }
}

/* ================= LOAD ACCOUNTS ================= */
$accounts = [];
$res = $conn->query("
  SELECT a.id, a.account_no, a.account_type, a.currency,
         u.full_name, u.email
  FROM accounts a
  JOIN users u ON u.id = a.user_id
  WHERE a.account_type IN ('savings','current')
  ORDER BY a.id DESC
  LIMIT 500
");
while ($r = $res->fetch_assoc()) {
  $accounts[] = $r;
}

/* ================= LEDGER BALANCE ================= */
function ledger_balance(mysqli $conn, int $accountId): float {
  $st = $conn->prepare("
    SELECT COALESCE(
      SUM(CASE WHEN direction='credit' THEN amount ELSE -amount END), 0
    )
    FROM ledger_entries
    WHERE account_id=?
  ");
  $st->bind_param("i", $accountId);
  $st->execute();
  return (float)($st->get_result()->fetch_row()[0] ?? 0);
}

/* ================= PROCESS FORM ================= */
if (is_post()) {
  csrf_verify();

  try {
    $accountId = (int)($_POST['account_id'] ?? 0);
    $direction = $_POST['direction'] ?? '';
    $amount    = (float)($_POST['amount'] ?? 0);
    $reason    = trim($_POST['reason'] ?? '');

    if (!$accountId) throw new Exception('Select an account');
    if (!in_array($direction, ['credit','debit'], true)) throw new Exception('Invalid type');
    if ($amount <= 0) throw new Exception('Amount must be greater than zero');
    if (strlen($reason) < 5) throw new Exception('Reason is required');

    $conn->begin_transaction();

    /* LOCK CUSTOMER ACCOUNT */
    $st = $conn->prepare("
      SELECT currency, user_id
      FROM accounts
      WHERE id=?
      FOR UPDATE
    ");
    $st->bind_param("i", $accountId);
    $st->execute();
    $acc = $st->get_result()->fetch_assoc();
    if (!$acc) throw new Exception('Account not found');

    $currency = $acc['currency'];
    $userId   = (int)$acc['user_id'];

    /* ================= CONTROL ACCOUNT ================= */
    $ctrlNo = 'BANK_CONTROL_' . $currency;

    $st = $conn->prepare("
      SELECT id FROM accounts
      WHERE account_no=?
      LIMIT 1
      FOR UPDATE
    ");
    $st->bind_param("s", $ctrlNo);
    $st->execute();
    $ctrlId = (int)($st->get_result()->fetch_row()[0] ?? 0);

    if (!$ctrlId) {
      /* MUST USE VALID USER ID (ADMIN) */
      $systemUserId = (int)$admin['id'];

      $st = $conn->prepare("
        INSERT INTO accounts
          (user_id, account_no, account_type, currency, balance, is_primary)
        VALUES
          (?, ?, 'current', ?, 0, 0)
      ");
      $st->bind_param("iss", $systemUserId, $ctrlNo, $currency);
      $st->execute();

      $ctrlId = (int)$conn->insert_id;
      if (!$ctrlId) throw new Exception('Failed to create control account');
    }

    /* CREATE TRANSACTION */
    $ref = now_ref('ABK');
    $st = $conn->prepare("
      INSERT INTO ledger_txn (ref, type, status, narration, created_by)
      VALUES (?, 'admin_adjust', 'posted', ?, ?)
    ");
    $st->bind_param("ssi", $ref, $reason, $admin['id']);
    $st->execute();
    $txnId = $conn->insert_id;

    /* BALANCE CHECK */
    $current = ledger_balance($conn, $accountId);
    $newBal  = $current + ($direction === 'credit' ? $amount : -$amount);
    if ($newBal < 0) throw new Exception('Insufficient balance');

    if ($direction === 'credit') {
      /* CREDIT CUSTOMER */
      $st = $conn->prepare("
        INSERT INTO ledger_entries
          (txn_id, account_id, direction, amount, currency, balance_after)
        VALUES (?, ?, 'credit', ?, ?, ?)
      ");
      $st->bind_param("iidss", $txnId, $accountId, $amount, $currency, $newBal);
      $st->execute();

      /* DEBIT CONTROL */
      $st = $conn->prepare("
        INSERT INTO ledger_entries
          (txn_id, account_id, direction, amount, currency)
        VALUES (?, ?, 'debit', ?, ?)
      ");
      $st->bind_param("iids", $txnId, $ctrlId, $amount, $currency);
      $st->execute();
    } else {
      /* DEBIT CUSTOMER */
      $st = $conn->prepare("
        INSERT INTO ledger_entries
          (txn_id, account_id, direction, amount, currency, balance_after)
        VALUES (?, ?, 'debit', ?, ?, ?)
      ");
      $st->bind_param("iidss", $txnId, $accountId, $amount, $currency, $newBal);
      $st->execute();

      /* CREDIT CONTROL */
      $st = $conn->prepare("
        INSERT INTO ledger_entries
          (txn_id, account_id, direction, amount, currency)
        VALUES (?, ?, 'credit', ?, ?)
      ");
      $st->bind_param("iids", $txnId, $ctrlId, $amount, $currency);
      $st->execute();
    }

    /* AUDIT */
    audit($conn, (int)$admin['id'], 'ADMIN_ADJUST', [
      'ref'       => $ref,
      'account'   => $accountId,
      'direction' => $direction,
      'amount'    => $amount,
      'currency'  => $currency
    ]);

    /* NOTIFY USER */
    $msg = ucfirst($direction) . " of {$currency} " . money($amount) . " (Ref: {$ref})";
    $st = $conn->prepare("
      INSERT INTO notifications (user_id, title, message)
      VALUES (?, 'Account Adjustment', ?)
    ");
    $st->bind_param("is", $userId, $msg);
    $st->execute();

    $conn->commit();
    flash('msg', "Balance updated successfully. Ref: {$ref}");
    redirect('adjust_balance.php');

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

/* ================= VIEW ================= */
$title = 'Adjust Balance — Astrabank';
include __DIR__ . '/../../views/partials/head.php';
include __DIR__ . '/../../views/partials/admin_sidebar.php';
?>

<div class="container py-4">
  <div class="d-flex justify-content-between align-items-center mb-3">
    <h3 class="fw-bold mb-0">Adjust Account Balance</h3>
    <a class="btn btn-outline-secondary" href="dashboard.php">Back</a>
  </div>

  <?php if ($m = flash('msg')): ?><div class="alert alert-success"><?= e($m) ?></div><?php endif; ?>
  <?php if ($e = flash('err')): ?><div class="alert alert-danger"><?= e($e) ?></div><?php endif; ?>

  <div class="card ab-card p-4">
    <form method="post">
      <?= csrf_field() ?>
      <div class="row g-3">
        <div class="col-md-6">
          <label class="form-label">Account</label>
          <select name="account_id" class="form-select" required>
            <option value="">-- Select --</option>
            <?php foreach ($accounts as $a): ?>
              <option value="<?= (int)$a['id'] ?>">
                <?= e($a['full_name']) ?> • <?= e($a['account_no']) ?> (<?= e($a['currency']) ?>)
              </option>
            <?php endforeach; ?>
          </select>
        </div>
        <div class="col-md-3">
          <label class="form-label">Type</label>
          <select name="direction" class="form-select">
            <option value="credit">Credit</option>
            <option value="debit">Debit</option>
          </select>
        </div>
        <div class="col-md-3">
          <label class="form-label">Amount</label>
          <input type="number" step="0.01" name="amount" class="form-control" required>
        </div>
        <div class="col-12">
          <label class="form-label">Reason</label>
          <input type="text" name="reason" class="form-control" required>
        </div>
        <div class="col-12">
          <button class="btn ab-btn text-white">Submit</button>
        </div>
      </div>
    </form>
  </div>
</div>

<?php include __DIR__ . '/../../views/partials/foot.php'; ?>
