namespace Netina.Core.EntityServices.OrderBagHandlers;

public class SubmitDiscountActionCommandHandler(IRepositoryWrapper repositoryWrapper, IMediator mediator)
    : IRequestHandler<SubmitDiscountActionCommand, OrderSDto>
{
    public async Task<OrderSDto> Handle(SubmitDiscountActionCommand request, CancellationToken cancellationToken)
    {
        var order = await repositoryWrapper.SetRepository<Order>()
            .TableNoTracking
            .FirstOrDefaultAsync(o => o.Id == request.OrderId, cancellationToken);
        if (order == null)
            throw new AppException("Order not found", ApiResultStatusCode.NotFound);

        if (request.DiscountCode != null)
        {
            var discount = await repositoryWrapper.SetRepository<Discount>()
                .TableNoTracking
                .FirstOrDefaultAsync(d => d.Code == request.DiscountCode, cancellationToken);
            if (discount == null || discount.IsExpired())
                throw new AppException("تخفیف منقضی شده است یا وجود ندارد", ApiResultStatusCode.NotFound);

            var isFirstUserOfDiscount = await mediator.Send(new CheckUserDiscountFirstUseCommand(request.DiscountCode), cancellationToken);

            if (!isFirstUserOfDiscount)
                throw new BaseApiException(ApiResultStatusCode.BadRequest, "شما یک بار از این کد تخفیف استفاده نموده اید و قابلیت استفاده مجدد ندارید");

            order.SetDiscount(request.DiscountCode);
        }
        else
            order.RemoveDiscount();

        repositoryWrapper.SetRepository<Order>().Update(order);
        await repositoryWrapper.SaveChangesAsync(cancellationToken);
        var calculateOrder = await mediator.Send(new CalculateOrderCommand(order.Id), cancellationToken);

        return calculateOrder.AdaptToSDto();
    }
}