using MediatR;
using TakeoutSaaS.Application.App.Coupons.Seckill.Dto;
using TakeoutSaaS.Application.App.Coupons.Seckill.Queries;
using TakeoutSaaS.Domain.Products.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Coupons.Seckill.Handlers;

/// <summary>
/// 秒杀选品商品查询处理器。
/// </summary>
public sealed class GetSeckillPickerProductsQueryHandler(
    IProductRepository productRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetSeckillPickerProductsQuery, IReadOnlyList<SeckillPickerProductItemDto>>
{
    /// <inheritdoc />
    public async Task<IReadOnlyList<SeckillPickerProductItemDto>> Handle(
        GetSeckillPickerProductsQuery request,
        CancellationToken cancellationToken)
    {
        var tenantId = tenantProvider.GetCurrentTenantId();

        var limit = Math.Clamp(request.Limit ?? 200, 1, 500);
        var products = await productRepository.SearchPickerAsync(
            tenantId,
            request.OperationStoreId,
            request.CategoryId,
            request.Keyword,
            limit,
            cancellationToken);

        if (products.Count == 0)
        {
            return [];
        }

        var categoryLookup = (await productRepository.GetCategoriesByStoreAsync(
                tenantId,
                request.OperationStoreId,
                false,
                cancellationToken))
            .ToDictionary(item => item.Id, item => item.Name);

        return products
            .Select(item => new SeckillPickerProductItemDto
            {
                Id = item.Id,
                CategoryId = item.CategoryId,
                CategoryName = categoryLookup.GetValueOrDefault(item.CategoryId, string.Empty),
                Name = item.Name,
                Price = decimal.Round(item.Price, 2, MidpointRounding.AwayFromZero),
                Stock = Math.Max(0, item.StockQuantity ?? 0),
                SpuCode = item.SpuCode,
                Status = SeckillMapping.ToProductStatusText(item.Status, item.SoldoutMode)
            })
            .ToList();
    }
}


