using Fitness_core_BE.AI; using Fitness_core_BE.Helpers; using Fitness_core_BE.Interfaces.Services; using Fitness_core_BE.Models; using Microsoft.AspNetCore.SignalR; using System.Net.Http.Headers; using System.Numerics; using System.Text.Json; using static System.Runtime.InteropServices.JavaScript.JSType; namespace Fitness_core_BE.Hubs { public class ChatHub : Hub { private readonly IChatService _chatService; public readonly MealPlanOrchestrator _mealPlanOrchestrator; public readonly WorkoutPlanOrchestrator _workoutPlanOrchestrator; public ChatHub(IChatService chatService, MealPlanOrchestrator mealPlanOrchestrator, WorkoutPlanOrchestrator workoutPlanOrchestrator) { _chatService = chatService; _mealPlanOrchestrator = mealPlanOrchestrator; _workoutPlanOrchestrator = workoutPlanOrchestrator; } private Guid ResolveUserId() { // Later: Context.User.Claims (JWT) return Guid.Parse("d12fb5a6-969c-4fb2-a7f8-a5bc54ed0f11"); } public async Task JoinChat(object payload) { var data = DeserializePayload.Deserialize(payload); Guid chatId = DataExtractor.GetRequiredGuid(data, "chatId"); //Guid userId = ResolveUserId(); Guid userId = DataExtractor.GetRequiredGuid(data, "userId"); if (!await _chatService.CanUserAccessChatAsync(chatId, userId)) throw new HubException("Unauthorized to join this chat"); await Groups.AddToGroupAsync( Context.ConnectionId, $"chat-{chatId}" ); var history = await _chatService.GetMessagesAsync(new { chatId = chatId, userId = userId, skip = 0, take = 30 }); await Clients.Caller.SendAsync("ReceiveHistory", history); } public async Task SendMessage(object payload) { var data = DeserializePayload.Deserialize(payload); string reason = DataExtractor.GetRequiredString(data, "reason"); Guid chatId = DataExtractor.GetRequiredGuid(data, "chatId"); Guid userId = DataExtractor.GetRequiredGuid(data, "userId"); string message = DataExtractor.GetRequiredString(data, "message"); switch (reason) { case "user": var savedMessage = await _chatService.SendMessageAsync(new { chatId = chatId, senderId = userId, message = message, type = "userMessages" }); await Clients.Group($"chat-{chatId}") .SendAsync("ReceiveMessage", savedMessage); break; case "mealPlan": await SendChatMessageAsync( chatId, userId, message, "userMealReq" ); string messageType = DataExtractor.GetRequiredString(data, "messageType"); if (messageType == "generateMealPlan") { var plan = await _mealPlanOrchestrator .GeneratePlanAsync(payload); string aiMessage = JsonSerializer.Serialize(plan); await SendChatMessageAsync( chatId, AIAgents.MealAgentId, aiMessage, "createdPlan" ); } if (messageType == "modifyMealPlan") { var updated = await _mealPlanOrchestrator .UpdatePlanAsync(payload); string aiMessage = JsonSerializer.Serialize(updated); await SendChatMessageAsync( chatId, AIAgents.MealAgentId, aiMessage, "updatedPlan" ); } break; case "workoutPlan": await SendChatMessageAsync( chatId, userId, message, "userWorkoutReq" ); string workoutMessageType = DataExtractor.GetRequiredString(data, "messageType"); if (workoutMessageType == "generateWorkoutPlan") { var plan = await _workoutPlanOrchestrator .GeneratePlanAsync(payload); string aiMessage = JsonSerializer.Serialize(plan); await SendChatMessageAsync( chatId, AIAgents.WorkoutAgentId, aiMessage, "createdPlan" ); } if (workoutMessageType == "modifyWorkoutPlan") { var updated = await _workoutPlanOrchestrator .UpdatePlanAsync(payload); string aiMessage = JsonSerializer.Serialize(updated); await SendChatMessageAsync( chatId, AIAgents.WorkoutAgentId, aiMessage, "updatedPlan" ); } break; default: throw new HubException("Invalid reason for sending message."); } } public async Task LeaveChat(object payload) { var data = DeserializePayload.Deserialize(payload); Guid chatId = DataExtractor.GetRequiredGuid(data, "chatId"); await Groups.RemoveFromGroupAsync( Context.ConnectionId, $"chat-{chatId}" ); } private async Task SendChatMessageAsync( Guid chatId, Guid senderId, string message,string type) { var savedMessage = await _chatService.SendMessageAsync(new { chatId = chatId, senderId = senderId, message = message, type = type }); await Clients.Group($"chat-{chatId}") .SendAsync("ReceiveMessage", savedMessage); } } }