using System.Net;

namespace Netina.Core.EntityServices.MarketerHandlers;

public class GetMarketerProfileQueryHandler : IRequestHandler<GetMarketerProfileQuery, MarketerProfileResponseDto>
{
    private readonly IRepositoryWrapper _repositoryWrapper;
    private readonly ICurrentUserService _currentUserService;
    private readonly ISettingService _settingService;

    public GetMarketerProfileQueryHandler(IRepositoryWrapper repositoryWrapper, ICurrentUserService currentUserService,ISettingService settingService)
    {
        _repositoryWrapper = repositoryWrapper;
        _currentUserService = currentUserService;
        _settingService = settingService;
    }
    public async Task<MarketerProfileResponseDto> Handle(GetMarketerProfileQuery request, CancellationToken cancellationToken)
    {
        Guid marketerId;
        Marketer? marketer;
        if (request.MarketerId != null)
        {
            marketerId = request.MarketerId.Value;
            marketer = await _repositoryWrapper.SetRepository<Marketer>()
                .TableNoTracking
                .FirstOrDefaultAsync(m => m.Id == marketerId, cancellationToken);
        }
        else
        {
            if (_currentUserService.UserId == null)
                throw new BaseApiException("User id is null");
            if (!Guid.TryParse(_currentUserService.UserId, out Guid userId))
                throw new BaseApiException("User id is wrong");
            marketer = await _repositoryWrapper.SetRepository<Marketer>()
                .TableNoTracking
                .FirstOrDefaultAsync(m => m.UserId == userId, cancellationToken);

        }

        if (marketer == null)
            throw new BaseApiException(ApiResultStatusCode.MarketerNotFound,"Marketer not found" ,HttpStatusCode.NotFound);

        var discount = await _repositoryWrapper.SetRepository<Discount>()
            .TableNoTracking
            .FirstOrDefaultAsync(d => d.MarketerId == marketer.Id, cancellationToken);

        if (discount == null)
            throw new BaseApiException("Marketer has no discount");

        var setting = (await _settingService.GetSettingAsync(nameof(MarketerSetting), cancellationToken)) as MarketerSetting;
        if (setting == null)
            throw new BaseApiException("MarketerSetting is null");


        var response = new MarketerProfileResponseDto();

        var orderCount = await _repositoryWrapper.SetRepository<Order>()
            .TableNoTracking
            .CountAsync(o => o.DiscountCode == discount.Code, cancellationToken);
        response.OrderCount = orderCount;

        var newTotalProductPrice = await _repositoryWrapper.SetRepository<Order>()
            .TableNoTracking
            .Where(o => o.DiscountCode == discount.Code && o.OrderAt.Date > marketer.LastSettlement.Date)
            .SumAsync(o => o.TotalProductsPrice, cancellationToken);
        response.Balance = (long)(newTotalProductPrice / 100) * setting.ProfitPercent;
        response.DiscountCode = discount.Code;
        response.LastSettlementAt = marketer.LastSettlement;

        return response;
    }
}