using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Text;
using Domain.Entities.Store.ValueObject;
using Application.Abstractions.Messaging;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Admin.Pages.Store.Settlement;
///
/// 게임사 정산 목록 CSV 다운로드. 현재 필터 기준 최대 10,000 row 익스포트.
///
public class ExportModel(IMediator mediator) : PageModel
{
[BindProperty(SupportsGet = true)]
public QueryParams Query { get; set; } = new();
public sealed class QueryParams
{
[DisplayName("게임")]
public int? GameID { get; set; }
[DisplayName("연도")]
[Range(2000, 9999)]
public int? Year { get; set; }
[DisplayName("월")]
[Range(1, 12)]
public int? Month { get; set; }
[DisplayName("정산 상태")]
public GameSettlementStatus? Status { get; set; }
}
public async Task OnGetAsync(CancellationToken ct)
{
// 한 번에 최대 10,000 row 익스포트 (운영상 충분)
var result = await mediator.Send(new SearchGameSettlements.Query(
Query.GameID,
Query.Year,
Query.Month,
Query.Status,
1,
10000
), ct);
var sb = new StringBuilder();
sb.Append(''); // UTF-8 BOM (Excel 한글 호환)
sb.AppendLine("게임ID,게임명,게임사,연도,월,매출(원),주문수,상태,등록일시,처리일시,처리관리자,관리자메모");
foreach (var c in result.List)
{
sb.Append(c.GameID).Append(',');
sb.Append(Csv(c.GameName)).Append(',');
sb.Append(Csv(c.GamePublisher)).Append(',');
sb.Append(c.Year).Append(',');
sb.Append(c.Month).Append(',');
sb.Append(c.TotalRevenueAmount).Append(',');
sb.Append(c.OrderCount).Append(',');
sb.Append(Csv(StatusToText(c.Status))).Append(',');
sb.Append(c.CreatedAt.ToString("yyyy-MM-dd HH:mm")).Append(',');
sb.Append(c.SettledAt?.ToString("yyyy-MM-dd HH:mm") ?? "").Append(',');
sb.Append(Csv(c.SettledByAdminEmail ?? "")).Append(',');
sb.AppendLine(Csv(c.AdminMemo ?? ""));
}
var fileName = $"GameSettlements_{DateTime.UtcNow:yyyyMMdd_HHmmss}.csv";
return File(Encoding.UTF8.GetBytes(sb.ToString()), "text/csv", fileName);
}
private static string Csv(string s)
{
if (string.IsNullOrEmpty(s))
{
return "";
}
if (s.Contains(',') || s.Contains('"') || s.Contains('\n') || s.Contains('\r'))
{
return "\"" + s.Replace("\"", "\"\"") + "\"";
}
return s;
}
private static string StatusToText(GameSettlementStatus s) => s switch
{
GameSettlementStatus.Pending => "정산 대기",
GameSettlementStatus.Settled => "정산 완료",
_ => "?"
};
}