using Microsoft.AspNetCore.SignalR;
using ColaFlow.Modules.ProjectManagement.Application.Services;

namespace ColaFlow.API.Hubs;

/// <summary>
/// Project real-time collaboration Hub
/// </summary>
public class ProjectHub : BaseHub
{
    private readonly IProjectPermissionService _permissionService;

    public ProjectHub(IProjectPermissionService permissionService)
    {
        _permissionService = permissionService;
    }

    /// <summary>
    /// Join project room (to receive project-level updates)
    /// </summary>
    public async Task JoinProject(Guid projectId)
    {
        var tenantId = GetCurrentTenantId();
        var userId = GetCurrentUserId();

        // Validate user has permission to access this project
        var hasPermission = await _permissionService.IsUserProjectMemberAsync(
            userId, projectId, Context.ConnectionAborted);

        if (!hasPermission)
        {
            throw new HubException("You do not have permission to access this project");
        }

        var groupName = GetProjectGroupName(projectId);
        await Groups.AddToGroupAsync(Context.ConnectionId, groupName);

        Console.WriteLine($"User {userId} joined project {projectId}");

        // Notify other users that a new member joined
        await Clients.OthersInGroup(groupName).SendAsync("UserJoinedProject", new
        {
            UserId = userId,
            ProjectId = projectId,
            JoinedAt = DateTime.UtcNow
        });
    }

    /// <summary>
    /// Leave project room
    /// </summary>
    public async Task LeaveProject(Guid projectId)
    {
        var userId = GetCurrentUserId();

        // Validate user has permission to access this project (for consistency)
        var hasPermission = await _permissionService.IsUserProjectMemberAsync(
            userId, projectId, Context.ConnectionAborted);

        if (!hasPermission)
        {
            throw new HubException("You do not have permission to access this project");
        }

        var groupName = GetProjectGroupName(projectId);

        await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);

        // Notify other users that a member left
        await Clients.OthersInGroup(groupName).SendAsync("UserLeftProject", new
        {
            UserId = userId,
            ProjectId = projectId,
            LeftAt = DateTime.UtcNow
        });
    }

    /// <summary>
    /// Send typing indicator (when editing an issue)
    /// </summary>
    public async Task SendTypingIndicator(Guid projectId, Guid issueId, bool isTyping)
    {
        var userId = GetCurrentUserId();
        var groupName = GetProjectGroupName(projectId);

        await Clients.OthersInGroup(groupName).SendAsync("TypingIndicator", new
        {
            UserId = userId,
            IssueId = issueId,
            IsTyping = isTyping
        });
    }

    private string GetProjectGroupName(Guid projectId)
    {
        return $"project-{projectId}";
    }
}
