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

namespace Jovian.PopupSystem {
    /// <summary>
    /// ScriptableObject holding all popup system configuration. Create via
    /// Assets > Create > Jovian > Popup System > Popup Settings.
    /// </summary>
    [CreateAssetMenu(fileName = "PopupSettings", menuName = "Jovian/Popup System/Popup Settings")]
    public class PopupSettings : ScriptableObject {
        [Header("General")]
        public float popupDelay = 0.4f;
        public float fadeDuration = 0.2f;
        public AnchorSide defaultAnchorSide = AnchorSide.Below;
        public float screenEdgePadding = 10f;
        public float maxPopupWidth = 400f;
        public int sortingOrder = 100;

        [Header("Follow Mouse")]
        public Vector2 followMouseOffset = new(15f, -15f);

        [Header("Input")]
        public float touchHoldDuration = 0.6f;
        public bool gamepadFocusTrigger = true;

        [Header("Element Prefabs")]
        public List<PopupElementEntry> elementPrefabs = new();

        [Header("Priority")]
        public List<CategoryPriority> categoryPriorities = new();

        [Header("Per-Category Overrides")]
        public List<CategoryDelay> categoryDelayOverrides = new();

        private Dictionary<PopupElementType, GameObject> prefabLookup;

        /// <summary>
        /// Returns the element prefab registered under the given type, or null if not found.
        /// </summary>
        public GameObject GetPrefab(PopupElementType elementType) {
            if(prefabLookup == null) {
                prefabLookup = new Dictionary<PopupElementType, GameObject>();
                foreach(var entry in elementPrefabs) {
                    if(!string.IsNullOrEmpty(entry.type.Id) && entry.prefab != null) {
                        prefabLookup[entry.type] = entry.prefab;
                    }
                }
            }
            prefabLookup.TryGetValue(elementType, out var result);
            return result;
        }

        /// <summary>
        /// Returns the configured priority for a category, or 0 if not configured.
        /// </summary>
        public int GetPriority(PopupCategory category) {
            foreach(var cp in categoryPriorities) {
                if(cp.category == category) {
                    return cp.priority;
                }
            }
            return 0;
        }

        /// <summary>
        /// Returns the configured delay override for a category, or the default popupDelay.
        /// </summary>
        public float GetDelay(PopupCategory category) {
            foreach(var cd in categoryDelayOverrides) {
                if(cd.category == category) {
                    return cd.delay;
                }
            }
            return popupDelay;
        }
    }

    [Serializable]
    public sealed class PopupElementEntry {
        public PopupElementType type;
        public GameObject prefab;
    }

    [Serializable]
    public sealed class CategoryPriority {
        public PopupCategory category;
        public int priority;
    }

    [Serializable]
    public sealed class CategoryDelay {
        public PopupCategory category;
        public float delay;
    }
}
