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

namespace TakeoutSaaS.Application.App.Members.Handlers;

/// <summary>
/// 会员等级列表查询处理器。
/// </summary>
public sealed class GetMemberTierListQueryHandler(
    IMemberRepository memberRepository,
    IOrderRepository orderRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetMemberTierListQuery, IReadOnlyList<MemberTierListItemDto>>
{
    /// <inheritdoc />
    public async Task<IReadOnlyList<MemberTierListItemDto>> Handle(
        GetMemberTierListQuery request,
        CancellationToken cancellationToken)
    {
        await MemberCenterSupport.EnsureMemberCenterInitializedAsync(
            memberRepository,
            orderRepository,
            tenantProvider,
            cancellationToken);

        var tenantId = tenantProvider.GetCurrentTenantId();
        var tiers = await memberRepository.GetTiersAsync(tenantId, cancellationToken);
        var profiles = await memberRepository.GetProfilesAsync(tenantId, cancellationToken);

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

        var memberCountMap = profiles
            .Where(item => item.MemberTierId.HasValue)
            .GroupBy(item => item.MemberTierId!.Value)
            .ToDictionary(group => group.Key, group => group.Count());

        var result = tiers
            .OrderBy(item => item.SortOrder)
            .ThenBy(item => item.Id)
            .Select(tier =>
            {
                memberCountMap.TryGetValue(tier.Id, out var memberCount);
                var benefits = MemberCenterSupport.DeserializeBenefits(tier.BenefitsJson);
                var canDelete = !tier.IsDefault && memberCount <= 0 && tiers.Count > 1;

                return new MemberTierListItemDto
                {
                    TierId = tier.Id,
                    SortOrder = tier.SortOrder,
                    Name = tier.Name,
                    IconKey = tier.IconKey,
                    ColorHex = tier.ColorHex,
                    ConditionText = MemberCenterSupport.BuildConditionText(tier),
                    Perks = MemberCenterSupport.BuildPerks(tier, benefits),
                    MemberCount = memberCount,
                    IsDefault = tier.IsDefault,
                    CanDelete = canDelete
                };
            })
            .ToList();

        return result;
    }
}
