using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using System;
using UnityEngine.UI;
using TMPro;
using System.Reflection;

namespace TFramework
{
    public class BatchTool : EditorWindow
    {
        static BatchTool win;

        static Transform _root; 

        string[] _operate = new string[] { "更改UI显示优先级","替换材质" ,"规范命名","组件批处理"};
        int _currentOpIndex=0;

        private Rect _splitRect = Rect.zero;
        private float _splitterWidth = 5;
        private bool _isDrag = false;
        private float _minWidth = 60;
        private float _maxWidth = 250;
        private float _opMenuWidth = 100;
        Material _overlay;
        Material _meshPro;

        [MenuItem("TFramework/批处理")]
        private static void OpenWin()
        {
            win = GetWindow<BatchTool>();
            win.titleContent.text = "批处理工具";
            win.minSize = new Vector2(300, 500);
            win.maxSize = new Vector2(500, 500);
            win.Show();
        }

        private void OnEnable()
        {
            _overlay = AssetDatabase.LoadAssetAtPath<Material>("Assets/TFramework/Runtime/Materails/UI/Overlay.mat");
            _meshPro = AssetDatabase.LoadAssetAtPath<Material>("Assets/TFramework/Runtime/Materails/UI/OverlayMeshProUGUI.mat");

            InitComponentBatch();
        }

        private void OnGUI()
        {
            
            using(new EditorGUILayout.HorizontalScope())
            {
                EditorGUILayout.LabelField("根节点");
                _root = EditorGUILayout.ObjectField(_root, typeof(Transform), true) as Transform;
            }
            GUILayout.BeginHorizontal();
            DrawOpMenu();
            SplitterGUI();
            ExecuteOp();
            GUILayout.EndHorizontal();
            EventHandle();
        }

        void DrawOpMenu()
        {
            GUILayout.BeginVertical("PreBackground", GUILayout.Width(_opMenuWidth));
            for (int i = 0; i < _operate.Length; i++)
            {
                string style = _currentOpIndex == i ? "TV Selection" : "PrefixLabel";
                int index = i;
                if (GUILayout.Button(_operate[i],style))
                {
                    _currentOpIndex = index;
                }
            }
            GUILayout.EndVertical();
        }

        private void ExecuteOp()
        {
            switch (_operate[_currentOpIndex])
            {
                case "更改UI显示优先级":
                    ChangeUIShowPriority();
                    break;
                case "替换材质":
                    GUILayout.Label("功能暂未实现");
                    MatReplace();
                    break;
                case "规范命名":
                    GUILayout.Label("功能暂未实现");
                    break;
                case "组件批处理":
                    ComponentBatch();
                    break;
                default:
                    break;
            }
        }
        
        private void ChangeUIShowPriority()
        {
            GUILayout.BeginVertical();
            if(_root)
            {
                using(new EditorGUILayout.HorizontalScope())
                {
                    GUILayout.Label("LegacyUI预备材质");
                    _overlay = (Material)EditorGUILayout.ObjectField(_overlay, typeof(Material), true);
                }
                using (new EditorGUILayout.HorizontalScope())
                {
                    GUILayout.Label("MeshProUI预备材质");
                    _meshPro = (Material)EditorGUILayout.ObjectField(_meshPro, typeof(Material), true);
                }
                if (GUILayout.Button("开始更改"))
                {
                    Graphic[] graphics = _root.GetComponentsInChildren<Graphic>(true);
                    for (int i = 0; i < graphics.Length; i++)
                    {
                        if (graphics[i] is TextMeshProUGUI)
                            graphics[i].materialForRendering.shader = _meshPro.shader;
                        else
                        {
                            if (!graphics[i].material.name.Equals("Default UI Material")) continue;
                            graphics[i].material = _overlay;
                        }
                    }
                    EditorUtility.SetDirty(_root);
                    AssetDatabase.SaveAssets();
                    Log.Info("更改完成！");
                }
            }
            else
            {
                EditorGUILayout.LabelField("请指定一个根节点！");
            }
            GUILayout.EndVertical();
        }

        public static void MatReplace()
        {
            
        }

        private static MethodInfo _selectionAddMethod;
        private static Type _componentType;
        private static string _componentTypeFilter = "";
        private static bool _includeInactive = true;
        private static object[] _parameter = new object[1];

