using System.Collections.Generic;
using System.Linq;

namespace UVC.UI.Toolbar.Model
{
    /// <summary>
    /// 여러 개의 ToolbarRadioButton 객체들을 하나의 그룹으로 관리합니다.
    /// 이 그룹 내에서는 오직 하나의 라디오 버튼만이 선택된(IsSelected = true) 상태를 가질 수 있도록 보장합니다.
    /// </summary>
    /// <remarks>
    /// ToolbarModel은 ToolbarRadioButton이 추가될 때 GroupName을 기준으로 이 클래스의 인스턴스를 생성하거나
    /// 기존 인스턴스를 찾아 라디오 버튼을 등록(RegisterButton)합니다.
    /// 사용자가 라디오 버튼을 클릭하면, 해당 버튼은 이 그룹의 SetSelected 메서드를 호출하여
    /// 자신을 선택 상태로 만들고 그룹 내 다른 버튼들은 선택 해제 상태로 변경합니다.
    /// </remarks>
    /// <example>
    /// <code>
    /// // 이 클래스는 주로 ToolbarModel 내부에서 사용됩니다. 개발자가 직접 생성하기보다는
    /// // ToolbarModel에 ToolbarRadioButton을 추가함으로써 간접적으로 사용됩니다.
    /// 
    /// // ToolbarModel 내부에서의 사용 흐름 (간략화된 예시)
    /// // public class ToolbarModel
    /// // {
    /// //     private Dictionary<string, ToolbarRadioButtonGroup> _radioGroups = new Dictionary<string, ToolbarRadioButtonGroup>();
    /// // 
    /// //     public void AddItem(IToolbarItem item)
    /// //     {
    /// //         if (item is ToolbarRadioButton radioButton)
    /// //         {
    /// //             if (!_radioGroups.TryGetValue(radioButton.GroupName, out var group))
    /// //             {
    /// //                 group = new ToolbarRadioButtonGroup();
    /// //                 _radioGroups.Add(radioButton.GroupName, group);
    /// //             }
    /// //             group.RegisterButton(radioButton); // 라디오 버튼을 그룹에 등록
    /// //             radioButton.RadioGroup = group;    // 버튼에 그룹 참조 설정
    /// //         }
    /// //         // ...
    /// //     }
    /// // }
    /// 
    /// // 그룹 내 버튼 선택 로직 (ToolbarRadioButton의 ExecuteClick 내부에서 호출됨)
    /// // ToolbarRadioButtonGroup cameraGroup = new ToolbarRadioButtonGroup();
    /// // ToolbarRadioButton radio1 = new ToolbarRadioButton("camera") { Text = "Cam1" };
    /// // ToolbarRadioButton radio2 = new ToolbarRadioButton("camera") { Text = "Cam2" };
    /// // 
    /// // cameraGroup.RegisterButton(radio1);
    /// // cameraGroup.RegisterButton(radio2);
    /// // radio1.RadioGroup = cameraGroup;
    /// // radio2.RadioGroup = cameraGroup;
    /// // 
    /// // // radio1을 선택 (radio1.IsSelected = true, radio2.IsSelected = false가 됨)
    /// // cameraGroup.SetSelected(radio1); 
    /// // UnityEngine.Debug.Log($"Radio1 Selected: {radio1.IsSelected}, Radio2 Selected: {radio2.IsSelected}");
    /// // 
    /// // // radio2를 선택 (radio1.IsSelected = false, radio2.IsSelected = true가 됨)
    /// // cameraGroup.SetSelected(radio2);
    /// // UnityEngine.Debug.Log($"Radio1 Selected: {radio1.IsSelected}, Radio2 Selected: {radio2.IsSelected}");
    /// </code>
    /// </example>
    public class ToolbarRadioButtonGroup
    {
        private List<ToolbarRadioButton> _buttons = new List<ToolbarRadioButton>();

        /// <summary>
        /// 현재 그룹 내에서 선택된 라디오 버튼입니다.
        /// 선택된 버튼이 없으면 null을 반환할 수 있습니다 (일반적으로 그룹은 항상 하나가 선택되도록 설계되지만, 초기 상태 등 예외 가능).
        /// </summary>
        public ToolbarRadioButton SelectedButton { get; private set; }

