using UnityEngine;
using UnityEngine.UI;
using UVC.UI.Toolbar.Model;
using UVC.UI.ToolBar.View;

namespace UVC.UI.Toolbar.View
{
    /// <summary>
    /// 라디오 툴바 버튼(ToolbarRadioButton)의 UI 생성, 이벤트 연결, 시각적 업데이트를 처리하는 클래스입니다.
    /// IButtonViewProcessor 인터페이스를 구현하여 ToolbarView가 라디오 버튼을 일관된 방식으로 다룰 수 있도록 합니다.
    /// 라디오 버튼은 그룹 내에서 단 하나만 선택될 수 있는 특징을 가집니다.
    /// </summary>
    /// <remarks>
    /// 이 클래스의 주요 역할:
    /// 1. UI 생성: ToolbarView에 설정된 '라디오 버튼 프리팹'을 사용하여 버튼의 GameObject를 만듭니다.
    ///    이 프리팹에는 UnityEngine.UI.Toggle 컴포넌트가 포함되어 있어야 합니다.
    /// 2. 상호작용 설정:
    ///    - 생성된 토글 UI를 적절한 UnityEngine.UI.ToggleGroup에 할당합니다. (ToolbarView의 GetOrCreateToggleGroup 사용)
    ///    - UI Toggle의 상태가 변경될 때(사용자가 클릭하여 선택 시), 연결된 ToolbarRadioButton 모델의 ExecuteClick 메서드가 호출되고,
    ///      모델 및 같은 그룹 내 다른 라디오 버튼들의 IsSelected 상태가 업데이트되도록 합니다.
    /// 3. 시각적 업데이트: 버튼 모델의 상태(텍스트, 아이콘, 활성화 상태, 선택 상태 등)가 변경되면,
    ///    화면에 보이는 버튼의 모습(예: Toggle의 isOn 상태, 아이콘 변경 등)도 그에 맞게 업데이트합니다.
    /// </remarks>
    /// <example>
    /// <code>
    /// // ToolbarView 내에서 이 프로세서가 사용되는 방식 (간략화된 예시):
    /// // 1. ToolbarModel로부터 ToolbarRadioButton 객체들을 가져옵니다. (같은 GroupName을 가져야 그룹으로 묶임)
    /// // ToolbarRadioButton radioModel1 = new ToolbarRadioButton("ViewMode", "2D", true, ...);
    /// // ToolbarRadioButton radioModel2 = new ToolbarRadioButton("ViewMode", "3D", false, ...);
    /// 
    /// // 2. ToolbarView는 각 모델 타입에 맞는 Processor를 찾습니다.
    /// // IButtonViewProcessor processor = GetButtonViewProcessor(typeof(ToolbarRadioButton));
    /// 
    /// // 3. 각 라디오 버튼에 대해 UI 생성 요청
    /// // GameObject radioUI1 = processor.CreateButtonUI(radioModel1, toolbarContainer, this);
    /// // GameObject radioUI2 = processor.CreateButtonUI(radioModel2, toolbarContainer, this);
    /// 
    /// // 4. 각 라디오 버튼에 대해 상호작용 및 초기 시각적 요소 설정 요청
    /// // processor.SetupButtonInteractions(radioModel1, radioUI1, this);
    /// // processor.SetupButtonInteractions(radioModel2, radioUI2, this);
    /// // 이 과정에서 각 UI Toggle이 같은 ToggleGroup에 할당되고, 초기 isOn 상태가 설정됩니다.
    /// 
    /// // 5. 모델의 상태가 변경되거나 사용자가 UI를 클릭하면, 관련 이벤트가 발생하고
    /// //    ToolbarView는 processor의 UpdateToggleStateVisuals() 또는 UpdateCommonButtonVisuals()를 호출하여 UI를 업데이트합니다.
    /// </code>
    /// </example>
    public class ToolbarRadioButtonViewProcessor : IButtonViewProcessor
    {
        /// <summary>
        /// ToolbarRadioButton 모델에 해당하는 UI GameObject를 생성합니다.
        /// ToolbarView에 있는 radioButtonPrefab을 복제하여 사용합니다.
        /// </summary>
        /// <param name="buttonModel">UI를 생성할 기반이 되는 버튼 데이터 모델 (ToolbarRadioButton으로 간주됨).</param>
        /// <param name="parentContainer">생성된 버튼 UI가 자식으로 추가될 부모 Transform 객체입니다.</param>
        /// <param name="viewContext">현재 ToolbarView의 인스턴스. 프리팹 참조 및 ToggleGroup 관리에 사용됩니다.</param>
        /// <returns>성공적으로 생성된 버튼의 GameObject. 프리팹이 없으면 null을 반환합니다.</returns>
        public GameObject CreateButtonUI(ToolbarButtonBase buttonModel, Transform parentContainer, ToolbarView viewContext)
        {
            if (viewContext.radioButtonPrefab == null)
            {
                Debug.LogError("RadioButtonViewProcessor: radioButtonPrefab이 ToolbarView에 할당되지 않았습니다.", viewContext);
                return null;
            }
            return Object.Instantiate(viewContext.radioButtonPrefab, parentContainer);
        }

