using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditorInternal;
using UnityEngine;
using XGame.Framework;

namespace XGame.Editor
{
    [CustomEditor(typeof(XGameConfig))]
    internal class XGameConfigInspector : UnityEditor.Editor
    {
        private SerializedProperty script;
        private SerializedProperty productName;
        /// <summary>
        /// 项目的启动Assembly GUID
        /// </summary>
        public SerializedProperty launchAssemblyGUID;
        /// <summary>
        /// 项目的启动Assembly 名字
        /// </summary>
        public SerializedProperty launchAssemblyName;

        private SerializedProperty launchSceneGUID;
        private SerializedProperty launchSceneName;
        /// <summary>
        /// 项目的启动脚本GUID
        /// </summary>
        private SerializedProperty gameLogicGUID;
        /// <summary>
        /// 项目的启动脚本名字
        /// </summary>
        private SerializedProperty gameLogicTypeName;

        private string _productName;
        private AssemblyDefinitionAsset _launchAssembly;
        private SceneAsset _launchScene;
        private MonoScript _gameLogicScript;
        private HashSet<Action> _lsApplies = new HashSet<Action>();

        private void OnEnable()
        {
            script = serializedObject.FindProperty("m_Script");
            productName = serializedObject.FindProperty("productName");
            launchAssemblyGUID = serializedObject.FindProperty("launchAssemblyGUID");
            launchAssemblyName = serializedObject.FindProperty("launchAssemblyName");
            launchSceneGUID = serializedObject.FindProperty("launchSceneGUID");
            launchSceneName = serializedObject.FindProperty("launchSceneName");
            gameLogicGUID = serializedObject.FindProperty("gameLogicGUID");
            gameLogicTypeName = serializedObject.FindProperty("gameLogicTypeName");

            _productName = productName.stringValue;
            if (string.IsNullOrEmpty(launchAssemblyGUID.stringValue))
            {
                _launchAssembly = null;
            }
            else
            {
                _launchAssembly = AssetDatabase.LoadAssetAtPath<AssemblyDefinitionAsset>(AssetDatabase.GUIDToAssetPath(launchAssemblyGUID.stringValue));
            }
            if (string.IsNullOrEmpty(launchSceneGUID.stringValue))
            {
                _launchScene = null;
            }
            else
            {
                _launchScene = AssetDatabase.LoadAssetAtPath<SceneAsset>(AssetDatabase.GUIDToAssetPath(launchSceneGUID.stringValue));
            }
            if (string.IsNullOrEmpty(gameLogicGUID.stringValue))
            {
                _gameLogicScript = null;
            }
            else
            {
                _gameLogicScript = AssetDatabase.LoadAssetAtPath<MonoScript>(AssetDatabase.GUIDToAssetPath(gameLogicGUID.stringValue));
            }
        }
        private void OnDisable()
        {
            _lsApplies.Clear();
        }
        public override void OnInspectorGUI()
        {
            serializedObject.Update();

            EditorGUILayout.BeginVertical();
            {
                DrawScript();

                DrawSettings();

                DrawApply();

                serializedObject.ApplyModifiedProperties();
            }
            EditorGUILayout.EndVertical();
        }
        private void DrawScript()
        {
            EditorGUI.BeginDisabledGroup(true);
            EditorGUILayout.PropertyField(script);
            EditorGUI.EndDisabledGroup();

            GUILayout.Space(5);
        }
        private void DrawSettings()
        {
            //settings
            EditorGUILayout.BeginVertical("Box");
            {
                GUILayout.Space(5);
                GUIStyle labelStyle = new GUIStyle("Label")
                {
                    alignment = TextAnchor.MiddleLeft,
                    fontStyle = FontStyle.BoldAndItalic,
                    fontSize = 15
                };
                EditorGUILayout.LabelField(new GUIContent("Settings:"), labelStyle, GUILayout.Height(20));
                GUILayout.Space(5);


                EditorGUILayout.BeginHorizontal();
                {
                    GUILayout.Space(15);
                    EditorGUILayout.BeginVertical("Box");
                    {
                        GUILayout.Space(5);
                        _productName = EditorGUILayout.TextField(new GUIContent("Product Name", "项目名字"), _productName);
                        _launchAssembly = EditorGUILayout.ObjectField(new GUIContent("Launch Assembly", "项目的启动动态库"), _launchAssembly, typeof(AssemblyDefinitionAsset), true) as AssemblyDefinitionAsset;
                        _launchScene = EditorGUILayout.ObjectField(new GUIContent("Launch Scene", "启动场景"), _launchScene, typeof(SceneAsset), true) as SceneAsset;
                        _gameLogicScript = EditorGUILayout.ObjectField(new GUIContent("GameLogic", "启动脚本"), _gameLogicScript, typeof(MonoScript), true) as MonoScript;
                        AddApply(() => productName.stringValue = _productName);
                        AddApply(() =>
                        {
                            if (_launchAssembly != null)
                            {
                                launchAssemblyName.stringValue = _launchAssembly.name;
                                launchAssemblyGUID.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_launchAssembly));
                            }
                            else
                            {
                                launchAssemblyName.stringValue = string.Empty;
                                launchAssemblyGUID.stringValue = string.Empty;
                            }
                        });
                        AddApply(() =>
                        {
                            if (_launchScene != null)
                            {
                                launchSceneName.stringValue = _launchScene.name;
                                launchSceneGUID.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_launchScene));
                            }
                            else
                            {
                                launchSceneName.stringValue = string.Empty;
                                launchSceneGUID.stringValue = string.Empty;
                            }
                        });
                        AddApply(() =>
                        {
                            if (_gameLogicScript != null)
                            {
                                gameLogicTypeName.stringValue = _gameLogicScript.GetClass().AssemblyQualifiedName;
                                gameLogicGUID.stringValue = AssetDatabase.AssetPathToGUID(AssetDatabase.GetAssetPath(_gameLogicScript));
                            }
                            else
                            {
                                gameLogicTypeName.stringValue = string.Empty; 
                                gameLogicGUID.stringValue = string.Empty;
                            }
                        });
                    }
                    EditorGUILayout.EndVertical();
                }
                EditorGUILayout.EndHorizontal();

                GUILayout.Space(20);
            }
            EditorGUILayout.EndVertical();
        }
        private void DrawApply()
        {
            EditorGUILayout.BeginHorizontal();
            EditorGUILayout.Separator();
            if (GUILayout.Button("Apply", GUILayout.Width(50)))
            {
                DoApply();
            }
            EditorGUILayout.EndHorizontal();
        }
        private void DoApply()
        {
            foreach (var action in _lsApplies) action.Invoke();

            serializedObject.ApplyModifiedProperties();
            AssetDatabase.SaveAssets();
            AssetDatabase.Refresh();
        }

        private void AddApply(Action apply)
        {
            if (apply != null)
            {
                _lsApplies.Add(apply);
            }
        }
    }
}
