using System.Collections.Generic;
using Assets.Source.Content.Tweens;
using Assets.Source.UI;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

namespace Assets.Source.Content.UI.Components
{
    public class UIAnimFade : UIAnimation
    {
        public UITweenDataFade Data;
        public bool ZeroAlphaFromStart = true;

        public CanvasGroup[] CanvasGroups;
        public Image[] Images;

        public bool CustomMode;
        public float CustomDurationIn;
        public float CustomDurationOut;
        public AnimationCurve CustomFadeIn = AnimationCurve.EaseInOut(0, 0, 1, 1);
        public AnimationCurve CustomFadeOut = AnimationCurve.EaseInOut(0, 0, 1, 1);

        private Dictionary<CanvasGroup, float> _standardCanvasGroupAlphas = new Dictionary<CanvasGroup, float>();
        private Dictionary<Image, float> _standardImageAlphas = new Dictionary<Image, float>();
        private Sequence _seq;

        protected override void VAwake()
        {
            base.VAwake();
            foreach (var img in Images)
            {
                _standardImageAlphas.Add(img, img.color.a);
                if (ZeroAlphaFromStart)
                    img.color = img.color.SetAlpha(0);
            }
            foreach (var grp in CanvasGroups)
            {
                _standardCanvasGroupAlphas.Add(grp, grp.alpha);
                if (ZeroAlphaFromStart)
                    grp.alpha = 0;
            }
        }

        protected override void HandleTrigger(UIAnimationTrigger trigger)
        {
            _seq?.Kill();

            switch (trigger)
            {
                case UIAnimationTrigger.Open:
                    FadeIn();
                    break;
                case UIAnimationTrigger.Close:
                    FadeOut();
                    break;
            }
            _seq.onComplete = () => _seq = null;
        }

        public override void EndInstantly()
        {
            _seq?.Complete();
        }

        public override float GetInDuration()
        {
            return CustomMode ? CustomDurationIn : Data.FadeInDuration;
        }

        public override float GetOutDuration()
        {
            return CustomMode ? CustomDurationOut : Data.FadeOutDuration;
        }

        public void FadeIn()
        {
            var curve = CustomMode ? CustomFadeIn : Data.FadeInCurve;
            _seq = DOTween.Sequence();
            foreach (var canvasGroup in CanvasGroups)
                _seq.Join(canvasGroup.DOFade(_standardCanvasGroupAlphas[canvasGroup], GetInDuration()).SetEase(curve));
            foreach (var image in Images)
                _seq.Join(image.DOFade(_standardImageAlphas[image], GetInDuration()).SetEase(curve));
        }

        public void FadeOut()
        {
            var curve = CustomMode ? CustomFadeOut : Data.FadeOutCurve;
            _seq = DOTween.Sequence();
            foreach (var canvasGroup in CanvasGroups)
                _seq.Join(canvasGroup.DOFade(0, GetOutDuration()).SetEase(curve));
            foreach (var image in Images)
                _seq.Join(image.DOFade(0, GetOutDuration()).SetEase(curve));
        }
    }
}
