using System;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Haoliang.Core.Services;
using Haoliang.Models.Common;

namespace Haoliang.Api.Filters
{
    public class JwtAuthorizeFilter : IAuthorizationFilter
    {
        private readonly IAuthService _authService;
        private readonly IPermissionService _permissionService;

        public JwtAuthorizeFilter(IAuthService authService, IPermissionService permissionService)
        {
            _authService = authService;
            _permissionService = permissionService;
        }

        public void OnAuthorization(AuthorizationFilterContext context)
        {
            var allowAnonymous = context.ActionDescriptor.EndpointMetadata.OfType<AllowAnonymousAttribute>().Any();
            if (allowAnonymous)
                return;

            var user = context.HttpContext.Items["User"] as User;
            if (user == null)
            {
                // No user found in context, authentication failed
                context.Result = new UnauthorizedResult();
                return;
            }

            // Check if user is active
            if (!user.IsActive)
            {
                context.Result = new ForbidResult();
                return;
            }

            // Check for required permissions if specified
            var requiredPermissions = context.ActionDescriptor.EndpointMetadata
                .OfType<RequiredPermissionAttribute>()
                .FirstOrDefault();

            if (requiredPermissions != null)
            {
                var hasPermission = _permissionService.UserHasPermissionAsync(user.Id, requiredPermissions.PermissionName).Result;
                if (!hasPermission)
                {
                    context.Result = new ForbidResult();
                    return;
                }
            }
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]
    public class RequiredPermissionAttribute : Attribute
    {
        public string PermissionName { get; }

        public RequiredPermissionAttribute(string permissionName)
        {
            PermissionName = permissionName;
        }
    }

    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
    public class AllowAnonymousAttribute : Attribute
    {
    }
}