<?php
/**
 * TamRank Rate Limiter
 *
 * Transient-based per-user rate limiter for the TamRank REST API.
 * Tracks request counts within a 60-second sliding window using
 * WordPress transients as the backing store.
 *
 * Non-atomic read+increment is acceptable for soft quota enforcement
 * on low-concurrency admin API.
 *
 * @package TamRank
 * @since   8.0.0
 */

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Class TamRank_Rate_Limiter
 *
 * Provides transient-based per-user rate limiting with a
 * caller-supplied per-minute limit.
 */
if ( class_exists( 'TamRank_Rate_Limiter' ) ) {
    return;
}

class TamRank_Rate_Limiter {

    /**
     * Rate limit window in seconds.
     */
    const WINDOW_SECONDS = 60;

    /**
     * Check and increment the rate limit counter for a user.
     *
     * Reads the current counter from a transient, checks against the limit,
     * and increments if allowed. Returns an array describing the current
     * rate limit state.
     *
     * @param int    $user_id The WordPress user ID.
     * @param string $type    Request type: 'read' or 'write'.
     * @param int    $limit   Maximum allowed requests in the window.
     * @return array {
     *     Rate limit state.
     *
     *     @type bool $allowed    Whether the request is allowed.
     *     @type int  $limit      The configured limit.
     *     @type int  $remaining  Remaining requests in current window.
     *     @type int  $reset_at   Unix timestamp when the window resets.
     * }
     */
    public function check( $user_id, $type, $limit ) {
        $key    = $this->build_key( $user_id, $type );
        $stored = get_transient( $key );

        if ( false === $stored || ! is_array( $stored ) ) {
            $stored = [
                'count'        => 0,
                'window_start' => time(),
            ];
        }

        $reset_at = $stored['window_start'] + self::WINDOW_SECONDS;

        if ( $stored['count'] >= $limit ) {
            return [
                'allowed'   => false,
                'limit'     => $limit,
                'remaining' => 0,
                'reset_at'  => $reset_at,
            ];
        }

        $stored['count']++;
        $ttl = max( 1, $reset_at - time() );
        set_transient( $key, $stored, $ttl );

        return [
            'allowed'   => true,
            'limit'     => $limit,
            'remaining' => max( 0, $limit - $stored['count'] ),
            'reset_at'  => $reset_at,
        ];
    }

    /**
     * Build the transient key for a user and request type.
     *
     * @param int    $user_id The WordPress user ID.
     * @param string $type    Request type: 'read' or 'write'.
     * @return string Transient key, e.g. 'tamrank_rl_read_42'.
     */
    private function build_key( $user_id, $type ) {
        return sprintf( 'tamrank_rl_%s_%d', $type, $user_id );
    }
}
