<?php
/**
 * Rate Limit Trait
 *
 * Provides rate limiting functionality for frontend operations.
 *
 * @package Jeremias\WcLicensedProduct\Common
 */

declare(strict_types=1);

namespace Jeremias\WcLicensedProduct\Common;

/**
 * Trait for implementing rate limiting on user actions
 *
 * Uses WordPress transients for storage. Rate limits are per-user when logged in,
 * or per-IP when not logged in.
 */
trait RateLimitTrait
{
    /**
     * Check rate limit for a user action
     *
     * @param string $action Action identifier (e.g., 'transfer', 'download')
     * @param int $limit Maximum attempts per window
     * @param int $window Time window in seconds
     * @return bool True if within limit, false if exceeded
     */
    protected function checkUserRateLimit(string $action, int $limit, int $window): bool
    {
        $userId = get_current_user_id();
        $key = $userId > 0
            ? (string) $userId
            : 'ip_' . md5($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0');

        $transientKey = 'wclp_rate_' . $action . '_' . $key;
        $data = get_transient($transientKey);

        if ($data === false) {
            // First request, start counting
            set_transient($transientKey, ['count' => 1, 'start' => time()], $window);
            return true;
        }

        $count = (int) ($data['count'] ?? 0);
        $start = (int) ($data['start'] ?? time());

        // Check if window has expired
        if (time() - $start >= $window) {
            // Reset counter
            set_transient($transientKey, ['count' => 1, 'start' => time()], $window);
            return true;
        }

        // Check if limit exceeded
        if ($count >= $limit) {
            return false;
        }

        // Increment counter
        set_transient($transientKey, ['count' => $count + 1, 'start' => $start], $window);
        return true;
    }

    /**
     * Get remaining time until rate limit resets
     *
     * @param string $action Action identifier
     * @param int $window Time window in seconds (must match the one used in checkUserRateLimit)
     * @return int Seconds until rate limit resets, or 0 if not rate limited
     */
    protected function getRateLimitRetryAfter(string $action, int $window): int
    {
        $userId = get_current_user_id();
        $key = $userId > 0
            ? (string) $userId
            : 'ip_' . md5($_SERVER['REMOTE_ADDR'] ?? '0.0.0.0');

        $transientKey = 'wclp_rate_' . $action . '_' . $key;
        $data = get_transient($transientKey);

        if ($data === false) {
            return 0;
        }

        $start = (int) ($data['start'] ?? time());

        return max(0, $window - (time() - $start));
    }
}
