using Microsoft.AspNetCore.SignalR;

namespace MiningService.API.Hubs;

/// <summary>
/// EN: SignalR Hub for real-time mining updates.
/// VI: SignalR Hub cho cập nhật đào thời gian thực.
/// </summary>
public class MiningHub : Hub
{
    private readonly ILogger<MiningHub> _logger;

    public MiningHub(ILogger<MiningHub> logger)
    {
        _logger = logger;
    }

    /// <summary>
    /// EN: Join miner's personal update group.
    /// VI: Tham gia nhóm cập nhật cá nhân của thợ đào.
    /// </summary>
    public async Task JoinMinerGroup(Guid minerId)
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, $"miner:{minerId}");
        _logger.LogInformation("Client {ConnectionId} joined miner group {MinerId}", 
            Context.ConnectionId, minerId);
    }

    /// <summary>
    /// EN: Leave miner's personal update group.
    /// VI: Rời nhóm cập nhật cá nhân của thợ đào.
    /// </summary>
    public async Task LeaveMinerGroup(Guid minerId)
    {
        await Groups.RemoveFromGroupAsync(Context.ConnectionId, $"miner:{minerId}");
        _logger.LogInformation("Client {ConnectionId} left miner group {MinerId}", 
            Context.ConnectionId, minerId);
    }

    /// <summary>
    /// EN: Join leaderboard updates group.
    /// VI: Tham gia nhóm cập nhật bảng xếp hạng.
    /// </summary>
    public async Task JoinLeaderboardGroup()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, "leaderboard");
    }

    public override async Task OnConnectedAsync()
    {
        _logger.LogInformation("Client connected: {ConnectionId}", Context.ConnectionId);
        await base.OnConnectedAsync();
    }

    public override async Task OnDisconnectedAsync(Exception? exception)
    {
        _logger.LogInformation("Client disconnected: {ConnectionId}", Context.ConnectionId);
        await base.OnDisconnectedAsync(exception);
    }
}

/// <summary>
/// EN: Service to send mining updates to clients.
/// VI: Service gửi cập nhật đào đến clients.
/// </summary>
public interface IMiningHubService
{
    Task SendPointsUpdated(Guid minerId, decimal earnedPoints, decimal totalPoints, int streakDays);
    Task SendSessionStarted(Guid minerId, DateTime endTime, decimal hourlyRate);
    Task SendStreakMilestone(Guid minerId, int streakDays, decimal bonusPoints);
}

public class MiningHubService : IMiningHubService
{
    private readonly IHubContext<MiningHub> _hubContext;

    public MiningHubService(IHubContext<MiningHub> hubContext)
    {
        _hubContext = hubContext;
    }

    public async Task SendPointsUpdated(Guid minerId, decimal earnedPoints, decimal totalPoints, int streakDays)
    {
        await _hubContext.Clients.Group($"miner:{minerId}")
            .SendAsync("PointsUpdated", new { earnedPoints, totalPoints, streakDays });
    }

    public async Task SendSessionStarted(Guid minerId, DateTime endTime, decimal hourlyRate)
    {
        await _hubContext.Clients.Group($"miner:{minerId}")
            .SendAsync("SessionStarted", new { endTime, hourlyRate });
    }

    public async Task SendStreakMilestone(Guid minerId, int streakDays, decimal bonusPoints)
    {
        await _hubContext.Clients.Group($"miner:{minerId}")
            .SendAsync("StreakMilestone", new { streakDays, bonusPoints });
    }
}
