using System.Security.Claims;
using adas_core.Domain.Enums;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;

namespace adas_core.Authentication.Attributes;

[AttributeUsage(AttributeTargets.Method)]
public class AuthorizeRolesAttribute(PermissionEnum.RolesType type) : Attribute, IAuthorizationFilter
{
    /// <summary>
    /// Performs authorization by ensuring the current user is authenticated and has a role matching the required permission type.
    /// Responds with an unauthorized result when no user is authenticated, bypasses role checking for the AuthSome permission type,
    /// and otherwise responds with a forbid result when no user role starts with the permission type value.
    /// </summary>
    /// <param name="context">The authorization filter context providing access to the HTTP context and where the authorization result is assigned.</param>
    public void OnAuthorization(AuthorizationFilterContext context)
        {
            var user = context.HttpContext.User;
    
            if (user.Identity?.IsAuthenticated != true)
            {
                context.Result = new UnauthorizedResult();
                return;
            }
    
            var roles = user.Claims.Where(c => c.Type == ClaimTypes.Role);
    
            if (type == PermissionEnum.RolesType.AuthSome) return;
    
            var hasRequiredRole = roles.Any(r => r.Value.StartsWith(type.ToString()));
            if (!hasRequiredRole) context.Result = new ForbidResult();
        }
}