        /// <summary>
        /// 생성된 라디오 버튼 UI GameObject에 필요한 상호작용을 설정하고 초기 시각적 상태를 업데이트합니다.
        /// - UI Toggle 컴포넌트를 가져와 모델의 GroupName에 해당하는 ToggleGroup에 할당합니다.
        /// - UI Toggle의 상태 변경(onValueChanged) 시, 선택된 경우에만 모델의 ExecuteClick 메서드 호출 설정.
        /// - 모델의 초기 IsSelected 상태를 UI Toggle의 isOn 상태에 반영.
        /// - 모델의 초기 텍스트, 아이콘, 활성화 상태를 UI에 반영.
        /// </summary>
        /// <param name="buttonModel">설정 대상 버튼의 데이터 모델 (ToolbarRadioButton으로 캐스팅하여 사용).</param>
        /// <param name="buttonUIObject">화면에 표시된, 설정할 버튼의 UI GameObject.</param>
        /// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
        public void SetupButtonInteractions(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
        {
            ToolbarRadioButton radioModel = buttonModel as ToolbarRadioButton;
            if (radioModel == null) return;

            Toggle toggleComponent = buttonUIObject.GetComponent<Toggle>();
            if (toggleComponent != null)
            {
                // 모델의 GroupName을 사용하여 ToolbarView로부터 ToggleGroup을 가져오거나 생성합니다.
                // 같은 GroupName을 가진 라디오 버튼들은 이 ToggleGroup에 의해 관리됩니다.
                ToggleGroup uiToggleGroup = viewContext.GetOrCreateToggleGroup(radioModel.GroupName);
                toggleComponent.group = uiToggleGroup; // UI Toggle을 해당 그룹에 할당

                // 모델의 현재 IsSelected 상태로 UI Toggle의 초기 상태를 설정합니다.
                toggleComponent.SetIsOnWithoutNotify(radioModel.IsSelected);

                // UI Toggle의 상태가 사용자에 의해 변경될 때 호출될 리스너를 추가합니다.
                toggleComponent.onValueChanged.AddListener((isSelected) =>
                {
                    // 라디오 버튼은 선택될 때(isSelected가 true일 때)만 동작을 수행합니다.
                    // 해제될 때는 다른 라디오 버튼이 선택되면서 자동으로 해제되므로 별도 처리가 필요 없습니다.
                    if (isSelected)
                    {
                        // 사용자가 UI를 클릭하여 이 라디오 버튼을 선택하면, 모델의 ExecuteClick()을 호출합니다.
                        // ToolbarRadioButton의 ExecuteClick() 내부에서 IsSelected 상태가 true로 설정되고,
                        // 같은 그룹의 다른 라디오 버튼들은 IsSelected가 false로 설정됩니다.
                        // 이후 관련 이벤트가 발생하여 UI가 동기화됩니다.
                        // 파라미터 true는 '선택됨'을 명시적으로 나타낼 수 있으나, 모델 내부 로직에 따라 달라질 수 있습니다.
                        radioModel.ExecuteClick(true);
                    }
                });
            }
            else
            {
                Debug.LogError($"RadioButtonViewProcessor: RadioButton '{radioModel.Text}'의 GameObject에 Toggle 컴포넌트가 없습니다.", buttonUIObject);
            }
            UpdateCommonButtonVisuals(buttonModel, buttonUIObject, viewContext);
            UpdateToggleStateVisuals(radioModel, buttonUIObject, radioModel.IsSelected, viewContext);
        }

        /// <summary>
        /// 버튼 모델의 공통적인 시각적 속성(텍스트, 아이콘, 활성화 상태)이 변경되었을 때 UI를 업데이트합니다.
        /// </summary>
        public void UpdateCommonButtonVisuals(ToolbarButtonBase buttonModel, GameObject buttonUIObject, ToolbarView viewContext)
        {
            viewContext.InternalUpdateCommonButtonVisuals(buttonModel, buttonUIObject);
        }

        /// <summary>
        /// 라디오 버튼 모델의 IsSelected 상태가 변경되었을 때 UI의 시각적 표현을 업데이트합니다.
        /// UI Toggle 컴포넌트의 isOn 상태를 모델과 동기화하고, 선택 상태에 따라 아이콘을 변경합니다.
        /// </summary>
        /// <param name="toggleButtonModel">IsSelected 상태가 변경된 라디오 버튼의 모델 (ToolbarRadioButton으로 캐스팅하여 사용).</param>
        /// <param name="buttonUIObject">업데이트할 UI GameObject.</param>
        /// <param name="isSelected">모델의 새로운 IsSelected 값.</param>
        /// <param name="viewContext">현재 ToolbarView의 인스턴스.</param>
        public void UpdateToggleStateVisuals(ToolbarToggleButton toggleButtonModel, GameObject buttonUIObject, bool isSelected, ToolbarView viewContext)
        {
            // ToolbarRadioButton은 ToolbarToggleButton을 상속하므로, toggleButtonModel을 ToolbarRadioButton으로 캐스팅합니다.
            ToolbarRadioButton radioModel = toggleButtonModel as ToolbarRadioButton;
            if (radioModel == null) return;

            Toggle toggleComponent = buttonUIObject.GetComponent<Toggle>();
            if (toggleComponent != null)
            {
                if (toggleComponent.isOn != isSelected)
                {
                    toggleComponent.SetIsOnWithoutNotify(isSelected);
                }
            }
            // 공통 시각적 업데이트를 호출하여 선택 상태에 따른 아이콘 변경 등을 처리합니다.
            viewContext.InternalUpdateCommonButtonVisuals(radioModel, buttonUIObject); // 아이콘 업데이트를 위해 호출
        }
    }
}