using MediatR;
using TakeoutSaaS.Application.Identity.Commands;
using TakeoutSaaS.Application.Identity.Contracts;
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 UpdateMenuCommandHandler(
    IMenuRepository menuRepository,
    ITenantProvider tenantProvider)
    : IRequestHandler<UpdateMenuCommand, MenuDefinitionDto?>
{
    /// <inheritdoc />
    public async Task<MenuDefinitionDto?> Handle(UpdateMenuCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验存在
        var tenantId = tenantProvider.GetCurrentTenantId();
        var entity = await menuRepository.FindByIdAsync(request.Id, tenantId, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, "菜单不存在");

        // 2. 更新字段
        entity.ParentId = request.ParentId;
        entity.Name = request.Name.Trim();
        entity.Path = request.Path.Trim();
        entity.Component = request.Component.Trim();
        entity.Title = request.Title.Trim();
        entity.Icon = request.Icon?.Trim();
        entity.IsIframe = request.IsIframe;
        entity.Link = string.IsNullOrWhiteSpace(request.Link) ? null : request.Link.Trim();
        entity.KeepAlive = request.KeepAlive;
        entity.SortOrder = request.SortOrder;
        entity.RequiredPermissions = MenuMapper.JoinCodes(request.RequiredPermissions);
        entity.MetaPermissions = MenuMapper.JoinCodes(request.MetaPermissions);
        entity.MetaRoles = MenuMapper.JoinCodes(request.MetaRoles);
        entity.AuthListJson = request.AuthList.Count == 0
            ? null
            : System.Text.Json.JsonSerializer.Serialize(request.AuthList);

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

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