using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
namespace XenseAR {

    [CustomEditor(typeof(GltfAnchorEditor))]
    [CanEditMultipleObjects]
    public class GltfAnchorEditorGUI : Editor
    {

        [System.Serializable]
        private class Snapshot
        {
            public AnchoringTarget target;
        }

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

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

        public override void OnInspectorGUI()
        {
            bool anyUpdating = targets.Any(t =>
                (t as GltfAnchorEditor)?.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 GltfAnchorEditor 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(GltfAnchorEditor editor)
        {
            if (editor == null) return new Hash128();

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

            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 GltfAnchorEditor bundleEditor)
                        bundleEditor.Save();
                }
            }

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

        public void DrawButtonSingleTarget()
        {
            GltfAnchorEditor myScript = (GltfAnchorEditor)target;
            if (GUILayout.Button("Save"))
            {
                myScript.Save();
            }
            if (GUILayout.Button("Load"))
            {
                myScript.Load();
            }
            if (GUILayout.Button("Remove"))
            {
                myScript.Remove();
            }
            if (GUILayout.Button("Preview"))
            {
                myScript.Preview();
            }
            if (GUILayout.Button("Fetch"))
            {
                myScript.PopulateList();
            }
        }
    }
}
