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

/// <summary>
/// UI界面基类
/// </summary>
public class BasePanel : MonoBehaviour
{
    /// <summary>
    /// 存储控件的字典,键为控件的完整路径,值为控件列表
    /// </summary>
    private readonly Dictionary<string, List<UIBehaviour>> controlDic = new Dictionary<string, List<UIBehaviour>>();

    /// <summary>
    /// 初始化控件字典并添加事件监听器
    /// </summary>
    protected virtual void Awake()
    {
        FindChildrenControl<Button>();
        FindChildrenControl<Image>();
        FindChildrenControl<Text>();
        FindChildrenControl<Toggle>();
        FindChildrenControl<Slider>();
        FindChildrenControl<ScrollRect>();
        FindChildrenControl<InputField>();
        FindChildrenControl<TextMeshPro>();
        FindChildrenControl<TextMeshProUGUI>();
    }

    /// <summary>
    /// 根据控件名称获取控件
    /// </summary>
    /// <typeparam name="T">控件类型</typeparam>
    /// <param name="controlName">控件名称</param>
    /// <returns>控件实例</returns>
    public T GetControl<T>(string controlName) where T : UIBehaviour
    {
        if (controlDic.ContainsKey(controlName))
        {
            for (int i = 0; i < controlDic[controlName].Count; i++)
            {
                if (controlDic[controlName][i] is T)
                {
                    return controlDic[controlName][i] as T;
                }
            }
        }
        return null;
    }

    /// <summary>
    /// 查找子控件并添加到字典中,同时添加事件监听器
    /// </summary>
    /// <typeparam name="T">控件类型</typeparam>
    private void FindChildrenControl<T>() where T : UIBehaviour
    {
        T[] controls = GetComponentsInChildren<T>(true);

        for (int i = 0; i < controls.Length; i++)
        {
            string controlPath = controls[i].gameObject.name;
            if (controlDic.ContainsKey(controlPath))
            {
                controlDic[controlPath].Add(controls[i]);
            }
            else
            {
                controlDic.Add(controlPath, new List<UIBehaviour>() { controls[i] });
            }

            if (controls[i] is Button button)
            {
                button.onClick.AddListener(() =>
                {
                    OnClick(controlPath);
                });
            }
            else if (controls[i] is Toggle toggle)
            {
                toggle.onValueChanged.AddListener((value) =>
                {
                    OnChangeToggle(controlPath, value);
                });
            }
            else if (controls[i] is Slider slider)
            {
                slider.onValueChanged.AddListener((value) =>
                {
                    OnChangeSlider(controlPath, value);
                });
            }
            else if (controls[i] is InputField inputField)
            {
                inputField.onValueChanged.AddListener((value) =>
                {
                    OnInputChange(controlPath, value);
                });
            }
        }
    }

    /// <summary>
    /// 显示当前面板
    /// </summary>
    public virtual void ShowMe()
    {
        gameObject.SetActive(true);
    }

    /// <summary>
    /// 隐藏当前面板
    /// </summary>
    public virtual void HideMe()
    {
        gameObject.SetActive(false);
    }

    /// <summary>
    /// 按钮点击事件处理
    /// </summary>
    /// <param name="btnPath">按钮的完整路径</param>
    protected virtual void OnClick(string btnPath)
    {
        // 处理按钮点击事件
    }

    /// <summary>
    /// Toggle切换事件处理
    /// </summary>
    /// <param name="togglePath">Toggle的完整路径</param>
    /// <param name="isOn">Toggle的状态</param>
    protected virtual void OnChangeToggle(string togglePath, bool isOn)
    {
        // 处理Toggle切换事件
    }

    /// <summary>
    /// Slider值变化事件处理
    /// </summary>
    /// <param name="sliderPath">Slider的完整路径</param>
    /// <param name="value">Slider的当前值</param>
    protected virtual void OnChangeSlider(string sliderPath, float value)
    {
        // 处理Slider值变化事件
    }

    /// <summary>
    /// InputField值变化事件处理
    /// </summary>
    /// <param name="inputPath">InputField的完整路径</param>
    /// <param name="value">InputField的当前值</param>
    protected virtual void OnInputChange(string inputPath, string value)
    {
        // 处理InputField值变化事件
    }
}