using System.Text.Json;
using Microsoft.JSInterop;

namespace Bimix.UI.Shared.Services;

public class UserInfo
{
    public string FullName { get; set; } = string.Empty;
    public string Email { get; set; } = string.Empty;
    public string AvatarUrl { get; set; } = string.Empty;
}
public class AuthService
{
    private readonly IJSRuntime _jsRuntime;
    private bool? _isAuthenticated;
    private UserInfo? _userInfo = null;
    
    public event Action<bool>? AuthenticationStateChanged;
    
    public AuthService(IJSRuntime jsRuntime)
    {
        _jsRuntime = jsRuntime;
    }
    
    public bool IsAuthenticated => _isAuthenticated ?? false;
    public UserInfo? CurrentUser => _userInfo;
    
    public async Task<bool> CheckAuthenticationAsync()
    {
        try
        {
            var token = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", "google_token");
            var userInfoJson = await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", "user_info");
            
            _isAuthenticated = !string.IsNullOrEmpty(token);

            if (_isAuthenticated.Value && !string.IsNullOrEmpty(userInfoJson))
            {
                _userInfo = JsonSerializer.Deserialize<UserInfo>(userInfoJson);
            }
            
            Console.WriteLine($"AuthService.CheckAuthentication: token={(!string.IsNullOrEmpty(token) ? "EXISTS" : "NULL")}, isAuth={_isAuthenticated}");
            
            return _isAuthenticated.Value;
        }
        catch (Exception ex)
        {
            Console.WriteLine($"AuthService.CheckAuthentication ERROR: {ex.Message}");
            _isAuthenticated = false;
            _userInfo = null;
            return false;
        }
    }
    
    public async Task SetAuthenticationAsync(string token, UserInfo? userInfo = null)
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "google_token", token);

            if (userInfo != null)
            {
                _userInfo = userInfo;
                var userInfoJson = JsonSerializer.Serialize(userInfo);
                await _jsRuntime.InvokeVoidAsync("localStorage.setItem", "user_info", userInfoJson);
            }
            
            _isAuthenticated = true;
            Console.WriteLine($"AuthService.SetAuthentication: token saved, user={_userInfo?.Email}");
            AuthenticationStateChanged?.Invoke(true);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"AuthService.SetAuthentication ERROR: {ex.Message}");
        }
    }
    
    public async Task ClearAuthenticationAsync()
    {
        try
        {
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", "google_token");
            await _jsRuntime.InvokeVoidAsync("localStorage.removeItem", "user_info");
            _isAuthenticated = false;
            _userInfo = null;
            Console.WriteLine($"AuthService.ClearAuthentication: token and user ingfo removed");
            AuthenticationStateChanged?.Invoke(false);
        }
        catch (Exception ex)
        {
            Console.WriteLine($"AuthService.ClearAuthentication ERROR: {ex.Message}");
        }
    }
    
    public async Task<string?> GetTokenAsync()
    {
        if (_isAuthenticated != true) 
        {
            await CheckAuthenticationAsync();
        }
        
        if (_isAuthenticated != true) return null;
        
        try
        {
            return await _jsRuntime.InvokeAsync<string?>("localStorage.getItem", "google_token");
        }
        catch
        {
            return null;
        }
    }
}