using System.Collections.Concurrent;
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(IAuthenticationService authenticationService, IHttpContextAccessor httpContextAccessor) : IDashboardAsyncAuthorizationFilter
{
    private static readonly ConcurrentDictionary<string, byte> LoggedValidatedPrincipals = new();

    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)
        {
            var cookieEmail = cookieAppUser?.Email ?? string.Empty;
            var key = "hangfire_cookie:" + (string.IsNullOrWhiteSpace(cookieEmail) ? "__unknown" : cookieEmail);
            if (LoggedValidatedPrincipals.TryAdd(key, 0))
            {
                Console.WriteLine($"Hangfire: Cookie validated for user: {cookieEmail}");
            }

            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)
        {
            var jwtEmail = jwtAppUser?.Email ?? string.Empty;
            var key = "hangfire_jwt:" + (string.IsNullOrWhiteSpace(jwtEmail) ? "__unknown" : jwtEmail);
            if (LoggedValidatedPrincipals.TryAdd(key, 0))
            {
                Console.WriteLine($"Hangfire: JWT validated for user: {jwtEmail}");
            }

            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;
    }
}
