using MediatR;
using TakeoutSaaS.Application.App.Members.PointsMall.Dto;
using TakeoutSaaS.Application.App.Members.PointsMall.Queries;
using TakeoutSaaS.Domain.Membership.Repositories;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Members.PointsMall.Handlers;

/// <summary>
/// 查询积分商城商品列表处理器。
/// </summary>
public sealed class GetPointMallProductListQueryHandler(
    IPointMallRepository repository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetPointMallProductListQuery, MemberPointMallProductListResultDto>
{
    /// <inheritdoc />
    public async Task<MemberPointMallProductListResultDto> Handle(
        GetPointMallProductListQuery request,
        CancellationToken cancellationToken)
    {
        var tenantId = tenantProvider.GetCurrentTenantId();
        var status = MemberPointMallMapping.TryParseProductStatus(request.Status);
        var keyword = MemberPointMallMapping.NormalizeKeyword(request.Keyword);

        var items = await repository.SearchProductsAsync(
            tenantId,
            request.StoreId,
            status,
            keyword,
            cancellationToken);

        var productIds = items.Select(item => item.Id).ToList();
        var aggregates = await repository.GetProductAggregatesAsync(
            tenantId,
            request.StoreId,
            productIds,
            cancellationToken);

        var rows = items
            .Select(item =>
            {
                var aggregate = aggregates.TryGetValue(item.Id, out var value)
                    ? value
                    : MemberPointMallDtoFactory.EmptyProductAggregate(item.Id);
                return MemberPointMallDtoFactory.ToProductDto(item, aggregate);
            })
            .ToList();

        return new MemberPointMallProductListResultDto
        {
            Items = rows
        };
    }
}
