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;

namespace TakeoutSaaS.Application.Identity.Handlers;

/// <summary>
/// 角色模板克隆处理器。
/// </summary>
public sealed class CloneRoleTemplateCommandHandler(IRoleTemplateRepository roleTemplateRepository)
    : IRequestHandler<CloneRoleTemplateCommand, RoleTemplateDto>
{
    /// <inheritdoc />
    public async Task<RoleTemplateDto> Handle(CloneRoleTemplateCommand request, CancellationToken cancellationToken)
    {
        // 1. 校验源模板是否存在
        var source = await roleTemplateRepository.FindByCodeAsync(request.SourceTemplateCode, cancellationToken)
            ?? throw new BusinessException(ErrorCodes.NotFound, $"角色模板 {request.SourceTemplateCode} 不存在");

        // 2. 校验新模板编码是否冲突
        var exists = await roleTemplateRepository.FindByCodeAsync(request.NewTemplateCode, cancellationToken);
        if (exists is not null)
        {
            throw new BusinessException(ErrorCodes.Conflict, $"角色模板编码 {request.NewTemplateCode} 已存在");
        }

        // 3. 获取源模板权限
        var sourcePermissions = await roleTemplateRepository.GetPermissionsAsync(source.Id, cancellationToken);
        var permissionCodes = request.PermissionCodes is not null && request.PermissionCodes.Count > 0
            ? request.PermissionCodes.Distinct(StringComparer.OrdinalIgnoreCase).ToArray()
            : sourcePermissions
                .Select(x => x.PermissionCode)
                .Where(code => !string.IsNullOrWhiteSpace(code))
                .Distinct(StringComparer.OrdinalIgnoreCase)
                .ToArray();

        // 4. 构造新模板实体
        var target = new RoleTemplate
        {
            TemplateCode = request.NewTemplateCode.Trim(),
            Name = string.IsNullOrWhiteSpace(request.Name) ? source.Name : request.Name.Trim(),
            Description = request.Description ?? source.Description,
            IsActive = request.IsActive ?? source.IsActive
        };

        // 5. 持久化新模板与权限
        await roleTemplateRepository.AddAsync(target, permissionCodes, cancellationToken);
        await roleTemplateRepository.SaveChangesAsync(cancellationToken);

        // 6. 映射返回 DTO
        var permissionDtos = permissionCodes
            .Select(code => new PermissionTemplateDto
            {
                Code = code,
                Name = code,
                Description = code
            })
            .ToList();

        return new RoleTemplateDto
        {
            TemplateCode = target.TemplateCode,
            Name = target.Name,
            Description = target.Description,
            IsActive = target.IsActive,
            Permissions = permissionDtos
        };
    }
}
