using System;
using System.Collections;
using System.Collections.Generic;
using AlicizaX.UI.Extension;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;


[Serializable]
public enum ButtonModeType
{
    Normal,
    Toggle
}

[ExecuteAlways]
[DisallowMultipleComponent]
public class UXButton : UXSelectable, IButton, IPointerClickHandler, ISubmitHandler
{
    #region Serialized Fields

    [SerializeField] private ButtonModeType m_Mode;
    [SerializeField] private Button.ButtonClickedEvent m_OnClick = new();
    [SerializeField] private List<TransitionData> m_ChildTransitions = new();
    [SerializeField] private UXGroup m_UXGroup;
    [SerializeField] private AudioClip hoverAudioClip;
    [SerializeField] private AudioClip clickAudioClip;
    [SerializeField] private UnityEvent<bool> m_OnValueChanged = new();

    #endregion

    #region Private Fields

    private bool m_IsDown;
    private bool m_HasExitedWhileDown;
    private bool _mTogSelected;
    private Coroutine _resetRoutine;
    private Coroutine _deferredDeselectRoutine;
    private WaitForSeconds _waitFadeDuration;

    // 静态锁（用于 normal 模式点击后的“保持 Selected”并能转移）
    private static UXButton s_LockedButton = null;

    private bool m_IsFocusLocked = false;

    private bool m_IsNavFocused = false;

    #endregion

    #region Properties

    public bool Selected
    {
        get => _mTogSelected;
        set
        {
            if ((m_Mode == ButtonModeType.Normal && value) || m_Mode == ButtonModeType.Toggle)
            {
                if (m_Mode == ButtonModeType.Toggle) _mTogSelected = !value;
                HandleClick();
            }
        }
    }

    internal bool InternalTogSelected
    {
        get => _mTogSelected;
        set
        {
            if (_mTogSelected == value) return;
            _mTogSelected = value;
            m_OnValueChanged?.Invoke(value);

            // 如果当前控件处于聚焦（由导航/SetSelected 进入），那么视觉上应保持 Selected（无论逻辑是否为 selected）。
            bool isEventSystemSelected = EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject;
            bool isFocused = m_IsNavFocused || isEventSystemSelected;

            if (m_Mode == ButtonModeType.Toggle && isFocused)
            {
                // 即使逻辑值为 false，也保持 Selected 视觉，因为焦点还在该控件上
                SetState(SelectionState.Selected);
            }
            else
            {
                // 否则按逻辑恢复 Selected / Normal
                SetState(value ? SelectionState.Selected : SelectionState.Normal);
            }
        }
    }

    public Button.ButtonClickedEvent onClick
    {
        get => m_OnClick;
        set => m_OnClick = value;
    }

    public UnityEvent<bool> onValueChanged
    {
        get => m_OnValueChanged;
        set => m_OnValueChanged = value;
    }

    #endregion

    #region Unity Lifecycle

    protected override void Awake()
    {
        base.Awake();
        // 使用基类 m_MainTransition 的 fadeDuration
        _waitFadeDuration = new WaitForSeconds(Mathf.Max(0.01f, m_MainTransition.colors.fadeDuration));
        ApplyVisualState(m_SelectionState, true);
    }

    protected override void OnDestroy()
    {
        if (_resetRoutine != null)
            StopCoroutine(_resetRoutine);
        base.OnDestroy();
    }


    public override bool IsInteractable()
    {
        return base.IsInteractable() && m_Interactable;
    }

    #endregion

    #region Static lock helper

    private static void SetLockedButton(UXButton newLocked)
    {
        if (s_LockedButton == newLocked)
            return;

        if (s_LockedButton != null)
        {
            var old = s_LockedButton;
            s_LockedButton = null;
            old.m_IsFocusLocked = false;

            if (old._mTogSelected && old.m_Mode == ButtonModeType.Toggle)
                old.SetState(SelectionState.Selected);
            else
                old.SetState(SelectionState.Normal);
        }

        if (newLocked != null)
        {
            s_LockedButton = newLocked;
            s_LockedButton.m_IsFocusLocked = true;
            s_LockedButton.SetState(SelectionState.Selected);
        }
    }

    #endregion

    #region Pointer Handlers

    public override void OnPointerDown(PointerEventData eventData)
    {
        if (!CanProcess()) return;
        m_IsDown = true;
        m_HasExitedWhileDown = false;
        SetState(SelectionState.Pressed);
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        if (!m_Interactable || eventData.button != PointerEventData.InputButton.Left)
            return;

        m_IsDown = false;

        if (m_IsFocusLocked || (_mTogSelected && m_Mode == ButtonModeType.Toggle && navigation.mode != UXNavigation.Mode.None))
        {
            SetState(SelectionState.Selected);
            return;
        }

        var newState = m_HasExitedWhileDown ? SelectionState.Normal : SelectionState.Highlighted;
        SetState(newState);
    }

    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (!CanProcessEnter()) return;
        m_HasExitedWhileDown = false;

