<?php
/**
 * Paid-submission credit helpers.
 *
 * Every grant and use is a row in sm_credits. The current balance for
 * a poet is SUM(amount). All functions are idempotent in spirit:
 * grant_credits() always appends, never updates; the ledger is the
 * source of truth.
 */
declare(strict_types=1);

/**
 * Per-edition submission limit (issues and contests alike). Shared across
 * new-submission.php (enforcement) and the editor notes so the numbers
 * never disagree. Change it here to raise or lower the limit site-wide.
 */
if (!defined('SUB_LIMIT_REGULAR')) {
    define('SUB_LIMIT_REGULAR', 3);
}

/**
 * Current credit balance for a poet. Returns 0 if the table doesn't
 * exist yet (i.e. v6 migration not run).
 */
function credits_balance(PDO $pdo, int $poet_id): int
{
    try {
        $stmt = $pdo->prepare("SELECT COALESCE(SUM(amount), 0) FROM sm_credits WHERE poet_id = :id");
        $stmt->bindValue(':id', $poet_id, PDO::PARAM_INT);
        $stmt->execute();
        return (int)$stmt->fetchColumn();
    } catch (Throwable $e) {
        error_log('credits_balance: ' . $e->getMessage());
        return 0;
    }
}

/**
 * Grant or deduct credits. Pass a positive integer to grant, negative
 * to use. Returns true on success.
 */
function credits_grant(PDO $pdo, int $poet_id, int $amount, string $reason, ?int $editor_id = null, ?int $submission_id = null): bool
{
    if ($amount === 0) return false;
    try {
        $stmt = $pdo->prepare("INSERT INTO sm_credits
            (poet_id, amount, reason, granted_by_editor_id, used_for_submission_id, created_at)
            VALUES (:poet_id, :amount, :reason, :editor_id, :sub_id, NOW())");
        $stmt->bindValue(':poet_id',    $poet_id, PDO::PARAM_INT);
        $stmt->bindValue(':amount',     $amount,  PDO::PARAM_INT);
        $stmt->bindValue(':reason',     $reason,  PDO::PARAM_STR);
        $stmt->bindValue(':editor_id',  $editor_id,    $editor_id === null ? PDO::PARAM_NULL : PDO::PARAM_INT);
        $stmt->bindValue(':sub_id',     $submission_id, $submission_id === null ? PDO::PARAM_NULL : PDO::PARAM_INT);
        $stmt->execute();
        return true;
    } catch (Throwable $e) {
        error_log('credits_grant: ' . $e->getMessage());
        return false;
    }
}

/**
 * Recent ledger entries for a single poet (most recent first).
 */
function credits_history(PDO $pdo, int $poet_id, int $limit = 25): array
{
    try {
        $stmt = $pdo->prepare("SELECT id, amount, reason, granted_by_editor_id, used_for_submission_id, created_at
                               FROM sm_credits WHERE poet_id = :id
                               ORDER BY id DESC LIMIT :lim");
        $stmt->bindValue(':id',  $poet_id, PDO::PARAM_INT);
        $stmt->bindValue(':lim', $limit,   PDO::PARAM_INT);
        $stmt->execute();
        return $stmt->fetchAll(PDO::FETCH_ASSOC);
    } catch (Throwable $e) {
        error_log('credits_history: ' . $e->getMessage());
        return [];
    }
}
