using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using AOT;
using UnityEngine;

namespace FRVR
{
    public class FRVRSDK : MonoBehaviour
    {
        public const string Version = "1.0.9";
        public static bool IsInitialized { get; private set; }
        public static bool IsShutDown { get; private set; }
        private static bool _initializationRequested;
        private static FRVRSDK _sdkSingleton;
        private static AdModule _adModule;
        private static DataModule _dataModule;
        private static AnalyticsModule _analyticsModule;
        private static SocialModule _socialModule;
        private static IAPModule _iapModule;
        private static FeaturesModule _featuresModule;
        private static AuthModule _authModule;
        private static TournamentModule _tournamentModule;
        private static NotificationsModule _notificationsModule;
        private static ScoreModule _scoreModule;
        private static bool _debug;
        private static readonly List<Action> InitCallbacks = new List<Action>();
        private static Action<string> _getEntrypointDataCallback;
        private static Action<string> _getEntrypointDataErrorCallback;
        
        // Volume control properties
        private static bool _isMuted = false;
        private static float _originalVolume = 1.0f;

        public static AdModule Ad
        {
            get
            {
                EnsureSingletonExists();
                return _adModule;
            }
        }

        public static DataModule Data
        {
            get
            {
                EnsureSingletonExists();
                return _dataModule;
            }
        }

        public static AnalyticsModule Analytics
        {
            get
            {
                EnsureSingletonExists();
                return _analyticsModule;
            }
        }

        public static SocialModule Social
        {
            get
            {
                EnsureSingletonExists();
                return _socialModule;
            }
        }

        public static IAPModule IAP
        {
            get
            {
                EnsureSingletonExists();
                return _iapModule;
            }
        }

        public static FeaturesModule Features
        {
            get
            {
                EnsureSingletonExists();
                return _featuresModule;
            }
        }

        public static AuthModule Auth
        {
            get
            {
                EnsureSingletonExists();
                return _authModule;
            }
        }

        public static TournamentModule Tournament
        {
            get
            {
                EnsureSingletonExists();
                return _tournamentModule;
            }
        }

        public static NotificationsModule Notifications
        {
            get
            {
                EnsureSingletonExists();
                return _notificationsModule;
            }
        }

        public static ScoreModule Score
        {
            get
            {
                EnsureSingletonExists();
                return _scoreModule;
            }
        }

        public static bool IsAvailable
        {
            get
            {
                if (Application.isEditor)
                {
                    return true;
                }

                if (string.IsNullOrEmpty(Application.absoluteURL) || Application.platform != RuntimePlatform.WebGLPlayer)
                {
                    return false;
                }

                var host = new Uri(Application.absoluteURL).Host;
                var isLocalhost = host == "localhost" || host == "127.0.0.1" || host == "::1";

                if (isLocalhost)
                {
                    return true;
                }

                // Add your domain checks here
                return host.EndsWith("frvr.com") || host.EndsWith("dev-frvr.com");
            }
        }

        /**
         * Check if the FRVR SDK is available in the browser
         * This should be called after the SDK is loaded in index.html
         */
        public static bool IsSDKAvailable
        {
            get
            {
                if (Application.isEditor)
                {
                    return true;
                }

                if (Application.platform != RuntimePlatform.WebGLPlayer)
                {
                    return false;
                }

                // In WebGL, we can't directly check window.FRVR from C#
                // The JavaScript bridge will handle this check
                return true;
            }
        }

        /**
         * Init can be called multiple times, it will not cause any issues. Feel free to call it multiple times
         * if you need the init callback in multiple places.
         * 
         * Note: Make sure the FRVR SDK is loaded in your index.html before calling this method.
         */
        public static void Init(Action callback)
        {
            if (!Application.isEditor && Application.platform != RuntimePlatform.WebGLPlayer)
            {
                throw new Exception("FRVRSDK can be used only in Editor and WebGL builds");
            }

            if (IsInitialized)
            {
                callback();
                return;
            }

            EnsureSingletonExists();

            if (Application.isEditor)
            {
                if (!IsInitialized)
                {
                    IsInitialized = true;
                    _debug = true;
                }

                callback();
            }
            else if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                if (_initializationRequested)
                {
                    InitCallbacks.Add(callback);
                }
                else
                {
                    InitCallbacks.Add(callback);
                    _initializationRequested = true;
                    _debug = Application.absoluteURL.Contains("sdk_debug=true") || Debug.isDebugBuild;
                    InitFRVRSDK(Version);
                }
            }
        }

