using System;
using System.Collections.Generic;
using DG.Tweening;
using FairyGUI;
using UnityEngine.UI;

namespace ChillConnect
{
    public enum CountDownType
    {
        Second,
        Minute,
        Hour,
        Day
    }

    public class CountDownKit
    {
        private int countDownTime;
        private int leftTime = 0;
        private GTextField textGComponent;
        private GProgressBar barGComponent;
        private Text textComponent;
        private CountDownType countDownType = CountDownType.Second;
        private Dictionary<int, Action> onTriggerEventDict = new Dictionary<int, Action>();
        private Tween timer;
        private Action onCompletedEvent;
        private long endTime;
        private bool isDependenceServerTime = true;

        public CountDownKit SetTime(int second)
        {
            countDownTime = second;
            leftTime = countDownTime;
            return this;
        }

        public CountDownKit SetCountDownType(CountDownType countDownType)
        {
            this.countDownType = countDownType;
            return this;
        }

        public CountDownKit SetText(GTextField gText)
        {
            textComponent = null;
            textGComponent = gText;
            return this;
        }

        public CountDownKit SetBar(GProgressBar gProgressBar)
        {
            barGComponent = null;
            barGComponent = gProgressBar;
            return this;
        }

        public int interval = 1;

        public void Start()
        {
            endTime = (int)(DateTimeManager.Instance.GetServerCurrTimestamp() / 1000) + leftTime;
            UpdateView();
            timer = DOVirtual.DelayedCall(interval, () =>
            {
                leftTime -= interval;
                if (isDependenceServerTime)
                {
                    var current = DateTimeManager.Instance.GetServerCurrTimestamp() / 1000;
                    if (endTime <= current)
                    {
                        leftTime = 0;
                    }
                }

                UpdateView();
                if (leftTime <= 0)
                {
                    Stop();
                    OnCompleted();
                }
                else
                {
                    OnTrigger();
                }
            }, true).SetLoops(-1);
        }

        private void UpdateView()
        {
            UpdateText();
            UpdateBar();
        }

        public void Pause()
        {
            if (timer != null)
            {
                timer.Pause();
            }
        }

        public void Resume()
        {
            if (timer != null)
            {
                timer.Play();
            }
        }

        public void Stop()
        {
            if (timer != null && timer.IsActive())
            {
                timer?.Kill();
            }
        }

        public void OnDestroy()
        {
            Stop();
            leftTime = 0;

            textGComponent = null;

            textComponent = null;
            onTriggerEventDict = null;
            onCompletedEvent = null;
        }

        public void ConsumeTime(int consumeTime)
        {
            leftTime -= consumeTime;
            UpdateView();
            if (leftTime <= 0)
            {
                Stop();
                OnCompleted();
            }
            else
            {
                OnTrigger();
            }
        }

        private void OnTrigger()
        {
            if (onTriggerEventDict.ContainsKey(leftTime))
            {
                onTriggerEventDict[leftTime]?.Invoke();
            }
        }

        public void ClearTriggerEvent()
        {
            onTriggerEventDict.Clear();
        }

        public CountDownKit SetCompletedEvent(Action onCompleted)
        {
            onCompletedEvent = onCompleted;
            return this;
        }

        private void OnCompleted()
        {
            onCompletedEvent?.Invoke();
        }

        private void UpdateText()
        {
            if (textGComponent != null)
            {
                textGComponent.text = CommonHelper.TimeFormat(leftTime, countDownType);
            }

            if (textComponent != null)
            {
                textComponent.text = CommonHelper.TimeFormat(leftTime, countDownType);
            }
        }

        private void UpdateBar()
        {
            if (barGComponent != null)
            {
                if (barGComponent.max == 0)
                {
                    barGComponent.max = countDownTime;
                }

                barGComponent.TweenValue(leftTime, 1);
            }
        }

        public int GetLeftTime()
        {
            return leftTime;
        }

        public CountDownKit SetServerTimeDependence(bool _isDependenceServerTime)
        {
            isDependenceServerTime = _isDependenceServerTime;
            return this;
        }
    }
}