using AutoMapper; using IM.Commons; using System.Diagnostics; using MessageService.Domain.IReposities; using MessageService.WebApi.Application.Dtos; namespace MessageService.WebApi.Application.Conversation { public class ConversationService { private readonly IConversationReposity reposity; private readonly IMapper mapper; private readonly ILogger logger; public ConversationService(IConversationReposity reposity, IMapper mapper, ILogger logger) { this.reposity = reposity; this.mapper = mapper; this.logger = logger; } public async Task>> GetByOwnerIdAsync(Guid userId, CancellationToken cancellationToken = default) { var stopwatch = Stopwatch.StartNew(); try { var list = await reposity.ListByUserIdAsync(userId, cancellationToken); return Result.Success(list.Select(item => new ConversationResponse { Id = item.Id, UserId = item.UserId, TargetId = item.TargetId, TargetAvatar = item.TargetAvatar, TargetName = item.TargetName, LastReadSequenceId = item.LastReadSequenceId, UnreadCount = item.UnreadCount, ChatType = item.ChatType, LastMessage = item.LastMessage, DateTime = item.DateTime }).ToList()); } finally { stopwatch.Stop(); var traceId = Activity.Current?.TraceId.ToString() ?? string.Empty; if (stopwatch.ElapsedMilliseconds > 1000) { logger.LogWarning("Conversation list query was slow. TraceId={TraceId} UserId={UserId} ElapsedMs={ElapsedMs}", traceId, userId, stopwatch.ElapsedMilliseconds); } else { logger.LogInformation("Conversation list query completed. TraceId={TraceId} UserId={UserId} ElapsedMs={ElapsedMs}", traceId, userId, stopwatch.ElapsedMilliseconds); } } } public async Task> GetByIdAsync(Guid id, Guid userId, CancellationToken cancellationToken = default) { var conversation = await reposity.FindByIdAsync(id, cancellationToken); if (conversation is null || conversation.UserId != userId) { return Result.Fail(ResultCode.CONVERSATION_NOT_FOUND); } return Result.Success(mapper.Map(conversation)); } public async Task>> GetStreamkeysAsync(Guid userId, CancellationToken cancellationToken = default) { var list = await reposity.FindAllStreamKeyAsync(userId, cancellationToken); return Result.Success(list.ToList()); } public async Task> MarkAsReadAsync(Guid conversationId, Guid userId, long? lastReadSequenceId = null, CancellationToken cancellationToken = default) { var conversation = await reposity.FindByIdAsync(conversationId, cancellationToken); if (conversation is null || conversation.UserId != userId) { return Result.Fail(ResultCode.CONVERSATION_NOT_FOUND); } conversation.MarkAsRead(lastReadSequenceId); return Result.Success(); } } }