using UnityEngine;
using UnityEngine.Events;
using System.Collections.Generic;
using Sirenix.OdinInspector;
using UnityEngine.EventSystems;

[DisallowMultipleComponent]
public class UXGroup : UIBehaviour
{
    [SerializeField] private bool m_AllowSwitchOff;
    [ReadOnly, SerializeField] private List<UXButton> m_Buttons = new();

    private UXButton _current;
    private readonly HashSet<UXButton> _registeredButtons = new();

    public UnityEvent<UXButton> onSelectedChanged = new();

    public bool allowSwitchOff
    {
        get => m_AllowSwitchOff;
        set
        {
            m_AllowSwitchOff = value;
            ValidateGroupState();
        }
    }

    protected override void OnDestroy()
    {
        foreach (var button in _registeredButtons)
        {
            if (button) button.IsSelected = false;
        }
        m_Buttons.Clear();
        _registeredButtons.Clear();
        base.OnDestroy();
    }

    protected override void Awake() => ValidateGroupState();

    public void RegisterButton(UXButton button)
    {
        if (!button || _registeredButtons.Contains(button)) return;

        m_Buttons.Add(button);
        _registeredButtons.Add(button);

        if (button.IsSelected)
        {
            if (_current && _current != button)
                _current.IsSelected = false;
            _current = button;
        }

        ValidateGroupState();
    }

    public void UnregisterButton(UXButton button)
    {
        if (!button || !_registeredButtons.Contains(button)) return;

        m_Buttons.Remove(button);
        _registeredButtons.Remove(button);
        button.IsSelected = false;

        if (_current == button)
            _current = null;
    }

    internal void NotifyButtonClicked(UXButton clickedButton)
    {
        if (clickedButton.IsSelected)
        {
            if (m_AllowSwitchOff)
                SetSelectedButton(null);
        }
        else
        {
            SetSelectedButton(clickedButton);
        }
    }

    private void SetSelectedButton(UXButton target)
    {
        var previous = _current;
        _current = null;

        foreach (var button in m_Buttons)
        {
            bool shouldSelect = (button == target);
            if (button.IsSelected != shouldSelect)
                button.IsSelected = shouldSelect;

            if (shouldSelect)
                _current = button;
        }

        if (previous != _current)
            onSelectedChanged?.Invoke(_current);
    }

    private void ValidateGroupState()
    {
        bool hasSelected = _current != null && _current.IsSelected;
        if (!hasSelected && m_Buttons.Count > 0 && !m_AllowSwitchOff)
            SetSelectedButton(m_Buttons[0]);
    }

    public bool AnyOtherSelected(UXButton exclusion)
    {
        foreach (var button in m_Buttons)
        {
            if (button != exclusion && button.IsSelected)
                return true;
        }
        return false;
    }
}
