using System;
using System.Threading.Tasks;
using CmlLib.Core.Auth;
using CmlLib.Core.Auth.Microsoft;
using XboxAuthNet.Game.Msal;
using XboxAuthNet.Game.Msal.OAuth;

namespace ModpackLauncher.Services;

/// <summary>
/// Microsoft auth wrapper. Two modes:
///   1. Custom Azure AD client ID (msalClientId set) -> MSAL flow. Requires Microsoft
///      to have approved the app for Minecraft API access.
///   2. No custom client ID (default) -> CmlLib's BuildDefault() which uses the
///      WebView2-driven Microsoft Live OAuth flow with the Xbox Live SDK client ID.
///      Doesn't require an Azure registration; works out of the box on any Win10/11
///      machine that has the WebView2 Runtime installed (preinstalled since 2021).
/// </summary>
public sealed class AuthService
{
    private readonly string _clientId;

    public AuthService(string clientId)
    {
        _clientId = clientId;
    }

    /// <summary>True when the user has provided their own Azure App Registration ID.</summary>
    public bool HasCustomClientId => !string.IsNullOrWhiteSpace(_clientId)
        && _clientId != "00000000-0000-0000-0000-000000000000";

    /// <summary>Auth is always available now (BuildDefault provides a fallback).</summary>
    public bool IsConfigured => true;

    public async Task<MSession> AuthenticateAsync()
    {
        var loginHandler = await BuildLoginHandlerAsync();
        try
        {
            return await loginHandler.AuthenticateSilently();
        }
        catch
        {
            return await loginHandler.AuthenticateInteractively();
        }
    }

    public async Task<MSession> SignInInteractivelyAsync()
    {
        var loginHandler = await BuildLoginHandlerAsync();
        return await loginHandler.AuthenticateInteractively();
    }

    public async Task<MSession?> TryAuthenticateSilentlyAsync()
    {
        try
        {
            var loginHandler = await BuildLoginHandlerAsync();
            return await loginHandler.AuthenticateSilently();
        }
        catch
        {
            return null;
        }
    }

    public async Task SignOutAsync()
    {
        try
        {
            var loginHandler = await BuildLoginHandlerAsync();
            await loginHandler.Signout();
        }
        catch
        {
            // best-effort
        }
    }

    private async Task<JELoginHandler> BuildLoginHandlerAsync()
    {
        if (HasCustomClientId)
        {
            // Custom Azure AD MSAL flow -- requires the app to be approved by Microsoft.
            var app = await MsalClientHelper.BuildApplicationWithCache(_clientId);
            return new JELoginHandlerBuilder()
                .WithOAuthProvider(new MsalCodeFlowProvider(app))
                .Build();
        }

        // Default path: WebView2 + Xbox Live SDK community client ID. No Azure registration.
        // Note: requires WebView2 Runtime on Windows (preinstalled on Win10/11 since 2021).
        return JELoginHandlerBuilder.BuildDefault();
    }
}
