using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Application.Abstractions.YouTube; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Studio.GetSettings; internal sealed class Handler(IAppDbContext db, IYouTubeChannelCache channelCache) : IQueryHandler> { private static readonly Response Empty = new(false, null, null, null, null, null, null, 0, 0, 0, null); public async Task> Handle(Query request, CancellationToken ct) { var channel = await db.Channel.AsNoTracking().FirstOrDefaultAsync(c => c.MemberID == request.MemberID && c.IsActive, ct); if (channel is null) { return Result.Success(Empty); } // 채널 레코드가 존재하면 YouTube 연동된 상태 // SID = YouTube 채널 ID (캐시 키로 사용) var ytChannelID = channel.YouTubeChannelID ?? channel.SID; var ytInfo = await channelCache.GetAsync(ytChannelID); if (ytInfo is not null) { // 캐시 데이터가 DB와 다르면 DB 동기화 if (ytInfo.Title != channel.Name || ytInfo.SubscriberCount != channel.SubscriberCount || ytInfo.VideoCount != channel.VideoCount || ytInfo.ViewCount != channel.ViewCount || channel.YouTubeChannelID is null) { var tracked = await db.Channel.FindAsync([channel.ID], ct); if (tracked is not null) { tracked.UpdateYouTubeInfo( ytInfo.ChannelID, ytInfo.Title, ytInfo.CustomUrl, ytInfo.Description, ytInfo.ThumbnailUrl, ytInfo.BannerUrl, ytInfo.SubscriberCount, ytInfo.VideoCount, ytInfo.ViewCount, ytInfo.Email, ytInfo.PublishedAt); await db.SaveChangesAsync(ct); } } return Result.Success(new Response( true, ytInfo.Title, ytInfo.CustomUrl, ytInfo.Description, channel.YouTubeUrl, ytInfo.ThumbnailUrl, ytInfo.BannerUrl, ytInfo.SubscriberCount, ytInfo.VideoCount, ytInfo.ViewCount, ytInfo.PublishedAt)); } // 캐시 미스 → DB 데이터로 응답 var isConnected = channel.YouTubeChannelID is not null; return Result.Success(new Response( isConnected, channel.Name, channel.Handle, channel.Description, channel.YouTubeUrl, channel.ThumbnailUrl, channel.BannerUrl, channel.SubscriberCount, channel.VideoCount, channel.ViewCount, channel.YouTubePublishedAt)); } }