<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Carbon\Carbon;

class LoginAttempt extends Model
{
    protected $fillable = [
        'email',
        'ip_address',
        'user_agent',
        'successful',
        'locked_until',
    ];

    protected $casts = [
        'successful' => 'boolean',
        'locked_until' => 'datetime',
        'created_at' => 'datetime',
        'updated_at' => 'datetime',
    ];

    public function isLocked(): bool
    {
        return $this->locked_until && $this->locked_until > now();
    }

    public function scopeFailed($query)
    {
        return $query->where('successful', false);
    }

    public function scopeSuccessful($query)
    {
        return $query->where('successful', true);
    }

    public function scopeForEmail($query, $email)
    {
        return $query->where('email', $email);
    }

    public function scopeRecent($query, $minutes = 60)
    {
        return $query->where('created_at', '>=', now()->subMinutes($minutes));
    }

    public function scopeLocked($query)
    {
        return $query->whereNotNull('locked_until')
                    ->where('locked_until', '>', now());
    }

    public static function getFailedAttemptsCount(string $email, int $minutes = 60): int
    {
        return self::forEmail($email)
                   ->failed()
                   ->recent($minutes)
                   ->count();
    }

    public static function isEmailLocked(string $email): bool
    {
        $lockedAttempt = self::forEmail($email)
                            ->locked()
                            ->first();
        
        return $lockedAttempt && $lockedAttempt->isLocked();
    }

    public static function lockEmail(string $email, int $lockMinutes = 60): void
    {
        self::create([
            'email' => $email,
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
            'successful' => false,
            'locked_until' => now()->addMinutes($lockMinutes),
        ]);
    }

    public static function unlockEmail(string $email): void
    {
        self::forEmail($email)
            ->locked()
            ->update(['locked_until' => null]);
    }
}
