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.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Members.Handlers;

/// <summary>
/// 会员等级详情查询处理器。
/// </summary>
public sealed class GetMemberTierDetailQueryHandler(
    IMemberRepository memberRepository,
    IOrderRepository orderRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<GetMemberTierDetailQuery, MemberTierDetailDto>
{
    /// <inheritdoc />
    public async Task<MemberTierDetailDto> Handle(
        GetMemberTierDetailQuery request,
        CancellationToken cancellationToken)
    {
        await MemberCenterSupport.EnsureMemberCenterInitializedAsync(
            memberRepository,
            orderRepository,
            tenantProvider,
            cancellationToken);

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

        if (!request.TierId.HasValue)
        {
            var nextSort = tiers.Count == 0 ? 1 : tiers.Max(item => item.SortOrder) + 1;
            return new MemberTierDetailDto
            {
                TierId = null,
                SortOrder = nextSort,
                Name = string.Empty,
                IconKey = "user",
                ColorHex = "#999999",
                IsDefault = false,
                Rule = new MemberTierRuleDto
                {
                    UpgradeRuleType = "amount",
                    UpgradeAmountThreshold = 500m,
                    UpgradeOrderCountThreshold = null,
                    DowngradeWindowDays = 90
                },
                Benefits = new MemberTierBenefitsDto(),
                CanDelete = false
            };
        }

        var tier = tiers.FirstOrDefault(item => item.Id == request.TierId.Value);
        if (tier is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "会员等级不存在");
        }

        var profiles = await memberRepository.GetProfilesAsync(tenantId, cancellationToken);
        var assignedCount = profiles.Count(item => item.MemberTierId == tier.Id);
        var canDelete = !tier.IsDefault && assignedCount <= 0 && tiers.Count > 1;

        return MemberCenterSupport.ToTierDetailDto(tier, canDelete);
    }
}
