using System.Security.Claims;
using System.Net.Http.Json;
using Microsoft.AspNetCore.Components.Authorization;
using timetracker.Shared;

namespace timetracker.Client.Services;

public class HostAuthenticationStateProvider : AuthenticationStateProvider
{
    private readonly HttpClient _http;
    private static readonly ClaimsPrincipal Anonymous = new(new ClaimsIdentity());
    private ClaimsPrincipal? _currentUser;

    public HostAuthenticationStateProvider(HttpClient http)
    {
        _http = http;
    }

    public override async Task<AuthenticationState> GetAuthenticationStateAsync()
    {
        if (_currentUser != null)
        {
            return new AuthenticationState(_currentUser);
        }

        try
        {
            var response = await _http.GetAsync("api/auth/me");
            if (response.IsSuccessStatusCode)
            {
                var userInfo = await response.Content.ReadFromJsonAsync<UserInfo>();
                if (userInfo != null)
                {
                    var claims = new[]
                    {
                        new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
                        new Claim(ClaimTypes.Name, userInfo.Username),
                        new Claim("IsTenantAdmin", userInfo.IsTenantAdmin ? "true" : "false"),
                        new Claim(ClaimTypes.Role, userInfo.IsTenantAdmin ? "TenantAdmin" : "Employee")
                    };
                    var identity = new ClaimsIdentity(claims, "Cookie");
                    _currentUser = new ClaimsPrincipal(identity);
                    return new AuthenticationState(_currentUser);
                }
            }
        }
        catch
        {
            // Ignore error and fall back to anonymous (e.g. server offline or network issues)
        }

        _currentUser = Anonymous;
        return new AuthenticationState(_currentUser);
    }

    public void NotifyUserChanged(UserInfo? userInfo)
    {
        if (userInfo != null)
        {
            var claims = new[]
            {
                new Claim(ClaimTypes.NameIdentifier, userInfo.Id.ToString()),
                new Claim(ClaimTypes.Name, userInfo.Username),
                new Claim("IsTenantAdmin", userInfo.IsTenantAdmin ? "true" : "false"),
                new Claim(ClaimTypes.Role, userInfo.IsTenantAdmin ? "TenantAdmin" : "Employee")
            };
            var identity = new ClaimsIdentity(claims, "Cookie");
            _currentUser = new ClaimsPrincipal(identity);
        }
        else
        {
            _currentUser = Anonymous;
        }

        NotifyAuthenticationStateChanged(Task.FromResult(new AuthenticationState(_currentUser)));
    }
}
