using UnityEditor;
using UnityEngine;
using System.Linq;
using System.Collections.Generic;

namespace XenseAR
{
    [CustomEditor(typeof(AssetbundleAnchorEditor))]
    [CanEditMultipleObjects]

    public class AssetbundleAnchorEditorGUI : Editor
    {
        [System.Serializable]
        private class Snapshot
        {
            public AnchoringTarget target;
            public string bundleObjectName;
        }

        private Dictionary<Object, Hash128> _hashCache = new();

        private void OnEnable()
        {
            foreach (var obj in targets)
                _hashCache[obj] = ComputeSnapshotHash(obj as AssetbundleAnchorEditor);
        }

        public override void OnInspectorGUI()
        {
            bool anyUpdating = targets.Any(t =>
                (t as AssetbundleAnchorEditor)?.isUpdating == true);

            using (new EditorGUI.DisabledScope(anyUpdating))
            {
                if (anyUpdating)
                {
                    GUILayout.Button("Is Updating...");
                }
                else
                {
                    CheckForSnapshotChanges();
                    EditorGUILayout.Space();
                    DrawButtons();
                }
            }

            if (anyUpdating) Repaint();
        }

        private void CheckForSnapshotChanges()
        {
            serializedObject.Update();
            EditorGUI.BeginChangeCheck();

            DrawDefaultInspector();

            if (EditorGUI.EndChangeCheck())
            {
                serializedObject.ApplyModifiedProperties();

                foreach (var obj in targets)
                {
                    if (obj is not AssetbundleAnchorEditor editor)
                        continue;

                    var newHash = ComputeSnapshotHash(editor);
                    if (!_hashCache.TryGetValue(editor, out var oldHash) || newHash != oldHash)
                    {
                        _hashCache[editor] = newHash;
                        editor.MarkAsEdited();
                        EditorUtility.SetDirty(editor);
                    }
                }
            }
        }

        private Hash128 ComputeSnapshotHash(AssetbundleAnchorEditor editor)
        {
            if (editor == null) return new Hash128();

            Snapshot snapshot = new Snapshot
            {
                target = editor.GetTarget(),
                bundleObjectName = editor.GetBundleObjectName()
            };

            string json = JsonUtility.ToJson(snapshot);
            return Hash128.Compute(json);
        }

        private void DrawButtons()
        {
            if (targets.Length > 1)
            {
                DrawButtonMultipleTarget();
            }
            else
            {
                DrawButtonSingleTarget();
            }
        }

        private void DrawButtonMultipleTarget()
        {
            if (GUILayout.Button("Save All"))
            {
                foreach (var obj in targets)
                {
                    if (obj is AssetbundleAnchorEditor bundleEditor)
                        bundleEditor.Save();
                }
            }

            if (GUILayout.Button("Load All"))
            {
                foreach (var obj in targets)
                {
                    if (obj is AssetbundleAnchorEditor bundleEditor)
                        bundleEditor.Load();
                }
            }
        }

        private void DrawButtonSingleTarget()
        {
            AssetbundleAnchorEditor myScript = (AssetbundleAnchorEditor)target;

            if (GUILayout.Button("Save"))
                myScript.Save();

            if (GUILayout.Button("Load"))
                myScript.Load();

            if (GUILayout.Button("Remove"))
                myScript.Remove();

            if (GUILayout.Button("Fetch"))
                myScript.Fetch();
        }

    }
}