        public void JSLibCallback_Init()
        {
            IsInitialized = true;
            InitCallbacks.ForEach(a => a());
            InitCallbacks.Clear();
        }

        public void JSLibCallback_InitError(string errorJson)
        {
            var error = JsonUtility.FromJson<SdkError>(errorJson);
            DebugLog("SDK Initialization Error: " + error.error);
            // Don't call callbacks on error - let the developer handle the error
            InitCallbacks.Clear();
        }

        /// <summary>
        /// Signal to the FRVR tracker that the game is loaded and ready to play.
        /// </summary>
        public static void GameReady()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                GameReadySDK();
            }
            else if (Application.isEditor)
            {
                _sdkSingleton.DebugLog("Editor: Simulating GameReady");
            }
        }

        // Data module callbacks

        public void JSLibCallback_SetLocalJsonComplete(string json)
        {
            _dataModule?.HandleSetLocalJsonComplete(json);
        }

        public void JSLibCallback_GetLocalJsonComplete(string json)
        {
            _dataModule?.HandleGetLocalJsonComplete(json);
        }

        public void JSLibCallback_SetItemComplete(string json)
        {
            _dataModule?.HandleSetItemComplete(json);
        }

        public void JSLibCallback_GetItemComplete(string json)
        {
            _dataModule?.HandleGetItemComplete(json);
        }

        public void JSLibCallback_SetCloudItemComplete(string json)
        {
            _dataModule?.HandleSetCloudItemComplete(json);
        }

        public void JSLibCallback_GetCloudItemComplete(string json)
        {
            _dataModule?.HandleGetCloudItemComplete(json);
        }

        public void JSLibCallback_RemoveCloudItemComplete(string json)
        {
            _dataModule?.HandleRemoveCloudItemComplete(json);
        }

        public void JSLibCallback_RemoveCloudItemsComplete(string json)
        {
            _dataModule?.HandleRemoveCloudItemsComplete(json);
        }

        public void JSLibCallback_RemoveLocalItemComplete(string json)
        {
            _dataModule?.HandleRemoveLocalItemComplete(json);
        }

        public void JSLibCallback_RemoveLocalItemsComplete(string json)
        {
            _dataModule?.HandleRemoveLocalItemsComplete(json);
        }

        // IAP module callbacks
        public void JSLibCallback_IapPurchaseComplete(string result)
        {
            _iapModule?.HandleIapPurchaseComplete(result);
        }

        public void JSLibCallback_IapConsumePurchaseComplete(string purchaseId)
        {
            _iapModule?.HandleIapConsumePurchaseComplete(purchaseId);
        }

    public void JSLibCallback_IapGetUnconsumedPurchasesComplete(string purchasesJson)
    {
        _iapModule?.HandleIapGetUnconsumedPurchasesComplete(purchasesJson);
    }

    public void JSLibCallback_IapRestorePurchasesComplete(string purchasesJson)
    {
        _iapModule?.HandleIapRestorePurchasesComplete(purchasesJson);
    }

    // Social module callbacks
    public void JSLibCallback_ShareComplete(int result)
    {
        _socialModule?.HandleShareComplete(result);
    }

    public void JSLibCallback_InviteComplete(int result)
    {
        _socialModule?.HandleInviteComplete(result);
    }

    public void JSLibCallback_CanInviteComplete(int result)
    {
        _socialModule?.HandleCanInviteComplete(result);
    }

    // Ad module callbacks
        public void JSLibCallback_AdStarted()
        {
            _adModule?.HandleAdStarted();
        }

        public void JSLibCallback_AdError(string errorJson)
        {
            _adModule?.HandleAdError(errorJson);
        }

        public void JSLibCallback_AdFinished()
        {
            _adModule?.HandleAdFinished();
        }

        public void JSLibCallback_InterstitialAdStarted()
        {
            _adModule?.HandleInterstitialAdStarted();
        }

        public void JSLibCallback_InterstitialAdError(string errorJson)
        {
            _adModule?.HandleInterstitialAdError(errorJson);
        }

        public void JSLibCallback_InterstitialAdFinished()
        {
            _adModule?.HandleInterstitialAdFinished();
        }

        public void JSLibCallback_RewardAdStarted()
        {
            _adModule?.HandleRewardAdStarted();
        }

        public void JSLibCallback_RewardAdError(string errorJson)
        {
            _adModule?.HandleRewardAdError(errorJson);
        }

        public void JSLibCallback_RewardAdFinished()
        {
            _adModule?.HandleRewardAdFinished();
        }

        public void JSLibCallback_BannerAdComplete(int result)
        {
            _adModule?.HandleBannerAdComplete(result);
        }

        // Entrypoint callbacks
        public void JSLibCallback_GetEntrypointDataComplete(string result)
        {
            _getEntrypointDataCallback?.Invoke(result);
        }

        public void JSLibCallback_GetEntrypointDataError(string errorJson)
        {
            _getEntrypointDataErrorCallback?.Invoke(errorJson);
        }

        // Features module callbacks
        public void JSLibCallback_GetFeatureComplete(string result)
        {
            _featuresModule?.HandleGetFeatureComplete(result);
        }

        // Tournament module callbacks
        public void JSLibCallback_TournamentCreateComplete(string tournamentId)
        {
            _tournamentModule?.HandleTournamentCreateComplete(tournamentId);
        }

        public void JSLibCallback_TournamentCreateError(string errorJson)
        {
            _tournamentModule?.HandleTournamentCreateError(errorJson);
        }

        public void JSLibCallback_TournamentPostScoreComplete(int result)
        {
            _tournamentModule?.HandleTournamentPostScoreComplete();
        }

        public void JSLibCallback_TournamentPostScoreError(string errorJson)
        {
            _tournamentModule?.HandleTournamentPostScoreError(errorJson);
        }

        public void JSLibCallback_TournamentGetCurrentTournamentComplete(string tournamentJson)
        {
            _tournamentModule?.HandleTournamentGetCurrentTournamentComplete(tournamentJson);
        }

        public void JSLibCallback_TournamentGetCurrentTournamentError(string errorJson)
        {
            _tournamentModule?.HandleTournamentGetCurrentTournamentError(errorJson);
        }

        public void JSLibCallback_TournamentGetMyTournamentsComplete(string tournamentsJson)
        {
            _tournamentModule?.HandleTournamentGetMyTournamentsComplete(tournamentsJson);
        }

        public void JSLibCallback_TournamentGetMyTournamentsError(string errorJson)
        {
            _tournamentModule?.HandleTournamentGetMyTournamentsError(errorJson);
        }

        public void JSLibCallback_TournamentGetActiveTournamentsComplete(string tournamentsJson)
        {
            _tournamentModule?.HandleTournamentGetActiveTournamentsComplete(tournamentsJson);
        }

        public void JSLibCallback_TournamentGetActiveTournamentsError(string errorJson)
        {
            _tournamentModule?.HandleTournamentGetActiveTournamentsError(errorJson);
        }

        public void JSLibCallback_TournamentJoinComplete(int result)
        {
            _tournamentModule?.HandleTournamentJoinComplete();
        }

        public void JSLibCallback_TournamentJoinError(string errorJson)
        {
            _tournamentModule?.HandleTournamentJoinError(errorJson);
        }

        public void JSLibCallback_TournamentLeaveComplete(int result)
        {
            _tournamentModule?.HandleTournamentLeaveComplete();
        }

        public void JSLibCallback_TournamentLeaveError(string errorJson)
        {
            _tournamentModule?.HandleTournamentLeaveError(errorJson);
        }

        public void JSLibCallback_TournamentInvitePlayersComplete(int result)
        {
            _tournamentModule?.HandleTournamentInvitePlayersComplete();
        }

        public void JSLibCallback_TournamentInvitePlayersError(string errorJson)
        {
            _tournamentModule?.HandleTournamentInvitePlayersError(errorJson);
        }

        public void JSLibCallback_TournamentCreateOrPostScoreComplete(string resultJson)
        {
            _tournamentModule?.HandleTournamentCreateOrPostScoreComplete(resultJson);
        }

        public void JSLibCallback_TournamentCreateOrPostScoreError(string errorJson)
        {
            _tournamentModule?.HandleTournamentCreateOrPostScoreError(errorJson);
        }

        // Notifications module callbacks
        public void JSLibCallback_NotificationsCanScheduleMessagesComplete(int result)
        {
            _notificationsModule?.HandleNotificationsCanScheduleMessagesComplete(result);
        }

        public void JSLibCallback_NotificationsCanScheduleMessagesError(string errorJson)
        {
            _notificationsModule?.HandleNotificationsCanScheduleMessagesError(errorJson);
        }

        public void JSLibCallback_NotificationsSubscribeScheduleMessagesComplete(int result)
        {
            _notificationsModule?.HandleNotificationsSubscribeScheduleMessagesComplete();
        }

        public void JSLibCallback_NotificationsSubscribeScheduleMessagesError(string errorJson)
        {
            _notificationsModule?.HandleNotificationsSubscribeScheduleMessagesError(errorJson);
        }

        public void JSLibCallback_NotificationsScheduleMessageComplete(int result)
        {
            _notificationsModule?.HandleNotificationsScheduleMessageComplete();
        }

        public void JSLibCallback_NotificationsScheduleMessageError(string errorJson)
        {
            _notificationsModule?.HandleNotificationsScheduleMessageError(errorJson);
        }

        private static void EnsureSingletonExists()
        {
            if (_sdkSingleton != null)
            {
                return;
            }

            // Check if there's already a GameObject with the singleton name
            var existingSingleton = GameObject.Find("FRVRSDKSingleton");
            if (existingSingleton != null)
            {
                _sdkSingleton = existingSingleton.GetComponent<FRVRSDK>();
                if (_sdkSingleton != null)
                {
                    // Get the existing modules
                    _adModule = existingSingleton.GetComponent<AdModule>();
                    _dataModule = existingSingleton.GetComponent<DataModule>();
                    _analyticsModule = existingSingleton.GetComponent<AnalyticsModule>();
                    _socialModule = existingSingleton.GetComponent<SocialModule>();
                    _iapModule = existingSingleton.GetComponent<IAPModule>();
                    _featuresModule = existingSingleton.GetComponent<FeaturesModule>();
                    _authModule = existingSingleton.GetComponent<AuthModule>();
                    _tournamentModule = existingSingleton.GetComponent<TournamentModule>();
                    _notificationsModule = existingSingleton.GetComponent<NotificationsModule>();
                    _scoreModule = existingSingleton.GetComponent<ScoreModule>();
                    return;
                }
                else
                {
                    // Destroy the existing GameObject if it doesn't have the FRVRSDK component
                    DestroyImmediate(existingSingleton);
                }
            }

            var singletonObject = new GameObject();
            _sdkSingleton = singletonObject.AddComponent<FRVRSDK>();
            _adModule = singletonObject.AddComponent<AdModule>();
            _adModule.Init(_sdkSingleton);
            _dataModule = singletonObject.AddComponent<DataModule>();
            _dataModule.Init(_sdkSingleton);
            _analyticsModule = singletonObject.AddComponent<AnalyticsModule>();
            _analyticsModule.Init(_sdkSingleton);
            _socialModule = singletonObject.AddComponent<SocialModule>();
            _socialModule.Init(_sdkSingleton);
            _iapModule = singletonObject.AddComponent<IAPModule>();
            _iapModule.Init(_sdkSingleton);
            _featuresModule = singletonObject.AddComponent<FeaturesModule>();
            _featuresModule.Init(_sdkSingleton);
            _authModule = singletonObject.AddComponent<AuthModule>();
            _authModule.Init(_sdkSingleton);
            _tournamentModule = singletonObject.AddComponent<TournamentModule>();
            _tournamentModule.Init(_sdkSingleton);
            _notificationsModule = singletonObject.AddComponent<NotificationsModule>();
            _notificationsModule.Init(_sdkSingleton);
            _scoreModule = singletonObject.AddComponent<ScoreModule>();
            _scoreModule.Init(_sdkSingleton);

            DontDestroyOnLoad(singletonObject);
            singletonObject.name = "FRVRSDKSingleton";
        }

        public void DebugLog(string msg)
        {
            if (Application.isEditor && !_debug)
            {
                return;
            }

            if (_debug)
                Debug.Log("[FRVRSDK] " + msg);
        }

        public T WrapSDKFunc<T>(Func<T> liveFunc, Func<T> editorFunc)
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                return liveFunc();
            }

            if (Application.isEditor)
            {
                return editorFunc();
            }

            throw new Exception($"FRVRSDK unsupported platform {Application.platform}");
        }

        public void WrapSDKAction(Action liveAction, Action editorAction)
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            DebugLog("WrapSDKAction called - Platform: " + Application.platform + ", IsEditor: " + Application.isEditor);

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                DebugLog("Calling liveAction");
                liveAction();
            }
            else if (Application.isEditor)
            {
                DebugLog("Calling editorAction");
                editorAction();
            }
            else
            {
                throw new Exception($"FRVRSDK unsupported platform {Application.platform}");
            }
        }

        private void OnDestroy()
        {
            IsShutDown = true;
        }

        /// <summary>
        /// Check if external links are allowed on the current channel
        /// </summary>
        /// <returns>True if external links are allowed, false otherwise</returns>
        public static bool GetAllowExternalLinks()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                return GetAllowExternalLinksSDK();
            }

            if (Application.isEditor)
            {
                // In editor, return true by default for testing
                return true;
            }

            return false;
        }

        /// <summary>
        /// Get the channel ID from the FRVR SDK
        /// </summary>
        /// <returns>The channel ID as a string</returns>
        public static string GetChannelID()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                return GetChannelIDSDK();
            }

            if (Application.isEditor)
            {
                // In editor, return empty string by default for testing
                return "unity_editor";
            }

            return string.Empty;
        }

        /// <summary>
        /// Get entrypoint data from the FRVR SDK
        /// </summary>
        /// <param name="onSuccess">Callback with the entrypoint data as a JSON string</param>
        /// <param name="onError">Optional callback with error message</param>
        public static void GetEntrypointData(Action<string> onSuccess, Action<string> onError = null)
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            _getEntrypointDataCallback = onSuccess;
            _getEntrypointDataErrorCallback = onError;

            if (Application.platform == RuntimePlatform.WebGLPlayer)
            {
                GetEntrypointDataSDK();
            }
            else if (Application.isEditor)
            {
                onSuccess("{}");
            }
        }

        /// <summary>
        /// Mute all audio in the Unity game
        /// </summary>
        public static void MuteVolume()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (!_isMuted)
            {
                _originalVolume = AudioListener.volume;
                AudioListener.volume = 0f;
                _isMuted = true;
            }
        }

        /// <summary>
        /// Unmute all audio in the Unity game and restore previous volume level
        /// </summary>
        public static void UnmuteVolume()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            if (_isMuted)
            {
                AudioListener.volume = _originalVolume;
                _isMuted = false;
            }
        }

        /// <summary>
        /// Set the volume level for all audio in the Unity game
        /// </summary>
        /// <param name="volume">Volume level between 0.0 and 1.0</param>
        public static void SetVolume(float volume)
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            volume = Mathf.Clamp01(volume);
            AudioListener.volume = volume;
            
            // Update original volume if not muted
            if (!_isMuted)
            {
                _originalVolume = volume;
            }
        }

        /// <summary>
        /// Get the current volume level
        /// </summary>
        /// <returns>Current volume level between 0.0 and 1.0</returns>
        public static float GetVolume()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            return AudioListener.volume;
        }

        /// <summary>
        /// Check if the audio is currently muted
        /// </summary>
        /// <returns>True if audio is muted, false otherwise</returns>
        public static bool IsMuted()
        {
            if (!IsInitialized)
            {
                throw new Exception("FRVRSDK not initialized. Call FRVRSDK.Init() first.");
            }

            return _isMuted;
        }

        // WebGL SendMessage wrapper methods for volume control
        /// <summary>
        /// Public wrapper for MuteVolume() to enable WebGL SendMessage calls
        /// </summary>
        public void MuteVolumeInstance()
        {
            MuteVolume();
        }

        /// <summary>
        /// Public wrapper for UnmuteVolume() to enable WebGL SendMessage calls
        /// </summary>
        public void UnmuteVolumeInstance()
        {
            UnmuteVolume();
        }

        /// <summary>
        /// Public wrapper for SetVolume() to enable WebGL SendMessage calls
        /// </summary>
        /// <param name="volume">Volume level between 0.0 and 1.0</param>
        public void SetVolumeInstance(float volume)
        {
            SetVolume(volume);
        }

        /// <summary>
        /// Public wrapper for SetVolume() with string parameter to enable WebGL SendMessage calls
        /// </summary>
        /// <param name="volumeString">Volume level as string between 0.0 and 1.0</param>
        public void SetVolumeInstance(string volumeString)
        {
            if (float.TryParse(volumeString, out float volume))
            {
                SetVolume(volume);
            }
            else
            {
                DebugLog("Invalid volume string: " + volumeString);
            }
        }

