using System.Collections.Generic;
using JetBrains.Annotations;
using JohnsonUtils.Utilities;
using JohnsonUtils.Utilities.Icons;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.InputSystem.Utilities;

namespace JohnsonUtils.Canvases
{
    public class RebindUI : MonoBehaviour
    {
         
        [SerializeField, UsedImplicitly] private ImageUIComponent background;
        [SerializeField, UsedImplicitly] private GameObject rebindMenuContent;
        [SerializeField, UsedImplicitly] private TextUIComponent currentControlScheme;
        [SerializeField, UsedImplicitly] private ButtonUIComponent resetAllButton;
        [SerializeField, UsedImplicitly] private RectTransform scrollRectContent;
        [SerializeField, UsedImplicitly] private TextUIComponent rebindOverlayText;
        [SerializeField, UsedImplicitly] private RebindActionUI rebindPrefab;
        [SerializeField, UsedImplicitly] private ButtonUIComponent applyButton;

        //TODO ProjectInit replace this by your action map
        private IInputActionCollection2 _playerInputActionRef;

        [UsedImplicitly] private RebindActionUI _firstButton;

        private readonly List<RebindActionUI> _rebindUIs = new();
        private bool _isInitialized;

        private void Start()
        {
            //TODO ProjectInit Bind to OnInputDeviceChanged
            Debug.LogWarning($"Didn't init Start method on {GetType()} on {name} ");
        }

        private void OnEnable()
        {
            applyButton.OnClick += OnApplyPressed;
        }

        private void OnDisable()
        {
            applyButton.OnClick -= OnApplyPressed;
        }

        private void OnDestroy()
        {
            //TODO ProjectInit Unbind to OnInputDeviceChanged
            Debug.LogWarning($"Didn't init OnDestroy method on {GetType()} on {name} ");
        }

        private void OnApplyPressed()
        {
            // Save changes
            // Hide
        }
        
        [UsedImplicitly]
        private void OnResetAll()
        {
            _playerInputActionRef.RemoveAllBindingOverrides();
            UpdateAllRebindUI();
            // UpdateBindings
        }

        private void AddBindingsButton(string deviceName)
        {
            currentControlScheme.Text = $"< {deviceName.ToUpper()} >";
            ReadOnlyArray<InputAction> inputActions = new (); //TODO ProjectInit Get the actions from the Action map
            bool first = true;
            foreach (var inputAction in inputActions)
            {
                foreach (var mainBinding in BindingsIconsUtil.GetRelevantMainBindings(inputAction, deviceName))
                {
                    SpawnButton(inputAction, mainBinding, first);
                    first = false;
                }
            }
        }

        private void SpawnButton(InputAction inputAction, int mainBindingIndex, bool first)
        {
            RebindActionUI actionButton = Instantiate(rebindPrefab, scrollRectContent);
            _rebindUIs.Add(actionButton);
            actionButton.name = $"Rebind UI for {inputAction.name}";
            actionButton.Initialize(mainBindingIndex, inputAction, rebindOverlayText, OnUpdateBindingUIEvent);
            if (first)
            {
                _firstButton = actionButton;
            }
        }

        private void OnUpdateBindingUIEvent(string deviceLayoutName, string mainControlPath)
        {
            UpdateAllRebindUI();
            // UpdateBindings
        }

        private void UpdateAllRebindUI()
        {
            foreach (RebindActionUI rebindActionUI in _rebindUIs)
            {
                rebindActionUI.UpdateBindingDisplay(false);
            }
        }

        [UsedImplicitly]
        private void OnInputDeviceChanged(string newDevice)
        {
            _rebindUIs.Clear();
            scrollRectContent.DestroyChildren();
            AddBindingsButton(newDevice);
        }
        
    }
}