// EN: Connection manager for POS hub - tracks connected users per shop.
// VI: Connection manager cho POS hub - theo dõi users kết nối theo shop.

using System.Collections.Concurrent;

namespace OrderService.API.Hubs;

/// <summary>
/// EN: Thread-safe connection manager for POS/KDS hub connections.
/// VI: Connection manager thread-safe cho POS/KDS hub connections.
/// </summary>
public class PosConnectionManager
{
    // EN: Maps ConnectionId -> ShopId for quick lookup on disconnect
    // VI: Maps ConnectionId -> ShopId để tra cứu nhanh khi disconnect
    private readonly ConcurrentDictionary<string, Guid> _connectionToShop = new();

    // EN: Maps ShopId -> Set of ConnectionIds for shop-level queries
    // VI: Maps ShopId -> Set ConnectionIds cho truy vấn cấp shop
    private readonly ConcurrentDictionary<Guid, ConcurrentDictionary<string, byte>> _shopConnections = new();

    /// <summary>
    /// EN: Register a connection for a shop.
    /// VI: Đăng ký kết nối cho shop.
    /// </summary>
    public void AddConnection(string connectionId, Guid shopId)
    {
        _connectionToShop[connectionId] = shopId;

        var connections = _shopConnections.GetOrAdd(shopId, _ => new ConcurrentDictionary<string, byte>());
        connections[connectionId] = 0;
    }

    /// <summary>
    /// EN: Remove a connection and return the associated shop ID.
    /// VI: Xóa kết nối và trả về shop ID liên kết.
    /// </summary>
    public Guid? RemoveConnection(string connectionId)
    {
        if (!_connectionToShop.TryRemove(connectionId, out var shopId))
        {
            return null;
        }

        if (_shopConnections.TryGetValue(shopId, out var connections))
        {
            connections.TryRemove(connectionId, out _);

            // EN: Clean up empty shop entries / VI: Dọn dẹp các shop không còn kết nối
            if (connections.IsEmpty)
            {
                _shopConnections.TryRemove(shopId, out _);
            }
        }

        return shopId;
    }

    /// <summary>
    /// EN: Get all connection IDs for a specific shop.
    /// VI: Lấy tất cả connection IDs cho shop cụ thể.
    /// </summary>
    public IReadOnlyCollection<string> GetShopConnections(Guid shopId)
    {
        if (_shopConnections.TryGetValue(shopId, out var connections))
        {
            return connections.Keys.ToList().AsReadOnly();
        }

        return Array.Empty<string>();
    }

    /// <summary>
    /// EN: Get the number of active connections for a shop.
    /// VI: Lấy số lượng kết nối active cho shop.
    /// </summary>
    public int GetShopConnectionCount(Guid shopId)
    {
        if (_shopConnections.TryGetValue(shopId, out var connections))
        {
            return connections.Count;
        }

        return 0;
    }

    /// <summary>
    /// EN: Get total number of active connections.
    /// VI: Lấy tổng số kết nối active.
    /// </summary>
    public int TotalConnections => _connectionToShop.Count;
}
