using Application.Abstractions.YouTube; using SharedKernel.Extensions; using MediatR; using Microsoft.AspNetCore.Mvc.RazorPages; namespace Admin.Pages.Channel.List { public class ViewModel(IMediator mediator, IYouTubeApiService youTubeApi, IYouTubeLiveStateStore liveStateStore, IYouTubeChannelCache channelCache) : PageModel { // ── DB 데이터 ──────────────────────────────────────────────── public int ID { get; set; } public int MemberID { get; set; } public string? MemberInfo { get; set; } public string SID { get; set; } = default!; public string Name { get; set; } = default!; public string? Handle { get; set; } public string YouTubeUrl { get; set; } = default!; public decimal PlatformFeeRate { get; set; } public bool IsVerified { get; set; } public bool IsActive { get; set; } public string? UpdatedAt { get; set; } public string CreatedAt { get; set; } = default!; // ── YouTube API 데이터 ─────────────────────────────────────── public YouTubeChannelInfo? YouTubeChannel { get; set; } public bool YouTubeApiFailed { get; set; } public string? YouTubeApiError { get; set; } // ── 라이브 상태 (PubSub 기반 — Redis 조회만, API 호출 없음) ── public YouTubeLiveStreamInfo? LiveStream { get; set; } public async Task OnGetAsync(int id, CancellationToken ct) { var result = await mediator.Send(new GetChannel.Query(id), ct); if (result is null) { return; } ID = result.ID; MemberID = result.MemberID; MemberInfo = $"[{result.MemberID}] {result.MemberEmail}, {result.MemberName ?? result.MemberSID ?? "-"}"; SID = result.SID; Name = result.Name; Handle = result.Handle; YouTubeUrl = result.YouTubeUrl; PlatformFeeRate = result.PlatformFeeRate; IsVerified = result.IsVerified; IsActive = result.IsActive; UpdatedAt = result.UpdatedAt.GetDateAt(); CreatedAt = result.CreatedAt.GetDateAt(); // SID = YouTube 채널 ID → 채널 정보 조회 (1 unit) await FetchYouTubeChannelAsync(result.SID, ct); // 라이브 상태는 Redis에서만 조회 (API 호출 없음, 0 unit) LiveStream = await liveStateStore.GetLiveAsync(result.SID); } private async Task FetchYouTubeChannelAsync(string channelId, CancellationToken ct) { try { YouTubeChannel = await youTubeApi.GetChannelByIdAsync(channelId, ct); // YouTube API 조회 성공 시 Redis 캐시에 저장 (24시간 TTL) if (YouTubeChannel is not null) { await channelCache.SetAsync(YouTubeChannel); } if (YouTubeChannel is null) { YouTubeApiFailed = true; YouTubeApiError = $"채널 정보를 찾을 수 없습니다. 조회한 SID: \"{channelId}\" — DB Config의 YouTube API Key 설정을 확인하세요."; } } catch (Exception ex) { YouTubeApiFailed = true; YouTubeApiError = $"YouTube API 조회 실패: {ex.Message}"; } } } }