using Application.Abstractions.Cache;
using Application.Abstractions.Chat;
using StackExchange.Redis;
using System.Text.Json;

namespace Infrastructure.Chat
{
    public class RedisChatConnectionTracker(IConnectionMultiplexer redis) : IChatConnectionTracker
    {
        private readonly IDatabase _db = redis.GetDatabase();

        private static readonly JsonSerializerOptions _jsonOptions = new()
        {
            PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
            WriteIndented = false
        };

        public async Task AddAsync(ConnectedUser user)
        {
            var json = JsonSerializer.Serialize(user, _jsonOptions);
            await _db.HashSetAsync(CacheKeys.ChatConnections, user.ConnectionId, json);
        }

        public async Task RemoveAsync(string connectionId)
        {
            await _db.HashDeleteAsync(CacheKeys.ChatConnections, connectionId);
        }

        public async Task<IReadOnlyList<ConnectedUser>> GetAllAsync()
        {
            var entries = await _db.HashGetAllAsync(CacheKeys.ChatConnections);
            if (entries.Length <= 0)
            {
                return [];
            }

            var list = new List<ConnectedUser>(entries.Length);
            foreach (var entry in entries)
            {
                if (!entry.Value.IsNullOrEmpty)
                {
                    var user = JsonSerializer.Deserialize<ConnectedUser>((string)entry.Value!, _jsonOptions);
                    if (user is not null)
                    {
                        list.Add(user);
                    }
                }
            }

            return list.AsReadOnly();
        }

        public async Task ClearAllAsync()
        {
            await _db.KeyDeleteAsync(CacheKeys.ChatConnections);
        }
    }
}