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

namespace TakeoutSaaS.Application.App.Members.Handlers;

/// <summary>
/// 优惠券选择器查询处理器。
/// </summary>
public sealed class SearchMemberCouponPickerQueryHandler(
    ICouponRepository couponRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<SearchMemberCouponPickerQuery, IReadOnlyList<MemberCouponPickerItemDto>>
{
    /// <inheritdoc />
    public async Task<IReadOnlyList<MemberCouponPickerItemDto>> Handle(
        SearchMemberCouponPickerQuery request,
        CancellationToken cancellationToken)
    {
        if (request.VisibleStoreIds.Count == 0)
        {
            return [];
        }

        var tenantId = tenantProvider.GetCurrentTenantId();
        var keyword = (request.Keyword ?? string.Empty).Trim();
        var nowUtc = DateTime.UtcNow;

        var templates = await couponRepository.GetTemplatesAsync(tenantId, cancellationToken);

        var filtered = templates
            .Where(template => MemberCenterSupport.IsCouponVisibleToStores(template, request.VisibleStoreIds))
            .Where(template => MemberCenterSupport.IsCouponActive(template, nowUtc))
            .Where(template =>
                string.IsNullOrWhiteSpace(keyword) ||
                template.Name.Contains(keyword, StringComparison.OrdinalIgnoreCase))
            .OrderByDescending(template => template.UpdatedAt ?? template.CreatedAt)
            .ThenByDescending(template => template.Id)
            .Take(200)
            .Select(template => new MemberCouponPickerItemDto
            {
                CouponTemplateId = template.Id,
                Name = template.Name,
                CouponType = MemberCenterSupport.ResolveCouponTypeText(template.CouponType),
                Value = decimal.Round(template.Value, 2, MidpointRounding.AwayFromZero),
                MinimumSpend = template.MinimumSpend,
                DisplayText = MemberCenterSupport.BuildCouponDisplayText(template)
            })
            .ToList();

        return filtered;
    }
}
