using System;
using System.Collections;
using System.Linq;
using System.Reflection;
using UnityEngine;

namespace _Core
{
    internal class NGUIEventBlocker : MonoBehaviour
    {
        private static int triggerCount = 0;

        public void Awake() {
            DisableInput();
        }

        public void OnDestroy() {
            EnableInput();
        }

        internal static void EnableInput()
        {
            EnableInputCheckAndUpdate(triggerCount - 1);
        }

        internal static void DisableInput()
        {
            DisableInputCheckAndUpdate(triggerCount + 1);
        }

        private static void DisableInputCheckAndUpdate(int newVal)
        {
            if (triggerCount != newVal)
            {
                var blockerInstance = FindObjectOfType<NGUIEventBlocker>();
                if (blockerInstance != null)
                {
                    blockerInstance.StartCoroutine(blockerInstance.DelayedToggle(newVal == 0));
                }
            }

            triggerCount = newVal;
        }

        private IEnumerator DelayedToggle(bool enable)
        {
            yield return new WaitForEndOfFrame(); // 等待一帧，确保 UICamera 完成初始化
            ToggleEventSystem(enable);
        }

        private static void EnableInputCheckAndUpdate(int newVal)
        {
            ToggleEventSystem(newVal == 0);

            triggerCount = newVal;
        }

        private static void ToggleEventSystem(bool enable)
        {
            //Log.D($"Trying to {(enable ? "enable":"disable")} NGUI event system");
            var uiCameraType = FindTypeInAssemblies("UICamera");

            if (uiCameraType == null)
            {
                // Log.W("Cannot find type UICamera, NGUI event block skipped");
                return;
            }

            var currentCameraField = uiCameraType.GetField(
                "currentCamera",
                BindingFlags.Static | BindingFlags.Public
            );
            if (currentCameraField == null)
            {
                //Log.W("Cannot find field currentCamera, NGUI event block skipped");
                return;
            }

            var currentCamera = currentCameraField.GetValue(null) as Camera;
            if (currentCamera == null)
            {
                //Log.W("Cannot find camera instance currentCamera, NGUI event block skipped");
                return;
            }

            if (!currentCamera.TryGetComponent(uiCameraType, out var uiCamera))
            {
                //Log.W("Cannot find component uiCamera, NGUI event block skipped");
                return;
            }

            var ignoreAllEventsField = uiCamera.GetType().GetField("ignoreAllEvents");
            if (ignoreAllEventsField == null)
            {
                //Log.W("Cannot find field ignoreAllEventsField, NGUI event block skipped");
                return;
            }
            ignoreAllEventsField.SetValue(uiCamera, !enable);
            //Log.D($"NGUI UICamera.ignoreAllEvents is set to {!enable}");
        }

        /// <summary>
        /// 在已加载的程序集里查找指定类型名的类型。
        /// </summary>
        /// <param name="typeName">要查找的类型名。</param>
        /// <returns>找到的类型，或者 null（如果未找到）。</returns>
        private static Type FindTypeInAssemblies(string typeName)
        {
            // 首先尝试从默认程序集 Assembly-CSharp 中加载类型
            var type = Assembly.Load("Assembly-CSharp")?.GetType(typeName);

            if (type != null)
                return type;

            // 如果未找到，则在所有已加载的程序集中查找
            return AppDomain.CurrentDomain.GetAssemblies()
                .SelectMany(assembly => assembly.GetTypes())
                .FirstOrDefault(t => t.Name == typeName);
        }
    }
}
