using System.Collections;
using UnityEngine;

namespace ChillConnect
{
    public class SuperApplication : SApplication
    {
        private static SuperApplication m_instance;

        public string attribution = "organic";

        public static SuperApplication Instance
        {
            get
            {
                if (m_instance == null)
                {
                    if (IsAppQuit)
                    {
                        return null;
                    }

                    AppObjConst.ApplicationGo = new GameObject(AppObjConst.ApplicationGoName);
                    AppObjConst.ApplicationGo.SetParent(AppObjConst.FrameGo);
                    m_instance = AppObjConst.ApplicationGo.AddComponent<SuperApplication>();
                }

                return m_instance;
            }
        }

        public override void Init()
        {
            base.Init();
            if (!PlayerPrefsKit.HasKey(PrefsKeyConst.App_isNewInstall))
            {
                PlayerPrefsKit.WriteInt(PrefsKeyConst.App_isNewInstall, 1);
            }

            AppDispatcher.Instance.AddListener(AppMsg.AppManagerRegister,
                obj => { AppManagerRegister.RegisterData(); });
        }

        public override void Enable()
        {
            base.Enable();

            InitPlugin();
            InitAppSetting();

            ManagerRegister.Register();
            AppManagerRegister.Register();
            ManagerRegister.RegisterData();

            ManagerOfManager.Instance.Init();
            ModuleManager.Instance.StartUpAllModule();

            InitSettingMode();
            StartUpGameMain();
        }

        private void OnDestroy()
        {
            m_instance = null;
        }

        #region Enable

        private void InitPlugin()
        {
            DOTweenHelper.Init();
        }

        private void InitAppSetting()
        {
            if (!AppConst.UseInternalSetting) return;

            Physics.autoSimulation = true;
            Physics.autoSyncTransforms = true;
            Physics2D.simulationMode = SimulationMode2D.Script;
            Physics2D.autoSyncTransforms = true;
            Debug.unityLogger.logEnabled = AppConst.IsEnabledEngineLog;
            Debug.unityLogger.filterLogType = AppConst.EnabledFilterLogType;
            Screen.sleepTimeout = AppConst.SleepTimeoutMode;
            Application.runInBackground = AppConst.IsRunInBG;
            QualitySettings.vSyncCount = 0;
            QualitySettings.lodBias = 1;
            QualitySettings.antiAliasing = AppConst.AntiAliasing;
            Application.targetFrameRate = AppConst.LowFrameRate;
        }

        private void StartUpGameMain()
        {
            if (!IsRestart)
            {
                GameIManager.Instance.InitialMain();
            }
            else
            {
                GameIManager.Instance.EnterMain();
            }
        }

        #endregion Enable

        #region SettingMode

        private void InitSettingMode()
        {
            if (!AppConst.UseInternalSetting) return;
            InitResolutionMode();
            InitFrameRateMode();
        }

        private bool isHDMode;
        private bool isHFRMode;

        private void InitResolutionMode()
        {
            isHDMode = PlayerPrefsKit.ReadBool(PrefsKeyConst.Application_isHDMode, true);
            SetResolutionMode(isHDMode);
        }

        private void InitFrameRateMode()
        {
            isHFRMode = PlayerPrefsKit.ReadBool(PrefsKeyConst.Application_isHFRMode, true);
            SetFrameRateMode(isHFRMode);
        }

        private void SetResolutionMode(bool isHDMode)
        {
            if (isHDMode)
            {
                ScreenConst.CurrResolution.x = ScreenConst.RawResolution.x * AppConst.HDHighViewScale;
                ScreenConst.CurrResolution.y = ScreenConst.RawResolution.y * AppConst.HDHighViewScale;
            }
            else
            {
                ScreenConst.CurrResolution.x = ScreenConst.RawResolution.x * AppConst.HDLowViewScale;
                ScreenConst.CurrResolution.y = ScreenConst.RawResolution.y * AppConst.HDLowViewScale;
            }

            SetScreenResolution(ScreenConst.CurrResolution.x, ScreenConst.CurrResolution.y, true);
        }

        private void SetFrameRateMode(bool isHFRMode)
        {
            Application.targetFrameRate = isHFRMode ? AppConst.HighFrameRate : AppConst.LowFrameRate;


            QualitySettings.vSyncCount = 0;
            QualitySettings.lodBias = 1;
        }

        private void SetScreenResolution(float width, float height, bool isFullScreen)
        {
            StartCoroutine(OnSetScreenResolution(width, height, isFullScreen));
        }

        private IEnumerator OnSetScreenResolution(float width, float height, bool isFullScreen)
        {
            yield return YieldConst.WaitForEndOfFrame;
            var allCams = Camera.allCameras;
            if (allCams == null)
            {
                yield break;
            }

            foreach (var cam in allCams)
            {
                cam.enabled = false;
            }

            Screen.SetResolution((int)width, (int)height, isFullScreen);
            Screen.fullScreen = true;

            yield return YieldConst.WaitForEndOfFrame;
            if (allCams == null)
            {
                yield break;
            }

            foreach (var cam in allCams)
            {
                cam.enabled = true;
            }
        }

        #endregion SettingMode
    }
}