using System.Security.Claims;
using HoneyBox.Admin.Models.Common;
using HoneyBox.Admin.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace HoneyBox.Admin.Filters;

/// <summary>
/// 管理员权限验证特性
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
public class AdminPermissionAttribute : Attribute, IAsyncAuthorizationFilter
{
    /// <summary>
    /// 权限编码
    /// </summary>
    public string PermissionCode { get; }

    /// <summary>
    /// 构造函数
    /// </summary>
    /// <param name="permissionCode">权限编码</param>
    public AdminPermissionAttribute(string permissionCode)
    {
        PermissionCode = permissionCode;
    }

    /// <summary>
    /// 执行权限验证
    /// </summary>
    public async Task OnAuthorizationAsync(AuthorizationFilterContext context)
    {
        // 检查是否有 AllowAnonymous 特性
        var allowAnonymous = context.ActionDescriptor.EndpointMetadata
            .Any(em => em is Microsoft.AspNetCore.Authorization.AllowAnonymousAttribute);

        if (allowAnonymous)
        {
            return;
        }

        // 检查用户是否已认证
        var user = context.HttpContext.User;
        if (user?.Identity?.IsAuthenticated != true)
        {
            context.Result = new JsonResult(ApiResponse.Error(AdminErrorCodes.TokenInvalid, "未授权访问"))
            {
                StatusCode = StatusCodes.Status401Unauthorized
            };
            return;
        }

        // 获取用户ID
        var userIdClaim = user.FindFirst(ClaimTypes.NameIdentifier);
        if (userIdClaim == null || !long.TryParse(userIdClaim.Value, out var userId))
        {
            context.Result = new JsonResult(ApiResponse.Error(AdminErrorCodes.TokenInvalid, "无效的用户身份"))
            {
                StatusCode = StatusCodes.Status401Unauthorized
            };
            return;
        }

        // 获取权限服务
        var permissionService = context.HttpContext.RequestServices.GetRequiredService<IPermissionService>();

        // 检查权限
        var hasPermission = await permissionService.HasPermissionAsync(userId, PermissionCode);
        if (!hasPermission)
        {
            context.Result = new JsonResult(ApiResponse.Error(AdminErrorCodes.PermissionDenied, "没有操作权限"))
            {
                StatusCode = StatusCodes.Status403Forbidden
            };
        }
    }
}
