<?php

declare(strict_types=1);

namespace App\Models;

class UserSession extends BaseModel
{
    protected string $table = 'sessions';
    protected string $primaryKey = 'id';

    public function createSession(int $userId, string $token, string $ipAddress, string $userAgent, int $expiresIn): int
    {
        $this->execute(
            "INSERT INTO {$this->table} (user_id, token, ip_address, user_agent, expires_at)
             VALUES (:user_id, :token, :ip_address, :user_agent, DATE_ADD(NOW(), INTERVAL :seconds SECOND))",
            [
                'user_id' => $userId,
                'token' => $token,
                'ip_address' => $ipAddress,
                'user_agent' => $userAgent,
                'seconds' => $expiresIn,
            ]
        );

        return (int) $this->db->lastInsertId();
    }

    public function findByToken(string $token): ?array
    {
        return $this->queryOne(
            "SELECT * FROM {$this->table} WHERE token = :token AND expires_at > NOW() LIMIT 1",
            ['token' => $token]
        );
    }

    public function invalidateToken(string $token): bool
    {
        return $this->execute(
            "DELETE FROM {$this->table} WHERE token = :token",
            ['token' => $token]
        );
    }

    public function invalidateAllUserTokens(int $userId): void
    {
        $this->execute(
            "DELETE FROM {$this->table} WHERE user_id = :user_id",
            ['user_id' => $userId]
        );
    }

    public function cleanExpired(): void
    {
        $this->execute("DELETE FROM {$this->table} WHERE expires_at < NOW()");
    }

    public function countAttempts(string $ipAddress, int $windowSeconds = 300): int
    {
        $windowSeconds = max(1, $windowSeconds);
        $result = $this->queryOne(
            "SELECT COUNT(*) as cnt FROM {$this->table} WHERE ip_address = :ip AND created_at > DATE_SUB(NOW(), INTERVAL {$windowSeconds} SECOND)",
            ['ip' => $ipAddress]
        );
        return (int) ($result['cnt'] ?? 0);
    }
}
