using Hangfire.Annotations;
using Hangfire.Dashboard;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;

namespace Fast.Shared.Logic;

public class HangfireAuthorizationFilter : IDashboardAsyncAuthorizationFilter
{
    private readonly IAuthenticationService _authenticationService;
    private readonly IHttpContextAccessor _httpContextAccessor;

    public HangfireAuthorizationFilter(IAuthenticationService authenticationService, IHttpContextAccessor httpContextAccessor)
    {
        _authenticationService = authenticationService;
        _httpContextAccessor = httpContextAccessor;
    }

    public async Task<bool> AuthorizeAsync([NotNull] DashboardContext context)
    {
        var httpContext = _httpContextAccessor.HttpContext;
        if (httpContext == null)
        {
            Console.WriteLine("Hangfire: HttpContext is null via IHttpContextAccessor.  This should not happen in a valid request context.");
            return false;
        }

        // 1. Try Cookie Authentication first
        var cookieAuthenticateResult = await _authenticationService.AuthenticateAsync(httpContext, CookieAuthenticationDefaults.AuthenticationScheme);
        var cookieAppUser = await UserSynchronizationService.FindAppUserByEntraEmailsAsync(cookieAuthenticateResult.Principal);

        if (cookieAuthenticateResult?.Succeeded == true)
        {
            Console.WriteLine($"Hangfire: Cookie validated for user: {cookieAppUser?.Email ?? string.Empty}");
            return true;
        }
        else if (cookieAuthenticateResult?.Failure != null)
        {
            Console.WriteLine($"Hangfire: Cookie authentication failed: {cookieAuthenticateResult.Failure.Message}");
        }
        else
        {
            Console.WriteLine("Hangfire: No valid cookie found.");
        }

        // 2. If cookie failed, try JWT Bearer Authentication
        var jwtAuthenticateResult = await _authenticationService.AuthenticateAsync(httpContext, JwtBearerDefaults.AuthenticationScheme);
        var jwtAppUser = await UserSynchronizationService.FindAppUserByEntraEmailsAsync(jwtAuthenticateResult.Principal);

        if (jwtAuthenticateResult?.Succeeded == true)
        {
            Console.WriteLine($"Hangfire: JWT validated for user: {jwtAppUser?.Email ?? string.Empty}");
            return true;
        }
        else if (jwtAuthenticateResult?.Failure != null)
        {
            Console.WriteLine($"Hangfire: JWT authentication failed: {jwtAuthenticateResult.Failure.Message}");
        }
        else
        {
            Console.WriteLine("Hangfire: No valid JWT token found.");
        }

        return false;
    }
}