        // 如果 toggle 模式并且聚焦（导航/或 EventSystem 选中），保持 Selected（不触发 Highlight）
        bool isEventSystemSelected = EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject;
        bool isFocused = m_IsNavFocused || isEventSystemSelected;
        if (m_Mode == ButtonModeType.Toggle && isFocused)
        {
            SetState(SelectionState.Selected);
            return;
        }

        if (navigation.mode != UXNavigation.Mode.None)
        {
            if ((m_Mode == ButtonModeType.Normal && m_IsFocusLocked) ||
                (m_Mode == ButtonModeType.Toggle && _mTogSelected))
            {
                SetState(SelectionState.Selected);
                return;
            }
        }

        if (m_IsDown) return;

        SetState(SelectionState.Highlighted);
        PlayAudio(hoverAudioClip);
    }

    public override void OnPointerExit(PointerEventData eventData)
    {
        if (!m_Interactable) return;
        if (m_IsDown)
        {
            m_HasExitedWhileDown = true;
            return;
        }

        // 聚焦时保持 Selected（不回退到 Normal）
        bool isEventSystemSelected = EventSystem.current != null && EventSystem.current.currentSelectedGameObject == gameObject;
        bool isFocused = m_IsNavFocused || isEventSystemSelected;
        if (m_Mode == ButtonModeType.Toggle && isFocused)
        {
            SetState(SelectionState.Selected);
            return;
        }

        if (navigation.mode != UXNavigation.Mode.None)
        {
            if ((m_Mode == ButtonModeType.Normal && m_IsFocusLocked) ||
                (m_Mode == ButtonModeType.Toggle && _mTogSelected))
            {
                SetState(SelectionState.Selected);
                return;
            }
        }

        SetState(_mTogSelected ? SelectionState.Selected : SelectionState.Normal);
    }

    public void OnPointerClick(PointerEventData eventData)
    {
        if (eventData.button != PointerEventData.InputButton.Left || !m_Interactable)
            return;

        PlayAudio(clickAudioClip);

        if (m_Mode == ButtonModeType.Normal)
        {
            if (navigation.mode != UXNavigation.Mode.None)
            {
                if (EventSystem.current != null)
                    EventSystem.current.SetSelectedGameObject(gameObject, eventData);

                UISystemProfilerApi.AddMarker("Button.onClick", this);
                m_OnClick?.Invoke();

                if (IsStillSelected())
                    SetLockedButton(this);
            }
            else
            {
                UISystemProfilerApi.AddMarker("Button.onClick", this);
                m_OnClick?.Invoke();
            }
        }
        else
        {
            HandleClick();

            if (navigation.mode != UXNavigation.Mode.None)
            {
                if (EventSystem.current != null)
                    EventSystem.current.SetSelectedGameObject(gameObject, eventData);

                if (IsStillSelected())
                    SetLockedButton(this);
            }
        }
    }

    #endregion

    #region Submit handling (Keyboard Submit)

    public void OnSubmit(BaseEventData eventData)
    {
        if (_resetRoutine != null)
        {
            StopCoroutine(_resetRoutine);
            _resetRoutine = null;
        }

        if (Animator)
        {
            foreach (int id in _animTriggerCache.Values)
                Animator.ResetTrigger(id);
        }

        if (EventSystem.current != null)
            EventSystem.current.SetSelectedGameObject(gameObject, eventData);

        m_IsDown = true;
        m_HasExitedWhileDown = false;
        ForceSetState(SelectionState.Pressed);

        PlayAudio(clickAudioClip);

        if (m_Mode == ButtonModeType.Toggle)
        {
            _resetRoutine = StartCoroutine(SubmitToggleDeferredRoutine());
            return;
        }

        // ① 先执行回调（可能切走焦点）
        HandleClick();

        // ② 只在“焦点仍在自己”时才锁
        if (navigation.mode != UXNavigation.Mode.None && IsStillSelected())
            SetLockedButton(this);

        if (navigation.mode != UXNavigation.Mode.None && m_Mode == ButtonModeType.Normal)
            _resetRoutine = StartCoroutine(SubmitAndLockRoutine());
        else
            _resetRoutine = StartCoroutine(ResetAfterSubmit());
    }

    #endregion

    #region Selection / Navigation handling

    public override void OnSelect(BaseEventData eventData)
    {
        base.OnSelect(eventData);

        m_IsNavFocused = true;

        if (s_LockedButton != null && s_LockedButton != this)
        {
            SetLockedButton(this);
            return;
        }

        // 聚焦时（无论逻辑是否选中），Toggle 显示 Selected
        if (m_Mode == ButtonModeType.Toggle)
        {
            SetState(SelectionState.Selected);
            return;
        }

        if (m_IsDown)
        {
            SetState(SelectionState.Pressed);
        }
        else
        {
            if (m_IsFocusLocked)
                SetState(SelectionState.Selected);
            else
                SetState(SelectionState.Highlighted);
        }
    }

    private IEnumerator DeferredDeselectCheck()
    {
        // 等一帧，保证 EventSystem 更新 currentSelectedGameObject
        yield return null;

        bool selectionIsNull = EventSystem.current == null || EventSystem.current.currentSelectedGameObject == null;

        if (selectionIsNull)
        {
            // 统一走封装入口清理锁
            SetLockedButton(null);

            // 额外保证本实例的本地标志被清掉（以防极端顺序仍然残留）
            m_IsFocusLocked = false;
        }

        _deferredDeselectRoutine = null;
    }


    public override void OnDeselect(BaseEventData eventData)
    {
        base.OnDeselect(eventData);

        m_IsNavFocused = false;

        // 停掉上一次的延迟检查（若有）
        if (_deferredDeselectRoutine != null)
        {
            StopCoroutine(_deferredDeselectRoutine);
            _deferredDeselectRoutine = null;
        }

        // 延迟一帧再判断 EventSystem.current.currentSelectedGameObject，避免读取到旧值
        _deferredDeselectRoutine = StartCoroutine(DeferredDeselectCheck());

        // 视觉状态先按原逻辑处理（立即更新视觉），协程会确保锁状态在正确时刻被清理
        if (m_Mode == ButtonModeType.Toggle)
        {
            if (_mTogSelected)
                SetState(SelectionState.Selected);
            else
                SetState(SelectionState.Normal);

            return;
        }

        if (m_Mode == ButtonModeType.Normal && _mTogSelected)
        {
            SetState(SelectionState.Selected);
            return;
        }

        SetState(SelectionState.Normal);
    }

    #endregion

    #region Coroutines for submit/reset

    private IEnumerator SubmitAndLockRoutine()
    {
        yield return _waitFadeDuration;

        m_IsDown = false;
        m_HasExitedWhileDown = false;

        if (Animator)
        {
            foreach (int id in _animTriggerCache.Values)
                Animator.ResetTrigger(id);
        }

        if (IsStillSelected())
        {
            SetLockedButton(this);
            ApplyVisualState(SelectionState.Selected, false);
        }

        _resetRoutine = null;
    }


    private IEnumerator SubmitToggleDeferredRoutine()
    {
        yield return null;
        yield return _waitFadeDuration;

        HandleClick();

        if (Animator)
        {
            foreach (int id in _animTriggerCache.Values)
                Animator.ResetTrigger(id);
        }

        m_IsDown = false;
        m_HasExitedWhileDown = false;

        bool stillFocused = IsStillSelected();
        if (stillFocused)
            SetState(SelectionState.Selected);
        else
            SetState(_mTogSelected ? SelectionState.Selected : SelectionState.Normal);

        if (navigation.mode != UXNavigation.Mode.None && stillFocused)
            SetLockedButton(this);

        _resetRoutine = null;
    }


    private IEnumerator ResetAfterSubmit()
    {
        yield return _waitFadeDuration;
        SetState(_mTogSelected ? SelectionState.Selected : SelectionState.Normal);
        _resetRoutine = null;
    }

    #endregion

    #region Utility

    private bool IsStillSelected()
    {
        if (EventSystem.current != null)
            return EventSystem.current.currentSelectedGameObject == gameObject;
        return m_IsNavFocused;
    }

    #endregion

    #region Logic

    private bool CanProcess()
    {
        return m_Interactable;
    }

    private bool CanProcessEnter()
    {
        return m_Interactable;
    }

    private void HandleClick()
    {
        if (m_Mode == ButtonModeType.Normal)
        {
            UISystemProfilerApi.AddMarker("Button.onClick", this);
            m_OnClick?.Invoke();
        }
        else if (m_UXGroup)
        {
            m_UXGroup.NotifyButtonClicked(this);
        }
        else
        {
            InternalTogSelected = !_mTogSelected;
        }
    }

    /// <summary>
    /// 设置状态的入口（使用基类 SetState）
    /// </summary>
    /// <param name="state"></param>
    private void SetState(SelectionState state)
    {
        ForceSetState(state);
        ApplyVisualState(state, true);
    }

    /// <summary>
    /// 覆盖基类的 ApplyVisualState：先由基类处理 MainTransition，再处理 child transitions（保持原逻辑）
    /// </summary>
    public override void ApplyVisualState(SelectionState state, bool instant)
    {
        // main transition 由基类处理
        base.ApplyVisualState(state, instant);

        // child transitions 保持原有处理（UXButton 特有）
        for (int i = 0; i < m_ChildTransitions.Count; i++)
            base.ApplyTransition(m_ChildTransitions[i], state, instant);
    }

    private void PlayAudio(AudioClip clip)
    {
        if (clip && UXComponentExtensionsHelper.AudioHelper != null)
            UXComponentExtensionsHelper.AudioHelper.PlayAudio(clip);
    }

    #endregion

    protected override void OnSetProperty()
    {
        base.OnSetProperty();
        ApplyVisualState(m_SelectionState, true);
    }

    public void Focus()
    {
        if (!IsInteractable())
            return;

        if (EventSystem.current != null)
        {
            EventSystem.current.SetSelectedGameObject(gameObject, new BaseEventData(EventSystem.current));
        }

        m_IsNavFocused = true;

        if ((s_LockedButton != null && s_LockedButton != this) || s_LockedButton == null)
        {
            SetLockedButton(this);
        }
    }
}
