using Microsoft.EntityFrameworkCore; using Moonlight.App.Database.Entities; using Moonlight.App.Events; using Moonlight.App.Repositories; namespace Moonlight.App.Services.SupportChat; public class SupportChatServerService { private readonly IServiceScopeFactory ServiceScopeFactory; private readonly DateTimeService DateTimeService; private readonly EventSystem Event; public SupportChatServerService( IServiceScopeFactory serviceScopeFactory, DateTimeService dateTimeService, EventSystem eventSystem) { ServiceScopeFactory = serviceScopeFactory; DateTimeService = dateTimeService; Event = eventSystem; } public Task GetMessages(User recipient) { using var scope = ServiceScopeFactory.CreateScope(); var msgRepo = scope.ServiceProvider.GetRequiredService>(); var messages = msgRepo .Get() .Include(x => x.Recipient) .Include(x => x.Sender) .Where(x => x.Recipient.Id == recipient.Id) .OrderByDescending(x => x.CreatedAt) .AsEnumerable() .Take(50) .ToArray(); return Task.FromResult(messages); } public async Task SendMessage(User recipient, string content, User? sender, string? attachment = null) { using var scope = ServiceScopeFactory.CreateScope(); var msgRepo = scope.ServiceProvider.GetRequiredService>(); var userRepo = scope.ServiceProvider.GetRequiredService>(); var message = new SupportChatMessage() { CreatedAt = DateTimeService.GetCurrent(), IsQuestion = false, Sender = sender == null ? null : userRepo.Get().First(x => x.Id == sender.Id), Recipient = userRepo.Get().First(x => x.Id == recipient.Id), Answer = "", Attachment = attachment ?? "", Content = content, UpdatedAt = DateTimeService.GetCurrent() }; var finalMessage = msgRepo.Add(message); await Event.Emit($"supportChat.{recipient.Id}.message", finalMessage); await Event.Emit("supportChat.message", finalMessage); if (!userRepo.Get().First(x => x.Id == recipient.Id).SupportPending) { var ticketStart = new SupportChatMessage() { CreatedAt = DateTimeService.GetCurrent(), IsQuestion = false, Sender = null, Recipient = userRepo.Get().First(x => x.Id == recipient.Id), Answer = "", Attachment = "", Content = "Support ticket open", //TODO: Config UpdatedAt = DateTimeService.GetCurrent() }; var ticketStartFinal = msgRepo.Add(ticketStart); var user = userRepo.Get().First(x => x.Id == recipient.Id); user.SupportPending = true; userRepo.Update(user); await Event.Emit($"supportChat.{recipient.Id}.message", ticketStartFinal); await Event.Emit("supportChat.message", ticketStartFinal); await Event.Emit("supportChat.new", recipient); } return finalMessage; } public Task> GetOpenChats() { var result = new Dictionary(); using var scope = ServiceScopeFactory.CreateScope(); var userRepo = scope.ServiceProvider.GetRequiredService>(); var msgRepo = scope.ServiceProvider.GetRequiredService>(); foreach (var user in userRepo.Get().Where(x => x.SupportPending).ToArray()) { var lastMessage = msgRepo .Get() .Include(x => x.Recipient) .Include(x => x.Sender) .Where(x => x.Recipient.Id == user.Id) .OrderByDescending(x => x.CreatedAt) .AsEnumerable() .FirstOrDefault(); result.Add(user, lastMessage); } return Task.FromResult(result); } public async Task CloseChat(User recipient) { using var scope = ServiceScopeFactory.CreateScope(); var msgRepo = scope.ServiceProvider.GetRequiredService>(); var userRepo = scope.ServiceProvider.GetRequiredService>(); var ticketEnd = new SupportChatMessage() { CreatedAt = DateTimeService.GetCurrent(), IsQuestion = false, Sender = null, Recipient = userRepo.Get().First(x => x.Id == recipient.Id), Answer = "", Attachment = "", Content = "Support ticket closed", //TODO: Config UpdatedAt = DateTimeService.GetCurrent() }; var ticketEndFinal = msgRepo.Add(ticketEnd); var user = userRepo.Get().First(x => x.Id == recipient.Id); user.SupportPending = false; userRepo.Update(user); await Event.Emit($"supportChat.{recipient.Id}.message", ticketEndFinal); await Event.Emit("supportChat.message", ticketEndFinal); await Event.Emit("supportChat.close", recipient); } }