// 本脚本只在不存在时会生成一次。已存在不会再次生成覆盖

using System.Collections.Generic;
using FairyGUI;
using UnityEngine;
using NBC;
using NBF.Setting;
using Unity.VisualScripting;
using UIPanel = NBC.UIPanel;

namespace NBF
{
    [UIBind(UIDef.ID.SettingPanel)]
    public partial class SettingPanel : UIPanel
    {
        private readonly List<TabItemData> tabList = new List<TabItemData>();
        private string _currentTab = "";
        private List<int> _canSelectIndex = new List<int>();
        private int _nowSelectIndex = -1;

        protected override void OnInit()
        {
            base.OnInit();
            IsShowCursor = true;
            //TEXT_SETTINGS_
            var groupNames = Settings.Instance.GetAllTabs();
            foreach (var group in groupNames)
            {
                var tab = new TabItemData
                {
                    Key = $"TEXT_SETTINGS_{group}",
                    Name = group
                };
                tabList.Add(tab);
            }


            MenuList.OnTabChange += ChangeTab;
            List.onClickItem.Set(OnClickListItem);
        }

        protected override void OnShow()
        {
            InputManager.Instance.On(this);
            SetActionIcon();
            Settings.Instance.LoadAllSettings();
            MenuList.SetTabs(tabList);
        }

        private void ChangeTab(int index)
        {
            if (index < 0) return;
            Log.Info($"Change tab index={index}");
            var tabListData = tabList[index];
            _currentTab = tabListData.Name;
            ResetSettingList();
        }


        private void ResetSettingList()
        {
            // TextTitle.text = Lan.Get(_currentGroup);
            _nowSelectIndex = -1;

            if (string.IsNullOrEmpty(_currentTab)) return;
            var options = Settings.Instance.GetOptionsByTab(_currentTab);
            Dictionary<string, List<OptionBase>> groupOptions = new Dictionary<string, List<OptionBase>>();
            foreach (var option in options)
            {
                if (!groupOptions.TryGetValue(option.Group, out List<OptionBase> list))
                {
                    list = new List<OptionBase>();
                    groupOptions.Add(option.Group, list);
                }

                list.Add(option);
            }

            _canSelectIndex.Clear();

            List.RemoveChildrenToPool();


            var url = UIPackage.GetItemURL(UIPackName, "SettingSubTitleItem");

            foreach (var key in groupOptions.Keys)
            {
                var value = groupOptions[key];


                if (List.AddItemFromPool(url) is GLabel label)
                {
                    label.SetLanguage(key);
                }

                foreach (var option in value)
                {
                    if (List.AddItemFromPool() is SettingItem item)
                    {
                        item.SetData(option);
                        var index = List.GetChildIndex(item);
                        _canSelectIndex.Add(index);
                    }
                }
            }
        }


        private void OnResetSettings()
        {
            var options = Settings.Instance.GetOptionsByTab(_currentTab);

            foreach (var option in options)
            {
                option.Reset();
            }

            ResetSettingList();

            Notices.Success("TEXT_OP_SUCCESS");
        }


        private void ChangeListSelected(bool up = true)
        {
            if (!up)
            {
                _nowSelectIndex++;
            }
            else
            {
                _nowSelectIndex--;
            }

            if (_nowSelectIndex < 0) _nowSelectIndex = 0;
            else if (_nowSelectIndex >= _canSelectIndex.Count) _nowSelectIndex = _canSelectIndex.Count - 1;
            var targetIndex = _canSelectIndex[_nowSelectIndex];
            SetListSelected(targetIndex);
        }

        private void SetListSelected(int selectedIndex)
        {
            if (selectedIndex >= 0 && selectedIndex < List.numItems)
            {
                List.selectedIndex = selectedIndex;
                List.ScrollToView(List.selectedIndex);
            }

            OnClickListItem();
        }

        private void OnClickListItem()
        {
            var index = List.selectedIndex;
            if (index < 0)
            {
                return;
            }

            var settingItem = List.GetChildAt(index);
            if (settingItem is SettingItem item)
            {
                // Introduce.TextName.SetLanguage(item.Option.Name);
                Introduce.TextIntroduce.SetLanguage(item.Option.Name);
                // Introduce.
            }

            for (var i = 0; i < _canSelectIndex.Count; i++)
            {
                var targetIndex = _canSelectIndex[i];
                if (targetIndex == index)
                {
                    _nowSelectIndex = i;
                }
            }
        }


        private void CancelAndBack()
        {
            var groupNames = Settings.Instance.GetAllTabs();
            foreach (var group in groupNames)
            {
                var options = Settings.Instance.GetOptionsByTab(group);
                foreach (var option in options)
                {
                    if (option.HaveNotApple())
                    {
                        option.Cancel();
                    }
                }
            }
        }

        #region Input Evnet

        private void SetActionIcon()
        {
            MenuList.SetBtnActionName(InputDef.UI.Prev, InputDef.UI.Next);
        }

        [InputInvoke(InputDef.UI.Prev, UIInputButtonShowMode.MenuLeft)]
        private void OnPrev()
        {
            MenuList.OnClickBtnPrev();
        }

        [InputInvoke(InputDef.UI.Next, UIInputButtonShowMode.MenuRight)]
        private void OnNext()
        {
            MenuList.OnClickBtnNext();
        }


        [InputInvoke(InputDef.UI.Left, UIInputButtonShowMode.BottomLeft)]
        private void OnLeft()
        {
            if (List.GetChildAt(List.selectedIndex) is SettingItem item)
            {
                item.OnPrev();
            }
        }

        [InputInvoke(InputDef.UI.Right, UIInputButtonShowMode.BottomLeft)]
        private void OnRight()
        {
            if (List.GetChildAt(List.selectedIndex) is SettingItem item)
            {
                item.OnNext();
            }
        }

        [InputInvoke(InputDef.UI.Up, UIInputButtonShowMode.BottomLeft)]
        private void OnUp()
        {
            ChangeListSelected();
        }

        [InputInvoke(InputDef.UI.Down, UIInputButtonShowMode.BottomLeft)]
        private void OnDown()
        {
            ChangeListSelected(false);
        }


        [InputInvoke(InputDef.UI.Enter, UIInputButtonShowMode.BottomRight, "保存")]
        private void OnApplySettings()
        {
            var options = Settings.Instance.GetOptionsByTab(_currentTab);
            Log.Info("OnApplySettings");
            foreach (var option in options)
            {
                option.Apply();
            }

            Notices.Success("TEXT_OP_SUCCESS");
        }

        [InputInvoke(InputDef.UI.Reset, UIInputButtonShowMode.BottomRight, "重置")]
        private void OnReset()
        {
            MessageBox.Show("是否重置为默认？", (ret) =>
            {
                if (ret) OnResetSettings();
            });
        }

        [InputInvoke(InputDef.UI.Back, UIInputButtonShowMode.BottomRight)]
        private void OnBack()
        {
            if (Settings.Instance.HaveNotAppleSettings())
            {
                MessageBox.Show("还有未保存的信息", (b) =>
                {
                    if (b)
                    {
                        CancelAndBack();
                        Hide();
                    }
                });
            }
            else
            {
                Hide();
            }
        }

        #endregion

        protected override void OnHide()
        {
            base.OnHide();
            InputManager.Instance.Off(this);
        }

        protected override void OnDestroy()
        {
            base.OnDestroy();
            MenuList.OnTabChange -= ChangeTab;
        }
    }
}