using System;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class Bar : MonoBehaviour
    {
        [Header("Dependencies")]
        [SerializeField]
        Image _fill;
        [SerializeField]
        Image _buffer;
        [SerializeField]
        Image _flash;
        [SerializeField]
        CanvasGroup _canvasGroup;
        
        [Header("Settings")] 
        [SerializeField]
        int _max = 100;
        [SerializeField]
        int _value = 20;

        void Awake()
        {
            _canvasGroup.alpha = 0;
        }

        public void TakeDamage(int amount)
        {
            float currentPercent = (float)_value / _max;
            _value = Mathf.Max(0,_value - amount);
            float targetPercent = (float)_value / _max;
            
            Fill = targetPercent;
            _buffer.fillAmount = currentPercent;
            Buffer = targetPercent;
            Shake();
        }


        public void SetColors(Color colorA, Color colorB)
        {
            _fill.color = colorA;
            _buffer.color = colorB;
        }

        #region Plumbing

        void Shake()
        {
            _shaker.Restart();
            _shaker.Play();
        }

        [ContextMenu("Replenish")]
        public void Replenish()
        {
            _value = _max;
            AnimateHealing(1,Flash);
        }

        public void Replenish(Action completed)
        {
            _value = _max;
            AnimateHealing(1,completed.Invoke);
        }
        
        void AnimateHealing(float targetPercent,TweenCallback onComplete)
        {
            DOVirtual
                .Float(_fill.fillAmount, 1,targetPercent, x => _fill.fillAmount = x)
                .SetEase(Ease.OutSine).OnComplete(onComplete);
        }

        float Fill
        {
            set => _fill.fillAmount = value;
        }

        float Buffer
        {
            set
            {
               
                DOVirtual
                    .Float(_buffer.fillAmount, value, 0.3f,x=>_buffer.fillAmount = x)
                    .SetEase(Ease.InSine);
            }
        }

        public Color FlashColor;

        [ContextMenu("Flash")]
        void Flash()
        {
            _flash.color = FlashColor;
            _flash.DOColor(_fill.color,1f).SetEase(Ease.OutSine).OnComplete(()=>_flash.color = Color.clear);
          
        }

        void OnValidate()
        {
            Max = _max;
            Value = _value;
        }

        public int Value
        {
            get => _value;
            set => _value = Mathf.Clamp(value, 0, _max);
        }

        public int Max
        {
            get => _max;
            set => _max = Mathf.Max(1, value);
        }
        
        // string healthText = health <= 0 ? "DEAD" : $"{health} / {_battler.MaxHealth}";

        public float Percent
        {
            get => _fill.fillAmount;
            set
            {
                var val = Mathf.Lerp(0, Max, value);
                _value = (int) val;
                _fill.fillAmount = _buffer.fillAmount = val / Max;
            }
        }

        void Start()
        {   
            _shaker = transform.DOPunchPosition(Vector3.right * 8, 0.5f, 30).SetAutoKill(false);
            _canvasGroup.alpha = 0;
        }

        public void FillTo(float percent)
        {
            Percent = percent;
        }

        void OnDestroy()
        {
            _shaker.Kill();
        }

        Tweener _shaker;

        #endregion

        public void Heal(int amount)
        {
            _value = Mathf.Min(Max, _value + amount);
            
            AnimateHealing((float)_value/Max,Flash);
        }

        bool _isShowing;

        public void Show()
        {
            DOTween.Kill(_canvasGroup);
            _canvasGroup.DOFade(1, 0.3f);
            _isShowing = true;
        }
        
        public void Hide()
        {
            DOTween.Kill(_canvasGroup);
            _canvasGroup.DOFade(0, 0.3f);
            _isShowing = false;
        }
    }