﻿using System.Collections.Generic;
using JLGames.RocketDriver.Actions.Extensions;
using UnityEngine.UIElements;

namespace JLGames.RocketDriver.Actions.UIElements
{
    /// <summary>
    /// Recommended for Editor only
    /// 建议只用于Editor
    /// </summary>
    public class ToggleGroupDynamic : VisualElement
    {
        public new class UxmlFactory : UxmlFactory<ToggleGroupDynamic, UxmlTraits>
        {
        }

        public delegate void OnToggleGroupEvent(Toggle targetToggle, int targetIndex);

        public readonly List<Toggle> Toggles = new List<Toggle>();
        public int ToggleCount => Toggles.Count;
        public event OnToggleGroupEvent OnToggleChanged;

        private bool m_AllowSwitchOff;

        public bool AllowSwitchOff => m_AllowSwitchOff;

        public void SetAllowSwitchOff(bool allow)
        {
            m_AllowSwitchOff = allow;
        }

        public void InitByChildren()
        {
            var count = childCount;
            if (0 == count) return;
            for (var index = 0; index < count; index++)
            {
                if (this[index] is Toggle)
                {
                    AddToogle(this[index] as Toggle);
                }
            }
        }

        public void InitByChildren<T>() where T : Toggle
        {
            var count = childCount;
            if (0 == count) return;
            for (var index = 0; index < count; index++)
            {
                if (this[index] is T)
                {
                    AddToogle(this[index] as T);
                }
            }
        }

        public void AddToogle(Toggle toggle)
        {
            if (null == toggle) return;
            Toggles.Add(toggle);
            toggle.RegisterCallback<ChangeEvent<bool>>(OnToggleChangedEvent);
        }

        public void RemoveToggle(Toggle toggle)
        {
            if (!Toggles.Remove(toggle)) return;
            toggle.UnregisterCallback<ChangeEvent<bool>>(OnToggleChangedEvent);
        }

        public void Dispose()
        {
            for (var i = Toggles.Count - 1; i >= 0; i--)
            {
                Toggles[i].UnregisterCallback<ChangeEvent<bool>>(OnToggleChangedEvent);
            }

            Toggles.Clear();
        }

        public void SetToggleOn(string toggleName, bool notify = false)
        {
            if (Toggles.Count == 0) return;
            var index = Toggles.FindIndex(toggle1 => toggle1.name == toggleName);
            SetToggleOnL(Toggles[index], index, notify);
        }

        public void SetToggleOn(int index, bool notify = false)
        {
            if (index < 0 || index >= Toggles.Count) return;
            SetToggleOnL(Toggles[index], index, notify);
        }

        public void SetToggleOn(Toggle toggle, bool notify = false)
        {
            if (null == toggle || Toggles.Count == 0) return;
            var index = Toggles.FindIndex(toggle1 => toggle1 == toggle);

            SetToggleOnL(toggle, index, notify);
        }

        private void SetToggleOnL(Toggle toggle, int index, bool notify)
        {
            toggle.SetValue(true, notify);
            if (!m_AllowSwitchOff)
            {
                Toggles.ForEach(o =>
                {
                    if (o != toggle) o.SetValue(false, false);
                });
            }

            OnToggleChanged?.Invoke(toggle, index);
        }

        private void OnToggleChangedEvent(ChangeEvent<bool> evt)
        {
            var toggle = evt.target as Toggle;
            if (null == toggle) return;

            if (evt.newValue)
            {
                var index = Toggles.FindIndex(toggle1 => toggle1 == toggle);
                SetToggleOnL(toggle, index, false);
            }
        }
    }
}