using System.Collections.Generic;
using System.Linq;
using Assets.Source.Content.UI.Components;
using Assets.Source.Misc;
using Assets.Source.UI.Elements;
using UnityEngine;
using UnityEngine.UI;

namespace Assets.Source.UI.Layers
{
    public class UIDialogueLayer : UILayer<IUIDialogue>
    {
        public ImageFader Blocker;
        public Button BlockerBtn;
        public Canvas BlockerCanvas;

        public bool BlockerActive { get; private set; }

        private List<IUIDialogue> _activeDialogues = new List<IUIDialogue>();

        public override void VInit()
        {
            base.VInit();

            Blocker.gameObject.SetActive(true);
            Blocker.FadeImmediate(false);
            Blocker.Images[0].raycastTarget = false;

            BlockerBtn.onClick.AddListener(HandleBlockerClick);

            foreach (var e in _elements)
            {
                e.OnOpenStart += () => HandleOpeningElement(e);
                e.OnCloseStart += () => HandleClosingElement(e);
            }
        }

        private void HandleOpeningElement(IUIElement element)
        {
            _activeDialogues.Add((IUIDialogue)element);
            SetBlocker(true);
            Blocker.transform.SetAsLastSibling();
            foreach (var connectedElement in element.ConnectedElements)
                connectedElement.gameObject.transform.SetAsLastSibling();
            element.gameObject.transform.SetAsLastSibling();
        }

        private void HandleClosingElement(IUIElement element)
        {
            _activeDialogues.Remove((IUIDialogue)element);
            if (_activeDialogues.Count == 0)
                SetBlocker(false);
            else
                _activeDialogues.Last().gameObject.transform.SetAsLastSibling();
        }

        private void HandleBlockerClick()
        {
            if (_activeDialogues.Count == 0)
                return;
            var last = _activeDialogues.Last();
            if (!last.PreventAutoClose)
                last.Close();
        }

        private void SetBlocker(bool active)
        {
            Blocker.Fade(active);
            Blocker.Images[0].raycastTarget = active;
            if (active)
                BlockerActive = true;
            else
                Run.NextFixedUpdate(() => BlockerActive = false, CoroutinePlace.Undefined);
        }
    }
}
