using System.Security.Claims;
using Microsoft.AspNetCore.Components.Authorization;
using ZB.MOM.WW.ScadaBridge.Security;

namespace ZB.MOM.WW.ScadaBridge.CentralUI.Auth;

/// <summary>
/// Claim-lookup helpers for the Central UI. Claim types are owned
/// by <see cref="JwtTokenService"/> (the single source of truth). These helpers
/// resolve them through the <c>JwtTokenService</c> constants so a rename there
/// propagates here instead of silently breaking ten copy-pasted call sites.
/// </summary>
public static class ClaimsPrincipalExtensions
{
    /// <summary>Fallback returned when no username claim is present.</summary>
    public const string UnknownUser = "unknown";

    /// <summary>
    /// The audit username for <paramref name="principal"/>, or
    /// <see cref="UnknownUser"/> when the claim is absent.
    /// </summary>
    /// <param name="principal">The claims principal to read the username from.</param>
    /// <returns>The username claim value, or <see cref="UnknownUser"/> if absent.</returns>
    public static string GetUsername(this ClaimsPrincipal principal)
        => principal.FindFirst(JwtTokenService.UsernameClaimType)?.Value ?? UnknownUser;

    /// <summary>
    /// The display name for <paramref name="principal"/>, or <c>null</c> when
    /// the claim is absent.
    /// </summary>
    /// <param name="principal">The claims principal to read the display name from.</param>
    /// <returns>The display name claim value, or <c>null</c> if the claim is absent.</returns>
    public static string? GetDisplayName(this ClaimsPrincipal principal)
        => principal.FindFirst(JwtTokenService.DisplayNameClaimType)?.Value;

    /// <summary>
    /// Resolves the current user's audit username from the auth state provider.
    /// Replaces the <c>GetCurrentUserAsync</c> helper that was copy-pasted into
    /// ten components.
    /// </summary>
    /// <param name="authStateProvider">The Blazor authentication state provider to read from.</param>
    /// <returns>A task that resolves to the current user's audit username, or <see cref="UnknownUser"/> if not authenticated.</returns>
    public static async Task<string> GetCurrentUsernameAsync(
        this AuthenticationStateProvider authStateProvider)
    {
        var authState = await authStateProvider.GetAuthenticationStateAsync();
        return authState.User.GetUsername();
    }
}
