using OmsorgCore.Application.Abstractions;

namespace OmsorgCore.Application.Services;

public class SessionAdminService : ISessionAdminService
{
    private readonly IRefreshTokenRepository _refreshTokenRepository;
    private readonly IUserRepository _userRepository;

    public SessionAdminService(IRefreshTokenRepository refreshTokenRepository, IUserRepository userRepository)
    {
        _refreshTokenRepository = refreshTokenRepository;
        _userRepository = userRepository;
    }

    public async Task<IReadOnlyList<SessionInfo>> GetActiveSessionsAsync(CancellationToken cancellationToken = default)
    {
        var tokens = await _refreshTokenRepository.GetAllActiveAsync(cancellationToken);
        return tokens
            .Select(t => new SessionInfo(t.Id, t.User.Username, t.CreatedAt, t.ExpiresAt))
            .ToList();
    }

    public async Task RevokeSessionAsync(Guid sessionId, CancellationToken cancellationToken = default)
    {
        var token = await _refreshTokenRepository.GetByIdAsync(sessionId, cancellationToken);
        if (token is null || token.RevokedAt is not null)
        {
            return;
        }

        token.RevokedAt = DateTime.UtcNow;
        token.User.SecurityStamp = Guid.NewGuid();

        await _refreshTokenRepository.SaveChangesAsync(cancellationToken);
    }

    public async Task RevokeAllSessionsAsync(CancellationToken cancellationToken = default)
    {
        var activeTokens = await _refreshTokenRepository.GetAllActiveAsync(cancellationToken);
        foreach (var token in activeTokens)
        {
            token.RevokedAt = DateTime.UtcNow;
        }

        var users = await _userRepository.GetAllAsync(cancellationToken);
        foreach (var user in users)
        {
            user.SecurityStamp = Guid.NewGuid();
        }

        await _userRepository.SaveChangesAsync(cancellationToken);
    }
}
