using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System;
using TMPro;

/// <summary>
/// Radial menu (decision wheel) for selecting battle actions
/// </summary>
public class BattleActionWheel : MonoBehaviour
{
    [Header("UI References")]
    public Canvas wheelCanvas;
    public GameObject wheelBackground;
    public GameObject actionButtonPrefab;
    public Transform wheelCenter;

    [Header("Wheel Settings")]
    public float wheelRadius = 100f;
    public float buttonSize = 60f;
    public float animationDuration = 0.3f;
    public AnimationCurve scaleCurve = AnimationCurve.EaseInOut(0f, 0f, 1f, 1f);

    [Header("Action Icons")]
    public Sprite moveIcon;
    public Sprite attackIcon;
    public Sprite itemIcon;
    public Sprite spellIcon;
    public Sprite runAwayIcon;
    public Sprite defendIcon;
    public Sprite waitIcon;

    [Header("Colors")]
    public Color defaultColor = Color.white;
    public Color hoverColor = Color.yellow;
    public Color disabledColor = Color.gray;

    private List<ActionButton> actionButtons = new List<ActionButton>();
    private Character currentCharacter;
    private bool isVisible = false;
    private Vector3 worldPosition;
    private Camera mainCamera;

    // Events
    public event Action<BattleActionType> OnActionSelected;
    public event Action OnWheelClosed;

    [System.Serializable]
    private class ActionButton
    {
        public GameObject buttonObject;
        public Button button;
        public Image icon;
        public TextMeshProUGUI label;
        public BattleActionType actionType;
        public bool isEnabled = true;

        public void SetEnabled(bool enabled)
        {
            isEnabled = enabled;
            button.interactable = enabled;
            icon.color = enabled ? Color.white : Color.gray;
        }

        public void SetHighlight(bool highlighted, Color normalColor, Color highlightColor)
        {
            icon.color = highlighted ? highlightColor : (isEnabled ? normalColor : Color.gray);
        }
    }

    void Awake()
    {
        mainCamera = Camera.main;
        if (wheelCanvas == null)
            wheelCanvas = GetComponentInChildren<Canvas>();

        if (wheelCanvas != null)
            wheelCanvas.worldCamera = mainCamera;

        SetVisible(false);
    }

    void Start()
    {
        InitializeWheel();
    }

    void Update()
    {
        if (isVisible)
        {
            // Update wheel position to follow character or world position
            UpdateWheelPosition();

            // Handle input for closing wheel
            if (Input.GetKeyDown(KeyCode.Escape) || Input.GetMouseButtonDown(1))
            {
                HideWheel();
            }
        }
    }

    private void InitializeWheel()
    {
        if (actionButtonPrefab == null)
        {
            Debug.LogError("BattleActionWheel: Action button prefab not assigned!");
            return;
        }

        CreateActionButtons();
    }

    private void CreateActionButtons()
    {
        // Define actions and their properties
        var actionDefinitions = new[]
        {
            new { type = BattleActionType.Attack, icon = attackIcon, label = "Attack" },
            new { type = BattleActionType.Move, icon = moveIcon, label = "Move" },
            new { type = BattleActionType.UseItem, icon = itemIcon, label = "Use Item" },
            new { type = BattleActionType.CastSpell, icon = spellIcon, label = "Cast Spell" },
            new { type = BattleActionType.Defend, icon = defendIcon, label = "Defend" },
            new { type = BattleActionType.RunAway, icon = runAwayIcon, label = "Run Away" }
        };

        int actionCount = actionDefinitions.Length;
        float angleStep = 360f / actionCount;

        for (int i = 0; i < actionCount; i++)
        {
            var actionDef = actionDefinitions[i];
            float angle = i * angleStep - 90f; // Start from top
            Vector3 position = GetPositionOnCircle(angle, wheelRadius);

            CreateActionButton(actionDef.type, actionDef.icon, actionDef.label, position, i);
        }
    }

