﻿#if UNITY_EDITOR
using JLGames.RocketDriver.Actions.Utils;
using JLGames.RocketDriver.CSharp.Utils;
using JLGames.RocketDriver.CSharp.Xml;
using UnityEditor;
using UnityEngine;

namespace JLGames.RocketDriver.Editor.Infra
{
    [CustomEditor(typeof(ExportSettings), true)]
    public class ExportSettingsEditor : UnityEditor.Editor
    {
        private SerializedProperty m_Settings;

        private ExportSettings EditorValue => serializedObject.targetObject as ExportSettings;

        private void OnEnable()
        {
            m_Settings = serializedObject.FindProperty("m_Settings");
        }

        public override void OnInspectorGUI()
        {
            AddButtons();
            base.OnInspectorGUI();
        }

        private void AddButtons()
        {
            if (GUILayout.Button("Save as XML"))
            {
                SaveAsXml();
                AssetDatabase.Refresh();
            }

            if (GUILayout.Button("Load from XML"))
            {
                LoadFromXml();
            }

            if (GUILayout.Button("Sort Asset Paths"))
            {
                SortAssetParts();
            }
        }

        private void SaveAsXml()
        {
            var selectionInfo = EditorSelectionUtil.GetSelectionFileInfo();
            if (null == selectionInfo || !selectionInfo.IsFile) return;
            var fileInfo = selectionInfo.FileInfo;
            var shortName = PathUtil.ClearExtension(fileInfo.Name);
            var targetFileName = UnityPathUtil.CombineUnityPath(fileInfo.DirectoryName, $"{shortName}.xml");
            var packageSettings = ((ExportSettings) Selection.activeObject).Settings;
            var xmlStr = XmlUtils.ToXml(packageSettings);
            TextUtil.CreateFileWithText(targetFileName, xmlStr);
        }

        private void LoadFromXml()
        {
            var selectionInfo = EditorSelectionUtil.GetSelectionFileInfo();
            if (null == selectionInfo || !selectionInfo.IsFile) return;
            var fileInfo = selectionInfo.FileInfo;
            var xmlFilePath = UnityPathUtil.CombineUnityPath(fileInfo.DirectoryName, $"{PathUtil.ClearExtension(fileInfo.Name)}.xml");
            var xmlStr = TextUtil.ReadText(xmlFilePath);
            var packageSettings = XmlUtils.FromXml<ExportPackageSettings>(xmlStr);
            UpdateProperties(packageSettings);
        }

        private void SortAssetParts()
        {
            var editorValue = EditorValue;
            foreach (var item in editorValue.Settings.Packages)
            {
                item.SortAssetPaths();
            }

            UpdateProperties(editorValue.Settings);
        }

        private void UpdateProperties(ExportPackageSettings settingsValue)
        {
            m_Settings.FindPropertyRelative("Main").stringValue = settingsValue.Main;
            var packages = m_Settings.FindPropertyRelative("Packages");
            if (null == settingsValue.Packages || settingsValue.Packages.Length == 0)
            {
                packages.arraySize = 0;
                return;
            }

            var size = settingsValue.Packages.Length;
            packages.arraySize = size;
            for (var index = 0; index < size; index++)
            {
                var package = packages.GetArrayElementAtIndex(index);
                var item = settingsValue.Packages[index];
                package.FindPropertyRelative("Name").stringValue = item.Name;
                package.FindPropertyRelative("Interactive").boolValue = item.Interactive;
                package.FindPropertyRelative("Recurse").boolValue = item.Recurse;
                package.FindPropertyRelative("IncludeDependencies").boolValue = item.IncludeDependencies;
                package.FindPropertyRelative("IncludeLibraryAssets").boolValue = item.IncludeLibraryAssets;
                package.FindPropertyRelative("ExportDir").stringValue = item.ExportDir;
                package.FindPropertyRelative("PackageName").stringValue = item.PackageName;
                package.FindPropertyRelative("PackageVersion").stringValue = item.PackageVersion;
                var assetPaths = package.FindPropertyRelative("AssetPaths");
                if (null == item.AssetPaths || item.AssetPaths.Count == 0)
                {
                    assetPaths.arraySize = 0;
                }
                else
                {
                    var pathSize = item.AssetPaths.Count;
                    assetPaths.arraySize = pathSize;
                    for (var idx = 0; idx < pathSize; idx++)
                    {
                        assetPaths.GetArrayElementAtIndex(idx).stringValue = item.AssetPaths[idx];
                    }
                }
            }

            m_Settings.serializedObject.ApplyModifiedProperties();
        }
    }
}
#endif