<?php

declare(strict_types=1);

namespace ApiModel\Infrastructure\Persistence\Repositories;

use ApiModel\Domain\Repository\RefreshTokenRepositoryInterface;
use PDO;

final class PdoRefreshTokenRepository implements RefreshTokenRepositoryInterface
{
    public function __construct(private readonly PDO $pdo) {}

    public function insert(string $userId, string $tokenHash, string $expiresAt): void
    {
        $this->pdo->prepare(
            'INSERT INTO auth.refresh_tokens (user_id, token_hash, expires_at, revoked) VALUES (?,?,?,false)',
        )->execute([$userId, $tokenHash, $expiresAt]);
    }

    public function findValidSessionByTokenHash(string $tokenHash): ?array
    {
        $st = $this->pdo->prepare(
            'SELECT rt.id, rt.expires_at, u.id AS uid, u.name, u.email, u.language, u.is_active
             FROM auth.refresh_tokens rt JOIN auth.users u ON u.id = rt.user_id
             WHERE rt.token_hash = ? AND rt.revoked = false',
        );
        $st->execute([$tokenHash]);
        $row = $st->fetch();

        if ($row === false) {
            return null;
        }

        // Obtener los roles del usuario de forma relacional
        $rst = $this->pdo->prepare(
            'SELECT r.name_en FROM auth.roles r 
             JOIN auth.role_user ru ON ru.role_id = r.id 
             WHERE ru.user_id = ?'
        );
        $rst->execute([$row['uid']]);
        $roles = $rst->fetchAll(PDO::FETCH_COLUMN);

        $row['role'] = implode(',', $roles);
        return $row;
    }

    public function revokeByTokenId(string $tokenId): void
    {
        $this->pdo->prepare('UPDATE auth.refresh_tokens SET revoked = true WHERE id = ?')->execute([$tokenId]);
    }

    public function revokeByUserIdAndTokenHash(string $userId, string $tokenHash): void
    {
        $this->pdo->prepare(
            'UPDATE auth.refresh_tokens SET revoked = true WHERE user_id = ? AND token_hash = ? AND revoked = false',
        )->execute([$userId, $tokenHash]);
    }

    public function revokeAllForUser(string $userId): void
    {
        $this->pdo->prepare('UPDATE auth.refresh_tokens SET revoked = true WHERE user_id = ? AND revoked = false')->execute([$userId]);
    }
}