    private void CreateActionButton(BattleActionType actionType, Sprite icon, string label, Vector3 position, int index)
    {
        GameObject buttonObj = Instantiate(actionButtonPrefab, wheelCenter);
        buttonObj.name = $"ActionButton_{actionType}";

        // Position the button
        RectTransform rectTransform = buttonObj.GetComponent<RectTransform>();
        if (rectTransform != null)
        {
            rectTransform.anchoredPosition = position;
            rectTransform.sizeDelta = Vector2.one * buttonSize;
        }

        // Get components
        Button button = buttonObj.GetComponent<Button>();
        Image iconImage = buttonObj.transform.Find("Icon")?.GetComponent<Image>();
        TextMeshProUGUI labelText = buttonObj.transform.Find("Label")?.GetComponent<TextMeshProUGUI>();

        // If components don't exist, create them
        if (iconImage == null)
        {
            GameObject iconObj = new GameObject("Icon");
            iconObj.transform.SetParent(buttonObj.transform, false);
            iconImage = iconObj.AddComponent<Image>();
            RectTransform iconRect = iconImage.GetComponent<RectTransform>();
            iconRect.anchorMin = Vector2.zero;
            iconRect.anchorMax = Vector2.one;
            iconRect.offsetMin = Vector2.zero;
            iconRect.offsetMax = Vector2.zero;
        }

        if (labelText == null)
        {
            GameObject labelObj = new GameObject("Label");
            labelObj.transform.SetParent(buttonObj.transform, false);
            labelText = labelObj.AddComponent<TextMeshProUGUI>();
            RectTransform labelRect = labelText.GetComponent<RectTransform>();
            labelRect.anchorMin = new Vector2(0f, -0.5f);
            labelRect.anchorMax = new Vector2(1f, -0.1f);
            labelRect.offsetMin = Vector2.zero;
            labelRect.offsetMax = Vector2.zero;
            labelText.text = label;
            labelText.fontSize = 12;
            labelText.alignment = TextAlignmentOptions.Center;
        }

        // Setup button
        if (icon != null && iconImage != null)
            iconImage.sprite = icon;

        if (labelText != null)
            labelText.text = label;

        // Create action button data
        ActionButton actionButton = new ActionButton
        {
            buttonObject = buttonObj,
            button = button,
            icon = iconImage,
            label = labelText,
            actionType = actionType
        };

        // Setup button events
        if (button != null)
        {
            button.onClick.AddListener(() => OnActionButtonClicked(actionType));

            // Add hover effects
            var eventTrigger = buttonObj.GetComponent<UnityEngine.EventSystems.EventTrigger>();
            if (eventTrigger == null)
                eventTrigger = buttonObj.AddComponent<UnityEngine.EventSystems.EventTrigger>();

            // Hover enter
            var pointerEnter = new UnityEngine.EventSystems.EventTrigger.Entry();
            pointerEnter.eventID = UnityEngine.EventSystems.EventTriggerType.PointerEnter;
            pointerEnter.callback.AddListener((data) => { actionButton.SetHighlight(true, defaultColor, hoverColor); });
            eventTrigger.triggers.Add(pointerEnter);

            // Hover exit
            var pointerExit = new UnityEngine.EventSystems.EventTrigger.Entry();
            pointerExit.eventID = UnityEngine.EventSystems.EventTriggerType.PointerExit;
            pointerExit.callback.AddListener((data) => { actionButton.SetHighlight(false, defaultColor, hoverColor); });
            eventTrigger.triggers.Add(pointerExit);
        }

        actionButtons.Add(actionButton);
        buttonObj.SetActive(false); // Start hidden
    }

    public void ShowWheel(Character character, Vector3 worldPos)
    {
        currentCharacter = character;
        worldPosition = worldPos;

        UpdateActionAvailability();
        SetVisible(true);
        AnimateWheelIn();

        Debug.Log($"🎯 Action wheel shown for {character.CharacterName} at {worldPos}");
    }

    public void HideWheel()
    {
        AnimateWheelOut(() =>
        {
            SetVisible(false);
            OnWheelClosed?.Invoke();
        });

        Debug.Log("🎯 Action wheel hidden");
    }

    private void UpdateActionAvailability()
    {
        if (currentCharacter == null) return;

        foreach (var actionButton in actionButtons)
        {
            bool isAvailable = IsActionAvailable(actionButton.actionType);
            actionButton.SetEnabled(isAvailable);
        }
    }

