using MediatR;
using TakeoutSaaS.Application.App.Merchants.Commands;
using TakeoutSaaS.Application.App.Merchants.Dto;
using TakeoutSaaS.Domain.Merchants.Entities;
using TakeoutSaaS.Domain.Merchants.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.App.Merchants.Handlers;

/// <summary>
/// 创建类目处理器。
/// </summary>
public sealed class CreateMerchantCategoryCommandHandler(
    IMerchantCategoryRepository categoryRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<CreateMerchantCategoryCommand, MerchantCategoryDto>
{
    /// <summary>
    /// 处理创建商户类目请求。
    /// </summary>
    /// <param name="request">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>类目 DTO。</returns>
    public async Task<MerchantCategoryDto> Handle(CreateMerchantCategoryCommand request, CancellationToken cancellationToken)
    {
        // 1. 获取租户上下文
        var tenantId = tenantProvider.GetCurrentTenantId();
        var normalizedName = request.Name.Trim();

        // 2. 检查重名
        if (await categoryRepository.ExistsAsync(normalizedName, tenantId, cancellationToken))
        {
            throw new BusinessException(ErrorCodes.Conflict, $"类目“{normalizedName}”已存在");
        }

        // 3. 计算排序
        var categories = await categoryRepository.ListAsync(tenantId, cancellationToken);
        var targetOrder = request.DisplayOrder ?? (categories.Count == 0 ? 1 : categories.Max(x => x.DisplayOrder) + 1);

        // 4. 构建实体
        var entity = new MerchantCategory
        {
            Name = normalizedName,
            DisplayOrder = targetOrder,
            IsActive = request.IsActive
        };

        // 5. 持久化并返回
        await categoryRepository.AddAsync(entity, cancellationToken);
        await categoryRepository.SaveChangesAsync(cancellationToken);

        return MerchantMapping.ToDto(entity);
    }
}
