using Jovian.Utilities;
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEditor;
using UnityEngine;
using Object = UnityEngine.Object;
#if UNITY_EDITOR
#endif

namespace Jovian.InspectorTools {
    public enum AutoFindScope {
        Self,
        SelfAndChildren,
        SelfAndParent,
        Scene,
        Project
    }

    public class AutoFindAttribute : PropertyAttribute, IActionableAttribute {
        public readonly AutoFindScope scope;
        public readonly string filter;
        public readonly bool isPrefab;

        public AutoFindAttribute() : this(string.Empty) { }

        public AutoFindAttribute(string filter) : this(AutoFindScope.SelfAndChildren, filter) { }

        public AutoFindAttribute(AutoFindScope scope) : this(scope, string.Empty) { }

        public AutoFindAttribute(AutoFindScope scope, bool isPrefab) : this(scope, isPrefab, string.Empty) { }

        public AutoFindAttribute(AutoFindScope scope, string filter) : this(scope, false, filter) { }

        public AutoFindAttribute(AutoFindScope scope, bool isPrefab, string filter) {
            this.scope = scope;
            this.isPrefab = isPrefab;
            this.filter = filter;
        }

#if UNITY_EDITOR
        public void Trigger(SerializedProperty property) {
            Search(property, false);
        }

        public void Search(SerializedProperty property, bool autoAddIfMissing) {
            AutoFindUtil.Search(this, property, autoAddIfMissing);
        }
#endif
    }
}

#if UNITY_EDITOR
namespace Jovian.InspectorTools.Internal {
    [CustomPropertyDrawer(typeof(AutoFindAttribute))]
    public class AutoFindAttributeDrawer : PropertyDrawer {
        private GUIContent searchButtonContent;
        private GUIStyle searchButtonStyle;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            if (searchButtonStyle == null || searchButtonContent == null) {
                searchButtonStyle = new GUIStyle(GUI.skin.button);
                searchButtonStyle.padding = new RectOffset(1, 1, 1, 1);
                searchButtonStyle.imagePosition = ImagePosition.ImageOnly;
                searchButtonContent =
                    EditorGUIUtility.IconContent(EditorGUIUtility.isProSkin ? "d_Search Icon" : "Search Icon");
            }

            label = EditorGUI.BeginProperty(position, label, property);
            position = EditorGUI.PrefixLabel(position, label);

            EditorGUI.BeginChangeCheck();

            float height = Mathf.Min(20f, position.height) - 2f;

            var buttonRect = new Rect(position);
            buttonRect.width = 18f;
            buttonRect.height = height;
            buttonRect.y += 1f;
            buttonRect.x -= buttonRect.width + 2f;

            if (GUI.Button(buttonRect, searchButtonContent, searchButtonStyle)) {
                if (attribute is AutoFindAttribute autoFindAttribute) {
                    autoFindAttribute.Search(property, (Event.current.modifiers & EventModifiers.Shift) != 0);
                }
            }

            EditorGUI.PropertyField(position, property, GUIContent.none);

            int indentLevel = EditorGUI.indentLevel;
            EditorGUI.indentLevel = 0;

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

            EditorGUI.indentLevel = indentLevel;
            EditorGUI.EndProperty();
        }
    }
}
#endif
