using UnityEngine;

namespace Davanci.Nexus
{
    // Spawns the AuthorizationManager at app start. The permission flow (CMP → ATT → SDK start →
    // notifications) is started later by the splash scene, once the app is active and the brand
    // has been shown; see AuthorizationManager.BeginPermissions.
    public static class NexusBootstrap
    {
        [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
        static void Init()
        {
            // Cap the frame rate so mobile GPUs don't render past the display and drain
            // battery. Only set a default if the game hasn't chosen its own.
            if (Application.targetFrameRate <= 0)
                Application.targetFrameRate = 60;

            // Silence Debug.Log spam in release builds, logging to the device console is
            // surprisingly expensive. Warnings and errors still get through.
#if !UNITY_EDITOR
            if (!Debug.isDebugBuild)
                Debug.unityLogger.filterLogType = LogType.Warning;
#endif

            if (AuthorizationManager.Instance != null)
                return;

            // Listen for foreground events before ATT so the post-ATT dismiss callback is not missed.
            NexusAdsRetry.EnsureAlive();

            // Runs in parallel with the CMP/ATT flow so values land before ads/IAP init.
            FetchRemoteConfig();

            // Create inactive first so we can set DontDestroy before Awake runs.
            var go = new GameObject("[Nexus] AuthorizationManager");
            go.SetActive(false);
            var manager = go.AddComponent<AuthorizationManager>();
            manager.DontDestroy = true;
            go.SetActive(true);
            Object.DontDestroyOnLoad(go);

            ActivatePlayGames();
            TrySpawnCloudSaveRunner();
            InitializeIap();
            // Ads are initialized later, once the ATT prompt has resolved (see
            // AuthorizationManager.RequestAllPermissions). Initializing ads *during* the ATT
            // prompt makes the first ad requests go out with an unsettled consent/IDFA, which
            // gives flaky fill — so we wait for ATT first.
        }

        static void FetchRemoteConfig()
        {
            var cfg = NexusConfig.Load();
            if (cfg == null || !cfg.enableRemoteConfig) return;
            NexusRemoteConfig.Fetch();
        }

        // Bring up ads so a rewarded/interstitial is preloaded before the game asks. Called after
        // the ATT prompt resolves. Opt-in via NexusConfig (Ads → enable + auto-init).
        // attTrackingAuthorized: null when requestATT is off; true/false after the ATT prompt.
        public static void InitializeAds(bool? attTrackingAuthorized = null)
        {
            var cfg = NexusConfig.Load();
            if (cfg == null || !cfg.enableAds || !cfg.adsAutoInitialize) return;
            NexusAds.Initialize(null, attTrackingAuthorized);
        }

        // Bring up in-app purchases at launch so prices/ownership are ready by the time the
        // store UI opens. Opt-in via NexusConfig (In-App Purchases → enable + auto-init).
        static void InitializeIap()
        {
            var cfg = NexusConfig.Load();
            if (cfg == null || !cfg.enableIap || !cfg.iapAutoInitialize) return;
            NexusIAP.Initialize(ok =>
            {
                if (!ok)
                    Debug.LogWarning("[Nexus] IAP init failed — add product IDs in Nexus Setup → Monetization " +
                        "(must match App Store Connect / Play Console exactly). Run Davanci Doctor → IAP for details.");
                else
                    Debug.LogWarning("[Nexus] IAP ready.");
            });
        }

        static void ActivatePlayGames()
        {
#if UNITY_ANDROID && DAVANCI_GPGS && !UNITY_EDITOR
            var cfg = NexusConfig.Load();
            if (cfg == null || !cfg.enableCloudSave) return;
            try { GooglePlayGames.PlayGamesPlatform.Activate(); }
            catch (System.Exception e) { Debug.LogWarning($"[Nexus] Play Games activate failed: {e.Message}"); }
#endif
        }

        // Android: defer the launch load until Play Games sign-in finishes.
        static void TrySpawnCloudSaveRunner()
        {
            var cfg = NexusConfig.Load();
            if (cfg == null || !cfg.cloudSaveAutoSync) return;

#if UNITY_ANDROID && DAVANCI_GPGS && !UNITY_EDITOR
            if (cfg.enableCloudSave)
            {
                try
                {
                    GooglePlayGames.PlayGamesPlatform.Instance.Authenticate(status =>
                    {
                        if (status != GooglePlayGames.BasicApi.SignInStatus.Success)
                            Debug.LogWarning($"[Nexus] Play Games sign-in: {status}. Cloud load will use the local mirror.");
                        SpawnCloudSaveRunnerNow();
                    });
                    return;
                }
                catch (System.Exception e)
                {
                    Debug.LogWarning($"[Nexus] Play Games authenticate failed: {e.Message}");
                }
            }
#endif
            SpawnCloudSaveRunnerNow();
        }

        static void SpawnCloudSaveRunnerNow()
        {
            if (NexusCloudSaveRunner.Instance != null) return;

            var go = new GameObject("[Nexus] CloudSaveRunner");
            go.SetActive(false);
            var runner = go.AddComponent<NexusCloudSaveRunner>();
            runner.DontDestroy = true;
            go.SetActive(true);
            Object.DontDestroyOnLoad(go);
        }
    }
}
