using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Api.Stocks.GetForeignCustody; internal sealed class Handler(IAppDbContext db) : IQueryHandler> { public async Task> Handle(Query request, CancellationToken ct) { var query = db.ForeignCustodyNation.AsNoTracking(); var nation = request.Nation?.Trim(); if (!string.IsNullOrEmpty(nation)) { query = query.Where(c => c.NationCd == nation); } var secnTpcd = request.SecnTpcd?.Trim(); var filterBySecnTpcd = !string.IsNullOrEmpty(secnTpcd); if (filterBySecnTpcd) { query = query.Where(c => c.SecnTpcd == secnTpcd); } if (request.From.HasValue) { query = query.Where(c => c.StdDt >= request.From.Value); } if (request.To.HasValue) { query = query.Where(c => c.StdDt <= request.To.Value); } var rows = await query .Select(c => new { c.NationCd, c.SecnTpcd, c.StdDt, c.FrsecCusAmt }) .ToListAsync(ct); List series; if (filterBySecnTpcd) { // 종목구분 지정 → 국가×종목구분별 시계열 (개별 유지) series = rows .GroupBy(c => new { c.NationCd, c.SecnTpcd }) .Select(g => new Response.Series { NationCd = g.Key.NationCd, SecnTpcd = g.Key.SecnTpcd, Points = g .OrderBy(c => c.StdDt) .Select(c => new Response.Point { StdDt = c.StdDt, CustodyAmount = c.FrsecCusAmt ?? 0m }) .ToList() }) .OrderBy(c => c.NationCd) .ToList(); } else { // 미지정 → 국가별로 같은 기준일의 종목구분 금액을 합산 series = rows .GroupBy(c => c.NationCd) .Select(g => new Response.Series { NationCd = g.Key, SecnTpcd = null, Points = g .GroupBy(c => c.StdDt) .OrderBy(p => p.Key) .Select(p => new Response.Point { StdDt = p.Key, CustodyAmount = p.Sum(c => c.FrsecCusAmt ?? 0m) }) .ToList() }) .OrderBy(c => c.NationCd) .ToList(); } return new Response { Nations = series }; } }