<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;

class OtpRateLimit extends Model
{
    protected $fillable = [
        'ip_address',
        'phone',
        'requests_count',
        'window_start',
        'last_request_at',
        'is_verified',
    ];

    protected $casts = [
        'is_verified' => 'boolean',
        'window_start' => 'datetime',
        'last_request_at' => 'datetime',
    ];

    /**
     * Find or create a rate limit record for the given IP and phone.
     */
    public static function findOrCreate(string $ip, string $phone): self
    {
        return self::updateOrCreate(
            ['ip_address' => $ip, 'phone' => $phone],
            ['window_start' => now()]
        );
    }

    /**
     * Check if the IP+phone pair has exceeded the rate limit.
     */
    public static function isLimited(string $ip, string $phone, int $maxRequests = 3, int $windowMinutes = 60): bool
    {
        $record = self::where('ip_address', $ip)
            ->where('phone', $phone)
            ->where('window_start', '>', now()->subMinutes($windowMinutes))
            ->first();

        if (! $record) {
            return false;
        }

        return $record->requests_count >= $maxRequests;
    }

    /**
     * Increment the request counter.
     */
    public static function recordAttempt(string $ip, string $phone): void
    {
        $record = self::findOrCreate($ip, $phone);

        // Reset window if older than 1 hour
        if ($record->window_start->lt(now()->subHour())) {
            $record->update([
                'window_start' => now(),
                'requests_count' => 1,
                'is_verified' => false,
            ]);
        } else {
            $record->increment('requests_count');
            $record->update(['last_request_at' => now()]);
        }
    }

    /**
     * Reset the counter after successful verification.
     */
    public static function reset(string $ip, string $phone): void
    {
        self::where('ip_address', $ip)
            ->where('phone', $phone)
            ->update([
                'requests_count' => 0,
                'is_verified' => true,
                'window_start' => now(),
            ]);
    }

    /**
     * Get remaining attempts for an IP+phone pair.
     */
    public static function remaining(string $ip, string $phone, int $maxRequests = 3, int $windowMinutes = 60): int
    {
        $record = self::where('ip_address', $ip)
            ->where('phone', $phone)
            ->where('window_start', '>', now()->subMinutes($windowMinutes))
            ->first();

        if (! $record) {
            return $maxRequests;
        }

        $remaining = $maxRequests - $record->requests_count;

        return max(0, $remaining);
    }

    /**
     * Clean up old rate limit records.
     */
    public static function cleanup(): int
    {
        return self::where('window_start', '<', now()->subHours(2))->delete();
    }
}
