using System;
using System.Collections;
using Intrepid.Core.Themes;
using Intrepid.Utilities;
using UnityEngine;
using UnityEngine.UI;

namespace Intrepid.Core.UI.Dialog
{
    public class DialogMinimalUI : MonoBehaviour
    {
        [GroupConfigurations, SerializeField] private float animationDuration = 0.5f;
        [GroupConfigurations, SerializeField] private float animationSpeed = 4.5f;
        [GroupConfigurations, SerializeField] private float scaleEmphasis = 0.90f;
        [GroupConfigurations, SerializeField] private float moveIntensity = 25f;
        [GroupInjections, SerializeField] private Image border;
        [GroupInjections, SerializeField] private Image background;
        [GroupInjections, SerializeField] private GameObject content;

        private UIDialogMinimalTheme theme;
        private RectTransform RectTransform { get; set; }
        private Vector2 MainPosition { get; set; }
        public Vector3 MainLocalScale { get; private set; }

        public UIDialogMinimalTheme Theme
        {
            get => theme;
            set
            {
                theme = value;
                border.color = theme.Button.Available;
                background.color = theme.Window.TransparentBackground;
            }
        }

        private void Awake()
        {
            RectTransform = GetComponent<RectTransform>();
            MainPosition = RectTransform.anchoredPosition;
            MainLocalScale = transform.localScale;
            if (theme.IsNotNull()) Theme = theme;
        }

        public void BlinkBorderActionTaken()
        {
            StartCoroutine(BlinkBorderCoroutine(Theme.Button.Clicked));
        }
        
        public void BlinkBorderSelected()
        {
            StartCoroutine(BlinkBorderCoroutine(Theme.Button.Selected));
        }
        
        public void BlinkBorderDropped()
        {
            StartCoroutine(BlinkBorderCoroutine(Theme.Button.Denied));
        }

        public void Emphasis()
        {
            StartCoroutine(EmphasisCoroutine());
        }

        public void Move(Vector2 start, Vector2 end)
        {
            StartCoroutine(MoveCoroutine(start, end));
        }

        private IEnumerator BlinkBorderCoroutine(Color target)
        {
            border.color = target;

            float time = 0;
            while (time < animationDuration)
            {
                border.color = Color.Lerp(target, Theme.Button.Available, time);
                yield return null;
                time += Time.unscaledDeltaTime * animationSpeed;
            }
            
            border.color = Theme.Button.Available;
        }
        
        private IEnumerator EmphasisCoroutine()
        {
            transform.localScale = MainLocalScale * scaleEmphasis;

            float time = 0;
            while (time < animationDuration)
            {
                transform.localScale = Vector3.Lerp(Vector3.one * scaleEmphasis, Vector3.one, time);
                yield return null;
                time += Time.unscaledDeltaTime * animationSpeed;
            }
            
            transform.localScale = MainLocalScale;
        }

        private IEnumerator MoveCoroutine(Vector2 start, Vector2 end)
        {
            var complete = MainPosition;
            
            float time = 0;
            while (time < animationDuration)
            {
                RectTransform.anchoredPosition = Vector2.Lerp(start, end, time);    
                yield return null;
                time += Time.unscaledDeltaTime * animationSpeed;
            }
            RectTransform.anchoredPosition = complete;
        }

        public void Upy()
        {
            Emphasis();
            Move(MainPosition, MainPosition + Vector2.up * moveIntensity);
        }

        public void Downy()
        {
            Emphasis();
            Move(MainPosition, MainPosition + Vector2.down * moveIntensity);
        }
        
        public void Lefty()
        {
            Emphasis();
            Move(MainPosition, MainPosition + Vector2.left * moveIntensity);
        }

        public void Righty()
        {
            Emphasis();
            Move(MainPosition, MainPosition + Vector2.right * moveIntensity);
        }
        
        public T GetInContent<T>() where T : Component
        {
            return content.GetComponent<T>();
        }
        
        public T GetOnContentChildren<T>() where T : Component
        {
            return content.GetComponentInChildren<T>();
        }
    }
}