using Jovian.EncounterSystem;
using UnityEditor;
using UnityEngine;

namespace Jovian.EncounterSystem.Editor {
    /// <summary>Table object-field + encounter dropdown picker. Changing tables clears the id.</summary>
    [CustomPropertyDrawer(typeof(EncounterLink))]
    public class EncounterLinkDrawer : PropertyDrawer {
        private const string NonePlaceholder = "<none>";
        private const string EmptyTablePlaceholder = "<select a table first>";

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            var tableProp = property.FindPropertyRelative("table");
            var idProp = property.FindPropertyRelative("internalId");

            EditorGUI.BeginProperty(position, label, property);

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

            var tableRect = new Rect(position.x, position.y, position.width, lineHeight);
            var encounterRect = new Rect(position.x, position.y + lineHeight + spacing, position.width, lineHeight);

            EditorGUI.BeginChangeCheck();
            EditorGUI.PropertyField(tableRect, tableProp, label);
            var tableChanged = EditorGUI.EndChangeCheck();

            using(new EditorGUI.IndentLevelScope()) {
                var table = tableProp.objectReferenceValue as EncounterTable;
                if(table == null || table.encounters == null || table.encounters.Count == 0) {
                    using(new EditorGUI.DisabledScope(true)) {
                        EditorGUI.Popup(encounterRect, "Encounter", 0, new[] { EmptyTablePlaceholder });
                    }
                    if(tableChanged) {
                        idProp.stringValue = string.Empty;
                    }
                }
                else {
                    DrawEncounterPicker(encounterRect, table, idProp, tableChanged);
                }
            }

            EditorGUI.EndProperty();
        }

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
            return EditorGUIUtility.singleLineHeight * 2 + EditorGUIUtility.standardVerticalSpacing;
        }

        private static void DrawEncounterPicker(Rect rect, EncounterTable table, SerializedProperty idProp, bool tableChanged) {
            var count = table.encounters.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 encounter = table.encounters[i];
                var id = encounter?.EncounterDefinition?.internalId ?? string.Empty;
                var name = encounter?.EncounterDefinition?.name;
                ids[i + 1] = id;
                names[i + 1] = string.IsNullOrEmpty(name)
                    ? $"<unnamed> ({encounter?.GetType().Name ?? "null"})"
                    : name;
                if(!tableChanged && id == idProp.stringValue && !string.IsNullOrEmpty(id)) {
                    currentIndex = i + 1;
                }
            }

            if(tableChanged) {
                idProp.stringValue = string.Empty;
                currentIndex = 0;
            }

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