<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Schema;

class RateLimitSetting extends Model
{
    protected $fillable = [
        'endpoint',
        'max_attempts',
        'decay_seconds',
        'is_enabled',
        'description',
    ];

    protected $casts = [
        'max_attempts' => 'integer',
        'decay_seconds' => 'integer',
        'is_enabled' => 'boolean',
    ];

    private const CACHE_KEY = 'rate_limit_settings_all';
    private const CACHE_TTL = 300; // 5 dakika

    public function scopeGlobal($query)
    {
        return $query->whereNull('endpoint');
    }

    /**
     * Belirli bir endpoint icin gecerli rate limit ayarini dondurur.
     * Once endpoint ozel ayar aranir, yoksa global ayar dondurulur.
     * Sonuc 5 dakika cache'lenir.
     */
    public static function getConfig(string $method, string $path): ?self
    {
        $settings = self::getAllCached();

        if ($settings === null) {
            return null;
        }

        $requestKey = strtoupper($method) . ' ' . $path;

        // 1) Tam eslesen endpoint ozel ayar
        $exact = $settings->firstWhere('endpoint', $requestKey);
        if ($exact) {
            return $exact;
        }

        // 2) Wildcard eslestirme (orn: "POST /api/chat/*/messages")
        foreach ($settings->whereNotNull('endpoint') as $setting) {
            $pattern = preg_quote($setting->endpoint, '#');
            $pattern = str_replace('\*', '[^/]+', $pattern);

            if (preg_match('#^' . $pattern . '$#', $requestKey)) {
                return $setting;
            }
        }

        // 3) Global ayar (endpoint = null)
        return $settings->firstWhere('endpoint', null);
    }

    /**
     * Tum ayarlari cache'den okur, yoksa DB'den cekip cache'e yazar.
     */
    public static function getAllCached()
    {
        try {
            if (!Schema::hasTable('rate_limit_settings')) {
                return null;
            }
        } catch (\Throwable) {
            return null;
        }

        return Cache::remember(self::CACHE_KEY, self::CACHE_TTL, function () {
            return self::all();
        });
    }

    /**
     * Admin panelden ayar degistiginde cache'i temizler.
     */
    public static function clearCache(): void
    {
        Cache::forget(self::CACHE_KEY);
    }
}
