<?php
require_once __DIR__ . '/functions.php';
require_once __DIR__ . '/security.php';

/* =========================================
   USER ACCOUNTS
========================================= */
function get_user_accounts(mysqli $conn, int $userId): array
{
    $st = $conn->prepare("
        SELECT *
        FROM accounts
        WHERE user_id = ?
        AND account_type IN ('savings','current')
        ORDER BY id ASC
    ");
    $st->bind_param("i", $userId);
    $st->execute();

    $res = $st->get_result();
    return $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
}


/* =========================================
   ACCOUNT BALANCE
========================================= */
function account_balance(mysqli $conn, int $accountId): float
{
    $st = $conn->prepare("
        SELECT COALESCE(
            SUM(CASE WHEN direction='credit' THEN amount ELSE -amount END),
            0
        ) AS balance
        FROM ledger_entries
        WHERE account_id = ?
    ");
    $st->bind_param("i", $accountId);
    $st->execute();

    $row = $st->get_result()->fetch_assoc();
    return (float)($row['balance'] ?? 0);
}


/* =========================================
   RECENT ENTRIES
========================================= */
function recent_entries(mysqli $conn, int $accountId, int $limit = 10): array
{
    $st = $conn->prepare("
        SELECT 
            t.ref,
            t.type,
            t.status,
            t.narration,
            t.created_at,
            e.direction,
            e.amount,
            e.currency,
            e.balance_after
        FROM ledger_entries e
        JOIN ledger_txn t ON t.id = e.txn_id
        WHERE e.account_id = ?
        ORDER BY e.id DESC
        LIMIT ?
    ");
    $st->bind_param("ii", $accountId, $limit);
    $st->execute();

    $res = $st->get_result();
    return $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
}


/* =========================================
   AUDIT LOG
========================================= */


/* =========================================
   ENSURE CRYPTO WALLETS
========================================= */
function ensure_crypto_wallets(mysqli $conn, int $userId): void
{
    $assets = $conn->query("
        SELECT id
        FROM crypto_assets
        WHERE enabled = 1
    ");

    $ins = $conn->prepare("
        INSERT IGNORE INTO crypto_wallets (user_id, asset_id, balance)
        VALUES (?, ?, 0)
    ");

    while ($a = $assets->fetch_assoc()) {
        $assetId = (int)$a['id'];
        $ins->bind_param("ii", $userId, $assetId);
        $ins->execute();
    }
}


/* =========================================
   VIRTUAL CARDS
========================================= */
function get_user_virtual_cards(mysqli $conn, int $userId): array
{
    $st = $conn->prepare("
        SELECT *
        FROM virtual_cards
        WHERE user_id = ?
        ORDER BY id DESC
    ");
    $st->bind_param("i", $userId);
    $st->execute();

    $res = $st->get_result();
    return $res ? $res->fetch_all(MYSQLI_ASSOC) : [];
}


/* =========================================
   CARD REQUESTS
========================================= */
function user_pending_card_requests(mysqli $conn, int $userId): int
{
    $st = $conn->prepare("
        SELECT COUNT(*) AS total
        FROM card_requests
        WHERE user_id = ?
        AND status = 'pending'
    ");
    $st->bind_param("i", $userId);
    $st->execute();

    $row = $st->get_result()->fetch_assoc();
    return (int)($row['total'] ?? 0);
}


function create_card_request(
    mysqli $conn,
    int $userId,
    string $network,
    string $tier,
    ?string $note = null
): int {

    $network = in_array($network, ['visa','mastercard'], true) ? $network : 'visa';
    $tier    = in_array($tier, ['standard','premium'], true) ? $tier : 'standard';

    $st = $conn->prepare("
        INSERT INTO card_requests
        (user_id, network, tier, status, note)
        VALUES (?, ?, ?, 'pending', ?)
    ");
    $st->bind_param("isss", $userId, $network, $tier, $note);
    $st->execute();

    return (int)$conn->insert_id;
}


/* =========================================
   GENERATE VIRTUAL CARD (ADMIN)
========================================= */
function generate_virtual_card(
    mysqli $conn,
    int $userId,
    int $requestId,
    string $network,
    string $cardholderName
): int {

    // Generate demo card details
    $pan = ($network === 'visa' ? '4' : '5');
    for ($i = 0; $i < 14; $i++) {
        $pan .= random_int(0, 9);
    }
    $last4 = substr($pan, -4);

    $expMonth = random_int(1, 12);
    $expYear  = (int)date('Y') + 4;
    $cvv      = str_pad((string)random_int(0, 999), 3, '0', STR_PAD_LEFT);

    // Encrypt sensitive values
    $panEnc = encrypt_str($pan);
    $cvvEnc = encrypt_str($cvv);

    /* ===============================
       INSERT CARD
       Columns count = values count
    ================================ */
    $st = $conn->prepare("
        INSERT INTO virtual_cards
        (
          user_id,
          request_id,
          network,
          cardholder_name,
          pan_enc,
          last4,
          exp_month,
          exp_year,
          cvv_enc,
          status,
          created_at
        )
        VALUES
        (?, ?, ?, ?, ?, ?, ?, ?, ?, 'active', NOW())
    ");

    /**
     * VALUES (9 placeholders):
     * i user_id
     * i request_id
     * s network
     * s cardholder_name
     * s pan_enc
     * s last4
     * i exp_month
     * i exp_year
     * s cvv_enc
     */
    $st->bind_param(
        "iissssiis",
        $userId,
        $requestId,
        $network,
        $cardholderName,
        $panEnc,
        $last4,
        $expMonth,
        $expYear,
        $cvvEnc
    );

    $st->execute();

    return (int)$conn->insert_id;
}



// ... keep your existing banking.php code ABOVE

/**
 * Ensure the user has exactly one primary account.
 * - If none is primary, sets the oldest account (MIN(id)) as primary.
 * - If multiple are primary, keeps the oldest primary and clears the rest.
 */
function ensure_primary_account(mysqli $conn, int $userId): void {

  // Count primaries
  $st = $conn->prepare("SELECT COUNT(*) AS c FROM accounts WHERE user_id=? AND is_primary=1");
  $st->bind_param("i", $userId);
  $st->execute();
  $c = (int)($st->get_result()->fetch_assoc()['c'] ?? 0);

  // If none -> set first account
  if ($c === 0) {
    $st = $conn->prepare("SELECT id FROM accounts WHERE user_id=? ORDER BY id ASC LIMIT 1");
    $st->bind_param("i", $userId);
    $st->execute();
    $row = $st->get_result()->fetch_assoc();
    if ($row) {
      $firstId = (int)$row['id'];
      $conn->begin_transaction();
      $conn->query("UPDATE accounts SET is_primary=0 WHERE user_id=".(int)$userId);
      $st2 = $conn->prepare("UPDATE accounts SET is_primary=1 WHERE user_id=? AND id=?");
      $st2->bind_param("ii", $userId, $firstId);
      $st2->execute();
      $conn->commit();
    }
    return;
  }

  // If multiple -> keep the oldest primary only
  if ($c > 1) {
    $st = $conn->prepare("SELECT id FROM accounts WHERE user_id=? AND is_primary=1 ORDER BY id ASC LIMIT 1");
    $st->bind_param("i", $userId);
    $st->execute();
    $keep = (int)($st->get_result()->fetch_assoc()['id'] ?? 0);

    if ($keep > 0) {
      $conn->begin_transaction();
      $st2 = $conn->prepare("UPDATE accounts SET is_primary=0 WHERE user_id=? AND id<>?");
      $st2->bind_param("ii", $userId, $keep);
      $st2->execute();
      $conn->commit();
    }
  }
}

/**
 * Get the user's primary account row.
 * Auto-fixes primary if missing.
 */
function get_primary_account(mysqli $conn, int $userId): ?array {
  ensure_primary_account($conn, $userId);

  $st = $conn->prepare("SELECT * FROM accounts WHERE user_id=? AND is_primary=1 LIMIT 1");
  $st->bind_param("i", $userId);
  $st->execute();
  $row = $st->get_result()->fetch_assoc();
  return $row ?: null;
}

/**
 * Set an account as primary (and enforce only one).
 */
function set_primary_account(mysqli $conn, int $userId, int $accountId): void {
  $conn->begin_transaction();

  $st1 = $conn->prepare("UPDATE accounts SET is_primary=0 WHERE user_id=?");
  $st1->bind_param("i", $userId);
  $st1->execute();

  $st2 = $conn->prepare("UPDATE accounts SET is_primary=1 WHERE user_id=? AND id=? LIMIT 1");
  $st2->bind_param("ii", $userId, $accountId);
  $st2->execute();

  $conn->commit();
}
