using System.Collections;
using Sirenix.OdinInspector;
using UnityEngine;
using UnityEngine.UIElements;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Objects.Unit.Actions.Exceptions;
using VOID.Generic.Objects.Unit.Events;

namespace VOID.UserInterface.Game.AlertUI
{
    public class AlertUI : MonoBehaviour
    {
        public static AlertUI current { get; private set; }

        [SerializeField, MinValue(0)] private float timeToHideAlert = 3f;
        [SerializeField] private string DEATH_MESSAGE = "Died!";
        [SerializeField] private string TURN_START = "Turn start";
        [SerializeField] private string ACTION_ERROR_MESSAGE = "Action prevented: {0}";

        private Label _label;
        private VisualElement _root;
        private Coroutine _hideAlertCoroutine;

        private void Awake()
        {
            current = this;

            var uiDocument = gameObject.GetComponent<UIDocument>();
            _root = uiDocument.rootVisualElement;
            _label = _root.Q<Label>("alert-label");
            HideAlert();
        }

        private void ShowAlert(string message)
        {
            if (_hideAlertCoroutine != null)
            {
                StopCoroutine(_hideAlertCoroutine);
            }

            _label.text = message;
            _label.style.display = DisplayStyle.Flex;
            _hideAlertCoroutine = StartCoroutine(HideAlertAfterDelay(timeToHideAlert));
        }

        private IEnumerator HideAlertAfterDelay(float delay)
        {
            yield return new WaitForSeconds(delay);
            HideAlert();
        }

        private void HideAlert()
        {
            _label.text = "";
            _label.style.display = DisplayStyle.None;
        }

        public void ListenFor(UnitObject unit)
        {
            unit.basicEvents.onDeathAfter.AddListener(OnDeathAfter);
            unit.basicEvents.onTurnSelfStart.AddListener(OnTurnSelfStart);
            unit.unitEvents.onActionError.AddListener(OnActionError);
        }

        public void StopListenFor(UnitObject unit)
        {
            unit.basicEvents.onDeathAfter.RemoveListener(OnDeathAfter);
            unit.basicEvents.onTurnSelfStart.RemoveListener(OnTurnSelfStart);
            unit.unitEvents.onActionError.RemoveListener(OnActionError);
        }

        /*         EVENTS BELOW        */
        /* for register and unregister */

        private void OnDeathAfter(DeathEvent e) => ShowAlert(DEATH_MESSAGE);
        private void OnTurnSelfStart(TurnEvent e) => ShowAlert(TURN_START);
        private void OnActionError(ActionErrorEvent e) => ShowAlert(string.Format(ACTION_ERROR_MESSAGE, UnitActionErrorMessage.Get(e.cause)));
    }
}