using Jovian.EncounterSystem;
using UnityEditor;
using UnityEngine;

namespace Jovian.EncounterSystem.Editor {
    /// <summary>Id dropdown (library inherited from the owning asset's <c>library</c> field) + inline fallback + resolved preview.</summary>
    [CustomPropertyDrawer(typeof(DialogLineRef))]
    public class DialogLineRefDrawer : PropertyDrawer {
        private const string NonePlaceholder = "<none>";
        private const string EmptyLibraryPlaceholder = "<set library on the parent asset>";
        private const float PreviewHeight = 32f;

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            var idProp = property.FindPropertyRelative("id");
            var inlineProp = property.FindPropertyRelative("inlineText");
            var library = ResolveLibrary(property);

            EditorGUI.BeginProperty(position, label, property);

            var lineHeight = EditorGUIUtility.singleLineHeight;
            var spacing = EditorGUIUtility.standardVerticalSpacing;

            var idRect = new Rect(position.x, position.y, position.width, lineHeight);
            DrawIdPicker(idRect, library, idProp, label);

            var inlineRect = new Rect(
                position.x,
                position.y + lineHeight + spacing,
                position.width,
                lineHeight * 2);
            EditorGUI.PropertyField(inlineRect, inlineProp, new GUIContent("Inline"));

            var previewRect = new Rect(
                position.x,
                position.y + lineHeight + spacing + lineHeight * 2 + spacing,
                position.width,
                PreviewHeight);
            DrawPreview(previewRect, library, idProp, inlineProp);

            EditorGUI.EndProperty();
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
            var lineHeight = EditorGUIUtility.singleLineHeight;
            var spacing = EditorGUIUtility.standardVerticalSpacing;
            // id + (inline 2 lines) + preview
            return lineHeight + spacing + lineHeight * 2 + spacing + PreviewHeight;
        }

        private static DialogLineLibrary ResolveLibrary(SerializedProperty property) {
            var libraryProp = property.serializedObject.FindProperty("library");
            return libraryProp?.objectReferenceValue as DialogLineLibrary;
        }

        private static void DrawIdPicker(Rect rect, DialogLineLibrary library, SerializedProperty idProp, GUIContent label) {
            if(library == null || library.lines == null || library.lines.Count == 0) {
                using(new EditorGUI.DisabledScope(true)) {
                    EditorGUI.Popup(rect, label.text, 0, new[] { EmptyLibraryPlaceholder });
                }
                return;
            }

            var count = library.lines.Count;
            var ids = new string[count + 1];
            var names = new string[count + 1];
            ids[0] = string.Empty;
            names[0] = NonePlaceholder;

            var currentIndex = 0;
            for(int i = 0; i < count; i++) {
                var line = library.lines[i];
                var id = line?.id ?? string.Empty;
                ids[i + 1] = id;
                names[i + 1] = string.IsNullOrEmpty(id) ? $"<unnamed {i}>" : id;
                if(id == idProp.stringValue && !string.IsNullOrEmpty(id)) {
                    currentIndex = i + 1;
                }
            }

            var newIndex = EditorGUI.Popup(rect, label.text, currentIndex, names);
            if(newIndex != currentIndex) {
                idProp.stringValue = ids[newIndex];
            }
        }

        private static void DrawPreview(Rect rect, DialogLineLibrary library, SerializedProperty idProp, SerializedProperty inlineProp) {
            var id = idProp.stringValue;
            var inline = inlineProp.stringValue;

            string resolved = null;
            if(library != null && !string.IsNullOrEmpty(id)) {
                resolved = library.Resolve(id);
            }
            if(string.IsNullOrEmpty(resolved)) {
                resolved = inline;
            }

            var style = new GUIStyle(EditorStyles.helpBox) {
                fontStyle = FontStyle.Italic,
                wordWrap = true
            };
            var label = string.IsNullOrEmpty(resolved) ? "<no text will display>" : resolved;
            EditorGUI.LabelField(rect, new GUIContent("Preview: " + label), style);
        }
    }
}