        public static void InitComponentBatch()
        {
            if(_selectionAddMethod==null)
            {
                MethodInfo[] methods = GlobalTool.GetTypeToCurrentDomain("UnityEditor.Selection").GetMethods(BindingFlags.Static | BindingFlags.NonPublic);
                for (int i = 0; i < methods.Length; i++)
                {
                    if(methods[i].Name=="Add")
                    {
                        ParameterInfo[] parameter = methods[i].GetParameters();
                        if(parameter!=null&&parameter.Length==1&&parameter[0].ParameterType.Name=="Object")
                        {
                            _selectionAddMethod = methods[i];
                            break;
                        }
                    }
                }
            }
        }

        public static void ComponentBatch()
        {
            EditorGUILayout.BeginVertical();
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.HelpBox("批处理[ " + (_root ? _root.name : "Root") + " ]下的[ " + (_componentType != null ? _componentType.FullName : "Component") + " ]组件！", MessageType.Info);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("筛选词条：", GUILayout.Width(120));
            _componentTypeFilter = EditorGUILayout.TextField(_componentTypeFilter);
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("组件：", GUILayout.Width(120));
            if (GUILayout.Button(_componentType != null ? _componentType.FullName : "<None>", "MiniPopup"))
            {
                GenericMenu gm = new GenericMenu();
                List<Type> types = GlobalTool.GetTypesInRunTimeAssemblies(type =>
                {
                    return type.IsSubclassOf(typeof(Component)) && type.FullName.ToLower().Contains(_componentTypeFilter.ToLower());
                });
                gm.AddItem(new GUIContent("<None>"), _componentType == null, () =>
                {
                    _componentType = null;
                });
                for (int i = 0; i < types.Count; i++)
                {
                    Type type = types[i];
                    gm.AddItem(new GUIContent(type.FullName.Replace(".", "/")), type == _componentType, () =>
                    {
                        _componentType = type;
                    });
                }
                gm.ShowAsContext();
            }
            EditorGUILayout.EndHorizontal();

            EditorGUILayout.BeginHorizontal();
            GUILayout.Label("包含未激活对象：", GUILayout.Width(120));
            _includeInactive = EditorGUILayout.Toggle(_includeInactive);
            EditorGUILayout.EndHorizontal();

            GUI.enabled = _root && _componentType != null && _selectionAddMethod != null;

            EditorGUILayout.BeginHorizontal();
            GUI.backgroundColor = Color.green;
            if (GUILayout.Button("Collect"))
            {
                Selection.activeGameObject = null;

                Component[] components = _root.transform.GetComponentsInChildren(_componentType, _includeInactive);
                for (int i = 0; i < components.Length; i++)
                {
                    _parameter[0] = components[i];
                    _selectionAddMethod.Invoke(null, _parameter);
                }
            }
            GUI.backgroundColor = Color.white;
            EditorGUILayout.EndHorizontal();

            GUI.enabled = true;

            EditorGUILayout.EndVertical();
        }

        private void SplitterGUI()
        {
            GUILayout.Box("", "PreVerticalScrollbarThumb", GUILayout.Width(_splitterWidth), GUILayout.MaxWidth(_splitterWidth), GUILayout.MinWidth(_splitterWidth), GUILayout.ExpandHeight(true));
            _splitRect = GUILayoutUtility.GetLastRect();
            EditorGUIUtility.AddCursorRect(_splitRect, MouseCursor.SplitResizeLeftRight);
        }

        private void EventHandle()
        {
            if (Event.current != null)
            {
                switch (Event.current.rawType)
                {
                    case EventType.MouseDown:
                        GUI.FocusControl(null);
                        if (_splitRect.Contains(Event.current.mousePosition))
                            _isDrag = true;
                        break;
                    case EventType.MouseDrag:
                        if (_isDrag)
                        {
                            _opMenuWidth += Event.current.delta.x;
                            if (_opMenuWidth <= _minWidth)
                                _opMenuWidth = _minWidth;
                            else if (_opMenuWidth >= _maxWidth)
                                _opMenuWidth = _maxWidth;
                            GUI.changed = true;
                        }
                        break;
                    case EventType.MouseUp:
                        _isDrag = false;
                        break;
                }
            }
        }
    }
}