    private bool IsActionAvailable(BattleActionType actionType)
    {
        if (currentCharacter == null) return false;

        switch (actionType)
        {
            case BattleActionType.Attack:
                return currentCharacter.Weapon != null;

            case BattleActionType.Move:
                return true; // Always available

            case BattleActionType.UseItem:
                // Check if character has any items (placeholder - implement item system)
                return HasUsableItems();

            case BattleActionType.CastSpell:
                // Check if character can cast spells (placeholder - implement spell system)
                return HasSpells();

            case BattleActionType.Defend:
            case BattleActionType.RunAway:
                return true; // Usually always available

            default:
                return true;
        }
    }

    private bool HasUsableItems()
    {
        // Placeholder implementation
        // TODO: Check character's inventory for usable items
        return true; // For now, assume characters always have items
    }

    private bool HasSpells()
    {
        // Placeholder implementation
        // TODO: Check character's spell list or mana
        return true; // For now, assume characters can cast spells
    }

    private void OnActionButtonClicked(BattleActionType actionType)
    {
        Debug.Log($"🎯 Action selected: {actionType}");
        OnActionSelected?.Invoke(actionType);
        HideWheel();
    }

    private Vector3 GetPositionOnCircle(float angleDegrees, float radius)
    {
        float angleRadians = angleDegrees * Mathf.Deg2Rad;
        return new Vector3(
            Mathf.Cos(angleRadians) * radius,
            Mathf.Sin(angleRadians) * radius,
            0f
        );
    }

    private void UpdateWheelPosition()
    {
        if (wheelCanvas == null || mainCamera == null) return;

        // Convert world position to screen position, then to canvas position
        Vector3 screenPos = mainCamera.WorldToScreenPoint(worldPosition);

        if (wheelCanvas.renderMode == RenderMode.ScreenSpaceOverlay)
        {
            wheelCenter.position = screenPos;
        }
        else if (wheelCanvas.renderMode == RenderMode.ScreenSpaceCamera)
        {
            Vector2 canvasPos;
            RectTransformUtility.ScreenPointToLocalPointInRectangle(
                wheelCanvas.transform as RectTransform,
                screenPos,
                wheelCanvas.worldCamera,
                out canvasPos
            );
            wheelCenter.localPosition = canvasPos;
        }
    }

    private void SetVisible(bool visible)
    {
        isVisible = visible;
        if (wheelCanvas != null)
            wheelCanvas.gameObject.SetActive(visible);
    }

    private void AnimateWheelIn()
    {
        // Simple scale animation using Unity's built-in animation
        if (wheelCenter != null)
        {
            wheelCenter.localScale = Vector3.zero;
            StartCoroutine(AnimateScale(wheelCenter, Vector3.zero, Vector3.one, animationDuration, () =>
            {
                // Show all buttons after animation
                foreach (var button in actionButtons)
                {
                    button.buttonObject.SetActive(true);
                }
            }));
        }
    }

    private void AnimateWheelOut(Action onComplete = null)
    {
        // Hide buttons first
        foreach (var button in actionButtons)
        {
            button.buttonObject.SetActive(false);
        }

        if (wheelCenter != null)
        {
            StartCoroutine(AnimateScale(wheelCenter, Vector3.one, Vector3.zero, animationDuration * 0.5f, onComplete));
        }
        else
        {
            onComplete?.Invoke();
        }
    }

    private System.Collections.IEnumerator AnimateScale(Transform target, Vector3 from, Vector3 to, float duration, Action onComplete = null)
    {
        float elapsed = 0f;

        while (elapsed < duration)
        {
            elapsed += Time.deltaTime;
            float t = elapsed / duration;

            // Apply easing curve if available
            if (scaleCurve != null && scaleCurve.keys.Length > 0)
            {
                t = scaleCurve.Evaluate(t);
            }

            target.localScale = Vector3.Lerp(from, to, t);
            yield return null;
        }

        target.localScale = to;
        onComplete?.Invoke();
    }

    void OnDestroy()
    {
        // Clean up any running coroutines
        StopAllCoroutines();
    }
}
