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

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

/// <summary>
/// 次卡模板列表查询处理器。
/// </summary>
public sealed class GetPunchCardTemplateListQueryHandler(
    IPunchCardRepository repository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetPunchCardTemplateListQuery, PunchCardListResultDto>
{
    /// <inheritdoc />
    public async Task<PunchCardListResultDto> Handle(
        GetPunchCardTemplateListQuery request,
        CancellationToken cancellationToken)
    {
        var tenantId = tenantProvider.GetCurrentTenantId();
        var page = Math.Max(1, request.Page);
        var pageSize = Math.Clamp(request.PageSize, 1, 200);
        var status = PunchCardMapping.ParseTemplateStatusFilter(request.Status);

        var (items, totalCount) = await repository.SearchTemplatesAsync(
            tenantId,
            request.StoreId,
            request.Keyword,
            status,
            page,
            pageSize,
            cancellationToken);

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

        var mappedItems = items
            .Select(item =>
            {
                var aggregate = aggregates.TryGetValue(item.Id, out var value)
                    ? value
                    : PunchCardDtoFactory.EmptyAggregate(item.Id);
                return PunchCardDtoFactory.ToListItemDto(item, aggregate);
            })
            .ToList();

        var statsSnapshot = await repository.GetTemplateStatsAsync(
            tenantId,
            request.StoreId,
            cancellationToken);

        return new PunchCardListResultDto
        {
            Items = mappedItems,
            Page = page,
            PageSize = pageSize,
            TotalCount = totalCount,
            Stats = PunchCardDtoFactory.ToStatsDto(statsSnapshot)
        };
    }
}
