using MediatR;
using TakeoutSaaS.Application.App.Members.Commands;
using TakeoutSaaS.Domain.Membership.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 SaveMemberTagsCommandHandler(
    IMemberRepository memberRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<SaveMemberTagsCommand>
{
    /// <inheritdoc />
    public async Task Handle(SaveMemberTagsCommand request, CancellationToken cancellationToken)
    {
        var tenantId = tenantProvider.GetCurrentTenantId();
        var profile = await memberRepository.FindProfileByIdAsync(tenantId, request.MemberId, cancellationToken);
        if (profile is null)
        {
            throw new BusinessException(ErrorCodes.NotFound, "会员不存在");
        }

        var tags = (request.Tags ?? [])
            .Select(item => (item ?? string.Empty).Trim())
            .Where(item => !string.IsNullOrWhiteSpace(item))
            .Distinct(StringComparer.OrdinalIgnoreCase)
            .ToList();

        if (tags.Count > 20)
        {
            throw new BusinessException(ErrorCodes.BadRequest, "标签数量不能超过 20 个");
        }

        if (tags.Any(item => item.Length > 32))
        {
            throw new BusinessException(ErrorCodes.BadRequest, "标签长度不能超过 32 个字符");
        }

        await memberRepository.ReplaceProfileTagsAsync(tenantId, request.MemberId, tags, cancellationToken);
        await memberRepository.SaveChangesAsync(cancellationToken);
    }
}
