using System.Security.Claims;
using Blazored.LocalStorage;
using Microsoft.AspNetCore.Components.Authorization;

namespace BackOffice.Services.Authorization;

public class AuthorizationService : IAuthorizationService
{
    private const string PermissionsCacheKey = "BackOffice.Permissions";
    private readonly ILocalStorageService _localStorage;
    private readonly AuthenticationStateProvider _authenticationStateProvider;

    public AuthorizationService(
        ILocalStorageService localStorage,
        AuthenticationStateProvider authenticationStateProvider)
    {
        _localStorage = localStorage;
        _authenticationStateProvider = authenticationStateProvider;
    }

    public async Task<bool> HasPermissionAsync(string permission)
    {
        if (string.IsNullOrWhiteSpace(permission))
        {
            return true;
        }

        var cachedPermissions = await _localStorage.GetItemAsync<HashSet<string>>(PermissionsCacheKey);
        if (cachedPermissions == null || cachedPermissions.Count == 0)
        {
            // فعلاً بر اساس Role ساده تصمیم می‌گیریم تا زمانی که BFF Permission API آماده شود
            var roles = await GetUserRolesAsync();
            if (roles == null || roles.Count == 0)
            {
                return false;
            }

            // SuperAdmin: همه دسترسی‌ها
            if (roles.Any(r => string.Equals(r, "Administrator", StringComparison.OrdinalIgnoreCase)))
            {
                return true;
            }

            // Admin: اجازه دسترسی به بیشتر صفحات مدیریتی
            if (roles.Any(r => string.Equals(r, "Admin", StringComparison.OrdinalIgnoreCase)))
            {
                // فعلاً همه permissionهای UI را برای Admin آزاد می‌کنیم
                return true;
            }

            // Inspector: فقط view
            if (roles.Any(r => string.Equals(r, "Inspector", StringComparison.OrdinalIgnoreCase)))
            {
                return permission.EndsWith(".view", StringComparison.OrdinalIgnoreCase);
            }

            return false;
        }

        return cachedPermissions.Contains(permission, StringComparer.OrdinalIgnoreCase);
    }

    public async Task<string?> GetUserRoleAsync()
    {
        var roles = await GetUserRolesAsync();
        return roles?.FirstOrDefault();
    }

    public async Task<List<string>?> GetUserRolesAsync()
    {
        var authState = await _authenticationStateProvider.GetAuthenticationStateAsync();
        var user = authState.User;

        if (user.Identity is not { IsAuthenticated: true })
        {
            return null;
        }

        var roleClaims = user.FindAll(ClaimTypes.Role).Select(c => c.Value).ToList();
        return roleClaims.Count > 0 ? roleClaims : null;
    }
}

