using System;
using System.Collections.Generic;
using UnityEngine;

namespace WS
{
    [ObjectSystem]
    public class UITabChoiceUpdateSystem : UpdateSystem<UITabChoice>
    {
        public override void Update(UITabChoice self)
        {
            self.Update();
        }
    }

    ///<summary>UI切换选择组件</summary>
    public class UITabChoice : WSComponent
    {
        ///<summary>UI集合</summary>
        private List<GameObject> UIObjects;
        ///<summary>系统事件</summary>
        private UnityEngine.EventSystems.EventSystem system;
        ///<summary>回车键-回调</summary>
        private Action OnCallback;
        ///<summary>任意时候点击回车键触发回调</summary>
        private bool IsArbitrary;
        ///<summary>倒序</summary>
        private bool IsReverseOrder;

        /// <summary>初始化</summary>
        /// <param name="enterkeycallback">回车键回调</param>
        /// <param name="isarbitrary">任意时候点击回车键触发回调</param>
        /// <param name="isreverseorder">是否倒序</param>
        /// <param name="uiobjs">UI</param>
        public void Init(Action enterkeycallback, bool isarbitrary, bool isreverseorder, params GameObject[] uiobjs)
        {
            system = UnityEngine.EventSystems.EventSystem.current;
            if (UIObjects == null)
                UIObjects = new List<GameObject>();
            UIObjects.AddRange(uiobjs);
            OnCallback = enterkeycallback;
            IsArbitrary = isarbitrary;
            IsReverseOrder = isreverseorder;
            if (UIObjects.Count > 0)
                system.SetSelectedGameObject(UIObjects[0]);
        }

        public void Update()
        {
            if (UIObjects != null)
            {
                if (Input.GetKeyDown(KeyCode.Tab))
                {
                    SwitchCurrent();
                }

                if (Input.GetKeyDown(KeyCode.Return) || Input.GetKeyDown(KeyCode.KeypadEnter))
                {
                    if (IsArbitrary)
                    {
                        OnCallback?.Invoke();
                    }

                    if (UIObjects.Count >= 2)
                    {
                        int index = IndexNow(system.currentSelectedGameObject);
                        if (IsReverseOrder)
                        {
                            if (index == 1)
                                OnCallback?.Invoke();
                        }
                        else
                        {
                            if (index == UIObjects.Count - 2)
                                OnCallback?.Invoke();
                        }
                    }
                }
            }
        }

        ///<summary>切换当前选择UI</summary>
        private void SwitchCurrent()
        {
            if (UIObjects.Contains(system.currentSelectedGameObject))
            {
                if (IsReverseOrder)
                {
                    //倒序
                    GameObject last = LastInput(system.currentSelectedGameObject);
                    system.SetSelectedGameObject(last);
                }
                else
                {
                    //正序
                    GameObject next = NextInput(system.currentSelectedGameObject);
                    system.SetSelectedGameObject(next);
                }
            }
        }

        ///<summary>获取上一个物体</summary>
        private GameObject LastInput(GameObject input)
        {
            int indexNow = IndexNow(input);
            if (indexNow - 1 >= 0)
            {
                return UIObjects[indexNow - 1].gameObject;
            }
            else
            {
                return UIObjects[UIObjects.Count - 1].gameObject;
            }
        }

        ///<summary>获取当前选中物体的序列</summary>
        private int IndexNow(GameObject input)
        {
            int indexNow = 0;
            for (int i = 0; i < UIObjects.Count; i++)
            {
                if (input == UIObjects[i])
                {
                    indexNow = i;
                    break;
                }
            }
            return indexNow;
        }

        ///<summary>获取下一个物体</summary>
        private GameObject NextInput(GameObject input)
        {
            int indexNow = IndexNow(input);
            if (indexNow + 1 < UIObjects.Count)
            {
                return UIObjects[indexNow + 1].gameObject;
            }
            else
            {
                return UIObjects[0].gameObject;
            }
        }

        public override void Dispose()
        {
            base.Dispose();
            UIObjects.Clear();
            OnCallback = null;
            IsArbitrary = false;
            IsReverseOrder = false;
        }
    }
}