#if UNITY_WEBGL
        [DllImport("__Internal")]
        private static extern void InitFRVRSDK(string version);

        [DllImport("__Internal")]
        private static extern void GameReadySDK();

        [DllImport("__Internal")]
        private static extern bool GetAllowExternalLinksSDK();

        [DllImport("__Internal")]
        private static extern string GetChannelIDSDK();

        [DllImport("__Internal")]
        private static extern void GetEntrypointDataSDK();
#else
        // Preventing build to fail when using another platform than WebGL
        private static void InitFRVRSDK(string version) { }
        private static void GameReadySDK() { }
        private static bool GetAllowExternalLinksSDK() { return false; }
        private static string GetChannelIDSDK() { return string.Empty; }
        private static void GetEntrypointDataSDK() { }
#endif

        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void OnRuntimeMethodLoad()
        {
            // When "Reload Domain" is disabled in Editor settings to improve startup speed,
            // static variables should be cleaned manually before every game start.
            IsInitialized = false;
            IsShutDown = false;
            InitCallbacks.Clear();
            _initializationRequested = false;
            _sdkSingleton = null;
            _adModule = null;
            _dataModule = null;
            _analyticsModule = null;
            _socialModule = null;
            _featuresModule = null;
            _authModule = null;
            _tournamentModule = null;
            _notificationsModule = null;
            _scoreModule = null;
            _debug = false;
            _getEntrypointDataCallback = null;
            _getEntrypointDataErrorCallback = null;
            _isMuted = false;
            _originalVolume = 1.0f;
            
            // Clean up any existing singleton GameObjects to prevent duplicates
            var existingSingletons = FindObjectsOfType<FRVRSDK>();
            foreach (var singleton in existingSingletons)
            {
                if (Application.isPlaying)
                {
                    Destroy(singleton.gameObject);
                }
                else
                {
                    DestroyImmediate(singleton.gameObject);
                }
            }
        }
    }

    [Serializable]
    public class SdkError
    {
        public string error;

        public override string ToString()
        {
            return $"SdkError: {error}";
        }
    }
}
