<?php
// ============================================================
// core/Auth/RateLimiter.php
// Sliding Window Rate Limiting باستخدام Redis
// ============================================================

class RateLimiter
{
    private ?Redis $redis;

    // حدود مختلفة لكل نوع endpoint
    private const LIMITS = [
        'login'      => ['requests' => 5,   'window' => 60],   // 5 محاولات / دقيقة
        'otp'        => ['requests' => 3,   'window' => 300],  // 3 محاولات / 5 دقائق
        'register'   => ['requests' => 3,   'window' => 3600], // 3 محاولات / ساعة
        'api'        => ['requests' => 120, 'window' => 60],   // 120 طلب / دقيقة
        'ride'       => ['requests' => 30,  'window' => 60],   // 30 طلب / دقيقة
        'upload'     => ['requests' => 10,  'window' => 300],  // 10 رفع / 5 دقائق
    ];

    public function __construct(?Redis $redis)
    {
        $this->redis = $redis;
    }

    // ── فحص الحد ─────────────────────────────────────────────
    // $identifier: IP:userId أو IP فقط
    // $type: login | otp | api | ride | upload
    public function check(string $identifier, string $type = 'api'): bool
    {
        if (!$this->redis) {
            return true; // بدون Redis نمرر (fallback)
        }

        $limit  = self::LIMITS[$type] ?? self::LIMITS['api'];
        $window = $limit['window'];
        $max    = $limit['requests'];

        $key     = "rate:{$type}:{$identifier}";
        $current = $this->redis->incr($key);

        if ($current === 1) {
            $this->redis->expire($key, $window);
        }

        return $current <= $max;
    }

    // ── تطبيق الحد وإيقاف الطلب إن تجاوز ─────────────────────
    public function enforce(string $identifier, string $type = 'api'): void
    {
        if (!$this->check($identifier, $type)) {
            $limit  = self::LIMITS[$type] ?? self::LIMITS['api'];
            $window = $limit['window'];

            error_log("[RATE_LIMIT] Blocked: $identifier | type: $type");

            http_response_code(429);
            header("Retry-After: $window");
            echo json_encode([
                'error'       => 'Too many requests. Please slow down.',
                'retry_after' => $window,
            ]);
            exit;
        }
    }

    // ── بناء معرّف المستخدم ────────────────────────────────────
    public static function identifier(?string $userId = null): string
    {
        $ip = $_SERVER['REMOTE_ADDR'] ?? 'unknown';
        return $userId ? "{$ip}:{$userId}" : $ip;
    }

    // ── إعادة تعيين عداد (مثلاً بعد تسجيل دخول ناجح) ───────────
    public function reset(string $identifier, string $type = 'login'): void
    {
        if ($this->redis) {
            $this->redis->del("rate:{$type}:{$identifier}");
        }
    }
}
