<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class TwoFactorSession extends Model
{
    use HasFactory;

    protected $fillable = [
        'authenticatable_id',
        'authenticatable_type',
        'session_token',
        'verified',
        'expires_at',
        'ip_address',
        'user_agent',
    ];

    protected function casts(): array
    {
        return [
            'verified' => 'boolean',
            'expires_at' => 'datetime',
        ];
    }

    /**
     * Get the parent authenticatable model (User or PortalUser).
     */
    public function authenticatable()
    {
        return $this->morphTo();
    }

    /**
     * Generate a unique session token.
     */
    public static function generateToken(): string
    {
        return Str::random(64);
    }

    /**
     * Check if the session has expired.
     */
    public function isExpired(): bool
    {
        return $this->expires_at->isPast();
    }

    /**
     * Check if the session is verified.
     */
    public function isVerified(): bool
    {
        return $this->verified;
    }

    /**
     * Check if the session is valid (not expired and potentially usable).
     */
    public function isValid(): bool
    {
        return ! $this->isExpired();
    }

    /**
     * Mark the session as verified.
     */
    public function markAsVerified(): void
    {
        $this->verified = true;
        $this->save();
    }

    /**
     * Scope to get only valid sessions.
     */
    public function scopeValid($query)
    {
        return $query->where('expires_at', '>', now());
    }

    /**
     * Scope to get verified sessions.
     */
    public function scopeVerified($query)
    {
        return $query->where('verified', true);
    }

    /**
     * Scope to get sessions for a specific authenticatable.
     */
    public function scopeForAuthenticatable($query, $authenticatable)
    {
        return $query->where('authenticatable_type', get_class($authenticatable))
            ->where('authenticatable_id', $authenticatable->id);
    }
}
