using SharedKernel.Helpers;
using SharedKernel.Extensions;
using Application.Abstractions.YouTube;
using MediatR;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Admin.Pages.Channel.List
{
public class IndexModel(IMediator mediator, IYouTubeLiveStateStore liveStateStore) : PageModel
{
[BindProperty(SupportsGet = true)]
public QueryParams Query { get; set; } = new();
public sealed class QueryParams
{
public int? Search { get; set; }
public string? Keyword { get; set; }
public string? StartAt { get; set; }
public string? EndAt { get; set; }
public bool? IsVerified { get; set; }
[Range(1, int.MaxValue)]
[DisplayName("페이지 번호")]
public int PageNum { get; set; } = 1;
[Range(1, 100)]
[DisplayName("페이지 목록 수")]
public ushort PerPage { get; set; } = 20;
}
public int Total { get; set; } = 0;
public List<(
int Num,
int ID,
string SID,
string Name,
string? Handle,
string YouTubeUrl,
decimal PlatformFeeRate,
char IsVerified,
char IsActive,
int MemberID,
string? MemberName,
string? MemberEmail,
string? UpdatedAt,
string CreatedAt
)> List { get; set; } = [];
public Pagination? Pagination { get; set; }
/// 현재 라이브 중인 채널 SID(=YouTube 채널 ID) 집합
public HashSet LiveChannelIds { get; set; } = [];
public async Task OnGetAsync(CancellationToken ct)
{
if (!ModelState.IsValid)
{
return;
}
var result = await mediator.Send(new SearchChannels.Query(
Query.Search,
Query.Keyword,
Query.IsVerified,
Query.StartAt,
Query.EndAt,
Query.PageNum,
Query.PerPage
), ct);
Total = result.Total;
List = [..result.List.Select(c => (
c.Num,
c.ID,
c.SID,
c.Name,
c.Handle,
c.YouTubeUrl,
c.PlatformFeeRate,
c.IsVerified ? 'Y' : 'N',
c.IsActive ? 'Y' : 'N',
c.MemberID,
c.MemberName ?? "-",
c.MemberEmail ?? "-",
c.UpdatedAt.GetDateAt() ?? "-",
c.CreatedAt.GetDateAt()
))];
Pagination = new Pagination(result.Total, Query.PageNum, Query.PerPage);
// Redis에서 현재 라이브 중인 채널 ID 조회 (API 호출 없음)
var allLive = await liveStateStore.GetAllLiveAsync();
LiveChannelIds = [..allLive.Select(l => l.ChannelId)];
}
public async Task OnPostDeleteAsync(int[] ids, CancellationToken ct)
{
try
{
await mediator.Send(new DeleteChannel.Command(ids), ct);
TempData["SuccessMessage"] = $"{ids.Length}건이 삭제되었습니다.";
}
catch (Exception e)
{
TempData["ErrorMessages"] = e.Message;
}
return RedirectToPage("/Channel/List/Index", Query);
}
}
}