using MediatR;
using TakeoutSaaS.Application.Identity.Commands;
using TakeoutSaaS.Application.Identity.Contracts;
using TakeoutSaaS.Domain.Identity.Entities;
using TakeoutSaaS.Domain.Identity.Repositories;
using TakeoutSaaS.Shared.Abstractions.Constants;
using TakeoutSaaS.Shared.Abstractions.Exceptions;
using TakeoutSaaS.Shared.Abstractions.Tenancy;

namespace TakeoutSaaS.Application.Identity.Handlers;

/// <summary>
/// 创建权限处理器。
/// </summary>
public sealed class CreatePermissionCommandHandler(
    IPermissionRepository permissionRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<CreatePermissionCommand, PermissionDto>
{
    /// <summary>
    /// 处理创建权限请求。
    /// </summary>
    /// <param name="request">创建命令。</param>
    /// <param name="cancellationToken">取消标记。</param>
    /// <returns>创建后的权限 DTO。</returns>
    public async Task<PermissionDto> Handle(CreatePermissionCommand request, CancellationToken cancellationToken)
    {
        // 1. 权限固定时禁止新增
        if (!PermissionPolicy.CanMaintainPermissions)
        {
            throw new BusinessException(ErrorCodes.Forbidden, "权限已固定，禁止新增");
        }

        // 2. 获取租户上下文
        var tenantId = tenantProvider.GetCurrentTenantId();

        // 3. 构建权限实体
        var normalizedType = string.IsNullOrWhiteSpace(request.Type)
            ? "leaf"
            : request.Type.Trim().ToLowerInvariant();
        normalizedType = normalizedType is "group" or "leaf" ? normalizedType : "leaf";
        var parentId = request.ParentId > 0 ? request.ParentId : 0;
        var sortOrder = request.SortOrder < 0 ? 0 : request.SortOrder;
        var permission = new Permission
        {
            ParentId = parentId,
            SortOrder = sortOrder,
            Type = normalizedType,
            Name = request.Name,
            Code = request.Code,
            Description = request.Description
        };

        // 4. 持久化
        await permissionRepository.AddAsync(permission, cancellationToken);
        await permissionRepository.SaveChangesAsync(cancellationToken);

        // 5. 返回 DTO
        return new PermissionDto
        {
            Id = permission.Id,
            ParentId = permission.ParentId,
            SortOrder = permission.SortOrder,
            Type = permission.Type,
            Name = permission.Name,
            Code = permission.Code,
            Description = permission.Description
        };
    }
}
