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

namespace JLGames.RocketDriver.Actions.UIElements
{
    public class ToggleGroup : VisualElement
    {
        public new class UxmlFactory : UxmlFactory<ToggleGroup, UxmlTraits>
        {
        }

        private bool m_AllowSwitchOff;

        public bool AllowSwitchOff => m_AllowSwitchOff;

        public List<Toggle> ToggleList => this.Query<Toggle>().ToList();

        public ToggleGroup() : this(false)
        {
        }

        public ToggleGroup(bool allowSwitchOff)
        {
            SetAllowSwitchOff(allowSwitchOff);
        }

        public void SetAllowSwitchOff(bool allow)
        {
            m_AllowSwitchOff = allow;
            if (!allow)
            {
                RegisterCallback<ChangeEvent<bool>>(OnToggleChanged);
            }
            else
            {
                UnregisterCallback<ChangeEvent<bool>>(OnToggleChanged);
            }
        }

        public void SetToggleOn(string toggleName, bool notify = false)
        {
            var targetToggle =
                this.GetFirstTreeElement<Toggle>(toggle => toggle.name == toggleName && toggle.value == false);
            SetToggleOn(targetToggle, notify);
        }

        public void SetToggleOn(int index, bool notify = false)
        {
            var targetToggle = this.Query<Toggle>().AtIndex(index);
            SetToggleOn(targetToggle);
        }

        public void SetToggleOn(Toggle toggle, bool notify = false)
        {
            if (null == toggle) return;

            toggle.SetValue(true, notify);

            if (m_AllowSwitchOff) return;

            this.Query<Toggle>().ForEach(o =>
            {
                if (o != toggle) o.SetValue(false, false);
            });
        }

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

            if (m_AllowSwitchOff) return;

            this.Query<Toggle>().ForEach(o =>
            {
                if (o == toggle || !o.value) return;
                o.SetValueWithoutNotify(false);
            });
        }
    }
}