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

namespace Jovian.PopupSystem.Editor {
    [CustomPropertyDrawer(typeof(PopupCategory))]
    public sealed class PopupCategoryDrawer : PropertyDrawer {
        private static readonly string[] builtInIds = {
            "Character",
            "Item",
            "Skill",
            "General"
        };

        private const string customLabel = "Custom...";

        public override float GetPropertyHeight(SerializedProperty property, GUIContent label) {
            var idProp = FindIdProperty(property);
            if(idProp == null) {
                return EditorGUIUtility.singleLineHeight;
            }

            var currentValue = idProp.stringValue ?? "";
            var isCustom = Array.IndexOf(builtInIds, currentValue) < 0;

            // Two lines when in custom mode: dropdown + text field
            return isCustom
                ? EditorGUIUtility.singleLineHeight * 2 + 2
                : EditorGUIUtility.singleLineHeight;
        }

        public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) {
            EditorGUI.BeginProperty(position, label, property);

            var idProp = FindIdProperty(property);
            if(idProp == null) {
                EditorGUI.LabelField(position, label.text, "Cannot resolve PopupCategory id field");
                EditorGUI.EndProperty();
                return;
            }

            var currentValue = idProp.stringValue ?? "";
            var builtInIndex = Array.IndexOf(builtInIds, currentValue);
            var isCustom = builtInIndex < 0 && !string.IsNullOrEmpty(currentValue);

            // Build display options: built-in entries + "Custom..."
            var options = new List<string>(builtInIds);
            options.Add(customLabel);

            // Determine selected index
            int selectedIndex;
            if(builtInIndex >= 0) {
                selectedIndex = builtInIndex;
            }
            else {
                selectedIndex = options.Count - 1; // "Custom..."
            }

            // First line: dropdown
            var dropdownRect = new Rect(position.x, position.y, position.width, EditorGUIUtility.singleLineHeight);
            var newIndex = EditorGUI.Popup(dropdownRect, label.text, selectedIndex, options.ToArray());

            if(newIndex != selectedIndex) {
                if(newIndex < builtInIds.Length) {
                    idProp.stringValue = builtInIds[newIndex];
                }
                else {
                    // Switched to custom — seed with a placeholder if currently built-in
                    if(!isCustom) {
                        idProp.stringValue = "NewCategory";
                    }
                }
            }

            // Second line: editable text field when custom
            var finalIsCustom = newIndex >= builtInIds.Length || (newIndex == selectedIndex && isCustom);
            if(finalIsCustom) {
                var textRect = new Rect(
                    position.x + EditorGUIUtility.labelWidth + 2,
                    position.y + EditorGUIUtility.singleLineHeight + 2,
                    position.width - EditorGUIUtility.labelWidth - 2,
                    EditorGUIUtility.singleLineHeight);
                var newValue = EditorGUI.TextField(textRect, idProp.stringValue);
                if(newValue != idProp.stringValue) {
                    idProp.stringValue = newValue;
                }
            }

            EditorGUI.EndProperty();
        }

        private static SerializedProperty FindIdProperty(SerializedProperty property) {
            // readonly struct with [SerializeField] readonly string id
            // Unity serializes this as "id" directly
            var prop = property.FindPropertyRelative("id");
            if(prop != null) {
                return prop;
            }
            // Fallback: auto-property backing field pattern
            return property.FindPropertyRelative("<id>k__BackingField");
        }
    }
}
