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

namespace TakeoutSaaS.Application.Identity.Handlers;

/// <summary>
/// 创建菜单处理器。
/// </summary>
public sealed class CreateMenuCommandHandler(IMenuRepository menuRepository)
    : IRequestHandler<CreateMenuCommand, MenuDefinitionDto>
{
    /// <inheritdoc />
    public async Task<MenuDefinitionDto> Handle(CreateMenuCommand request, CancellationToken cancellationToken)
    {
        // 1. 菜单固定时禁止新增
        if (!MenuPolicy.CanMaintainMenus)
        {
            throw new BusinessException(ErrorCodes.Forbidden, "菜单已固定，禁止新增");
        }

        // 2. 构造实体
        var entity = new MenuDefinition
        {
            Portal = PortalType.Tenant,
            ParentId = request.ParentId,
            Name = request.Name.Trim(),
            Path = request.Path.Trim(),
            Component = request.Component.Trim(),
            Title = request.Title.Trim(),
            Icon = request.Icon?.Trim(),
            IsIframe = request.IsIframe,
            Link = string.IsNullOrWhiteSpace(request.Link) ? null : request.Link.Trim(),
            KeepAlive = request.KeepAlive,
            SortOrder = request.SortOrder,
            RequiredPermissions = MenuMapper.JoinCodes(request.RequiredPermissions),
            MetaPermissions = MenuMapper.JoinCodes(request.MetaPermissions),
            MetaRoles = MenuMapper.JoinCodes(request.MetaRoles),
            AuthListJson = request.AuthList.Count == 0
                ? null
                : System.Text.Json.JsonSerializer.Serialize(request.AuthList)
        };

        // 3. 持久化
        await menuRepository.AddAsync(entity, cancellationToken);
        await menuRepository.SaveChangesAsync(cancellationToken);

        // 4. 返回 DTO
        return MenuMapper.ToDto(entity);
    }
}
