#nullable enable
using System;
using System.Threading.Tasks;

namespace IGP.UnitySDK
{
    public partial class IGPRuntimeManager
    {
        private async Task<bool> TryAuthorizeOnStartupAsync()
        {
            ResetAuthorizationRuntimeState();
            SetAuthorizationState(IGPAuthorizationState.Pending);
            return await HostSessionPlatformRuntime.AuthorizeAsync();
        }

        private void ResetAuthorizationRuntimeState()
        {
            StopAuthorizationRefreshLoop();
            authorizationPipeName = string.Empty;
            authorizationBrokerToken = string.Empty;
            authorizationSessionToken = string.Empty;
            authorizationSessionExpiresAt = null;
            authorizationDeviceIdHash = string.Empty;
            authorizationGameId = 0;
            isAuthorizationRequired = false;
            lastAuthorizationFailure = null;
            authorizationFailureFallbackDismissed = false;
        }

        private void StopAuthorizationRefreshLoop()
        {
            if (authorizationRefreshCts == null)
            {
                return;
            }

            authorizationRefreshCts.Cancel();
            authorizationRefreshCts.Dispose();
            authorizationRefreshCts = null;
            authorizationRefreshTask = null;
        }

        private void ApplyAuthorizationSkipped()
        {
            isAuthorizationRequired = false;
            lastAuthorizationFailure = null;
            authorizationFailureFallbackDismissed = false;
            SetAuthorizationState(IGPAuthorizationState.Skipped);
            StopAuthorizationRefreshLoop();
        }

        private void SetAuthorizationState(IGPAuthorizationState nextState)
        {
            authorizationState = nextState;
            if (nextState != IGPAuthorizationState.Failed)
            {
                authorizationFailureFallbackDismissed = false;
            }

            var message = lastAuthorizationFailure?.message ?? string.Empty;
            if (!isDestroyed &&
                (lastPublishedAuthorizationState != nextState ||
                 lastPublishedAuthorizationRequired != isAuthorizationRequired ||
                 !string.Equals(lastPublishedAuthorizationMessage, message, StringComparison.Ordinal)))
            {
                lastPublishedAuthorizationState = nextState;
                lastPublishedAuthorizationRequired = isAuthorizationRequired;
                lastPublishedAuthorizationMessage = message;
                AuthorizationChanged?.Invoke(new IGPAuthorizationChangedEvent(
                    nextState,
                    isAuthorizationRequired,
                    message));
            }
        }
    }
}
