using System;
using System.Collections.Generic;
using System.Linq;
using Core;
using Script.Gameplay.Interface;
using Script.Gameplay.Player;
using Script.Gameplay.Facility;
using UnityEngine;
using Script.Gameplay.Input;

namespace UI
{
    // 用于显示和编辑 Facility 上的各个 IEditComponent 组件的 UI 面板
    public class PlayerEditViewer : UIBase
    {
        private PlayerEditController controller;
        private PlayerWatchModeController watchModeController;
        private IEditable editable;
        private List<IEditableComponent> components = new List<IEditableComponent>();
        private List<EditableComponentViewer> componentViewers = new List<EditableComponentViewer>();
        [SerializeField] private GameObject componentEditViewerPrefab;
        [SerializeField] private GameObject noEditableTargetPanel;
        [SerializeField] private float panelRadius = 100f;

        private InputManager inputManager;

        private void Awake()
        {
            inputManager = InputManager.Instance;
            ControllerLocator.Instance.TryGetWait<PlayerEditController>(GetPlayerEditControllerHandle);
            ControllerLocator.Instance.TryGetWait<PlayerWatchModeController>(GetPlayerWatchModeControllerHandle);
        }

        private void Start()
        {
        }

        public void OnEnterInsideWatchMode()
        {
            this.gameObject.SetActive(true);
            if (GetEditableFromController() != null)
            {
                GetEditableComponentsFromEditable();
                ClearComponentUI();
                GenerateComponentUI();
            }
            else
            {
                if (noEditableTargetPanel != null)
                {
                    noEditableTargetPanel.SetActive(true);
                }
            }
        }

        public void OnExitInsideWatchMode()
        {
            this.gameObject.SetActive(false);

            ClearComponentUI();
            if (noEditableTargetPanel != null)
            {
                noEditableTargetPanel.SetActive(false);
            }
        }

        // 获取 PlayerEditController 的回调
        private void GetPlayerEditControllerHandle(PlayerEditController editController)
        {
            controller = editController;
            //Debug.Log("PlayerEditViewer obtained PlayerEditController.");
        }

        // 获取 PlayerWatchModeController 的回调
        private void GetPlayerWatchModeControllerHandle(PlayerWatchModeController watchModeCtrl)
        {
            watchModeController = watchModeCtrl;
            watchModeController.OnEnterWatchMode += (WatchMode mode) =>
            {
                if (mode == WatchMode.Inside)
                    OnEnterInsideWatchMode();
            };
            watchModeController.OnExitWatchMode += (WatchMode mode) =>
            {
                if (mode == WatchMode.Inside)
                    OnExitInsideWatchMode();
            };
            
            //Debug.Log("PlayerEditViewer subscribed to WatchMode events.");
        }

        private IEditable GetEditableFromController()
        {
            if (controller == null)
            {
                Debug.Log($"controller is null in {nameof(PlayerEditViewer)}");
                return null;
            }

            return editable = controller.GetCurrentTarget();
        }

        private void GetEditableComponentsFromEditable()
        {
            if (editable == null)
            {
                Debug.Log($"editable is null in {nameof(PlayerEditViewer)}");
                return;
            }

            components = editable.GetEditableComponents()
                .Where(c => c != null)
                .ToList();
        }

        private void ClearComponentUI()
        {
            foreach (var viewer in componentViewers)
            {
                if (viewer != null)
                {
                    if (Application.isPlaying) Destroy(viewer.gameObject);
                    else DestroyImmediate(viewer.gameObject);
                }
            }

            componentViewers.Clear();
        }

        // 根据 components 生成 UI, 根据拥有的 IEditComponent 的数量动态生成 UI 元素。布局为环绕着面板中心排列（自适应间隔）。
        private void GenerateComponentUI()
        {
            if (components == null || components.Count == 0 || componentEditViewerPrefab == null) return;

            // 计算半径：如果有 RectTransform 就根据面板大小自适应，否则使用默认值
            float radius = panelRadius;
            var rect = GetComponent<RectTransform>();
            if (rect != null)
            {
                radius = Mathf.Min(rect.rect.width, rect.rect.height) * 0.4f;
            }

            int n = components.Count;
            float angleStep = 360f / n;

            for (int i = 0; i < n; i++)
            {
                float angleDeg = angleStep * i;
                float angleRad = Mathf.Deg2Rad * angleDeg;
                Vector2 localPos = new Vector2(Mathf.Cos(angleRad), Mathf.Sin(angleRad)) * radius;

                var go = Instantiate(componentEditViewerPrefab, transform);
                go.name = $"{componentEditViewerPrefab.name}_{i}";
                var viewer = go.GetComponent<EditableComponentViewer>();
                if (viewer != null)
                {
                    viewer.SetComponent(components[i]); // 注入此UI需要的组件数据
                    componentViewers.Add(viewer);
                }

                // 如果是 UI 元素，优先设置 RectTransform.anchoredPosition
                var childRect = go.GetComponent<RectTransform>();
                if (childRect != null)
                {
                    childRect.anchoredPosition = localPos;
                    childRect.localRotation = Quaternion.identity;
                    childRect.localScale = Vector3.one;
                }
                else
                {
                    go.transform.localPosition = new Vector3(localPos.x, localPos.y, 0f);
                    go.transform.localRotation = Quaternion.identity;
                    go.transform.localScale = Vector3.one;
                }

                // 如果预制件包含接收组件的方法（例如 SetComponent），通过 SendMessage 传递。若无则忽略。
                //go.SendMessage("SetComponent", components[i], SendMessageOptions.DontRequireReceiver);
            }
        }
    }
}