        /// <summary>
        /// 지정된 라디오 버튼을 이 그룹에 등록합니다.
        /// 등록된 버튼은 그룹의 선택 관리 대상이 됩니다.
        /// 버튼의 RadioGroup 속성에도 이 그룹의 참조가 설정되어야 합니다 (보통 ToolbarModel에서 처리).
        /// </summary>
        /// <param name="button">그룹에 등록할 ToolbarRadioButton입니다.</param>
        public void RegisterButton(ToolbarRadioButton button)
        {
            if (!_buttons.Contains(button))
            {
                _buttons.Add(button);
            }
        }

        /// <summary>
        /// 지정된 라디오 버튼을 그룹 내에서 선택된 상태로 설정합니다.
        /// 이전에 선택되었던 다른 버튼은 선택 해제 상태(IsSelected = false)로 변경됩니다.
        /// </summary>
        /// <param name="buttonToSelect">선택할 ToolbarRadioButton입니다. 이 버튼은 반드시 그룹에 미리 등록되어 있어야 합니다.</param>
        public void SetSelected(ToolbarRadioButton buttonToSelect)
        {
            if (buttonToSelect == null || !_buttons.Contains(buttonToSelect))
            {
                // 그룹에 등록되지 않은 버튼을 선택하려고 하면 무시하거나 경고를 로깅할 수 있습니다.
                UnityEngine.Debug.LogWarning($"SetSelected: 버튼 '{buttonToSelect?.Text}' (그룹: {buttonToSelect?.GroupName})은 현재 라디오 그룹에 등록되어 있지 않습니다.");
                return;
            }

            // 이미 선택된 버튼을 다시 클릭한 경우, 상태를 변경하지 않고 유지합니다.
            // (라디오 버튼은 일반적으로 한 번 선택되면 사용자가 직접 해제할 수 없고, 다른 버튼을 선택해야 해제됨)
            if (SelectedButton == buttonToSelect && buttonToSelect.IsSelected)
            {
                return;
            }

            SelectedButton = buttonToSelect; // 새 버튼을 선택된 버튼으로 설정
            foreach (var buttonInGroup in _buttons)
            {
                // 현재 순회 중인 버튼이 선택하려는 버튼(buttonToSelect)과 동일한지 비교하여
                // IsSelected 상태를 설정합니다.
                // 이렇게 하면 buttonToSelect만 true가 되고 나머지는 false가 됩니다.
                // IsSelected 속성의 setter는 필요한 이벤트(OnToggle, OnStateChanged 등)를 발생시킵니다.
                buttonInGroup.IsSelected = (buttonInGroup == buttonToSelect);
            }
        }

        /// <summary>
        /// 그룹에 등록된 모든 라디오 버튼의 목록을 가져옵니다.
        /// </summary>
        /// <returns>그룹 내 모든 ToolbarRadioButton의 읽기 전용 컬렉션입니다.</returns>
        public IReadOnlyList<ToolbarRadioButton> GetButtons()
        {
            return _buttons.AsReadOnly();
        }

        /// <summary>
        /// 그룹 내 버튼들의 초기 선택 상태를 설정합니다.
        /// 주로 ToolbarModel에서 라디오 버튼들을 추가한 후 호출될 수 있습니다.
        /// initialState가 true인 버튼이 있다면 해당 버튼을, 없다면 첫 번째 버튼을 선택합니다.
        /// </summary>
        internal void InitializeSelection()
        {
            if (!_buttons.Any()) return;

            ToolbarRadioButton buttonToSelectInitially = _buttons.FirstOrDefault(b => b.IsSelected);

            if (buttonToSelectInitially != null)
            {
                // initialState가 true로 설정된 버튼이 있다면, 해당 버튼으로 최종 선택 상태를 확정합니다.
                // (다른 initialState=true 버튼이 실수로 여러 개 있었을 경우를 대비하여 명확히 하나만 선택되도록 함)
                SetSelected(buttonToSelectInitially);
            }
            else
            {
                // IsSelected가 true인 버튼이 하나도 없다면, 그룹의 첫 번째 버튼을 기본으로 선택합니다.
                // (라디오 그룹은 일반적으로 항상 하나가 선택되어 있는 상태를 유지하려 함)
                SetSelected(_buttons[0]);
            }
        }
    }
}
