using Application.Abstractions.Data; using Application.Abstractions.Messaging; using Domain.Entities.Store.ValueObject; using Microsoft.EntityFrameworkCore; using SharedKernel.Results; namespace Application.Features.Admin.Store.Coupon.DeleteCodes; public sealed class Handler(IAppDbContext db) : ICommandHandler> { public async Task> Handle(Command request, CancellationToken ct) { if (request.CodeIDs is null || request.CodeIDs.Length == 0) { return Result.Failure(Error.Problem("CouponCode.NoIDs", "삭제할 코드를 선택해 주세요.")); } var targets = await db.CouponCode .Where(c => c.CouponID == request.CouponID && request.CodeIDs.Contains(c.ID)) .ToListAsync(ct); if (targets.Count == 0) { return Result.Failure(Error.NotFound("CouponCode.NotFound", "삭제할 코드를 찾을 수 없습니다.")); } var blocked = targets.Where(c => c.Status != CouponCodeStatus.Available).ToList(); if (blocked.Count > 0) { var preview = string.Join(", ", blocked.Take(10).Select(c => $"#{c.ID}({StatusText(c.Status)})")); var more = blocked.Count > 10 ? $" 외 {blocked.Count - 10}건" : string.Empty; return Result.Failure(Error.Conflict( "CouponCode.NotAvailable", $"사용 가능 상태(Available) 코드만 삭제할 수 있습니다. 대상 외 코드: {preview}{more}" )); } db.CouponCode.RemoveRange(targets); await db.SaveChangesAsync(ct); return Result.Success(new Response(targets.Count)); } private static string StatusText(CouponCodeStatus status) => status switch { CouponCodeStatus.Reserved => "결제 진행 중", CouponCodeStatus.Issued => "발급됨", CouponCodeStatus.Used => "사용됨", _ => status.ToString() }; }