﻿using UnityEngine;
using UnityEngine.Events;

namespace JLGames.RocketDriver.Actions.DateTimex
{
    public class MonoTimer : MonoBehaviour
    {
        /// <summary>
        /// Delay time (seconds)
        /// 延迟时间(秒)
        /// </summary>
        [Tooltip("Delay time (seconds)\n延迟时间(秒)")]
        public float Delay = 0;

        /// <summary>
        /// Interval time (seconds)
        /// 间隔时间(秒)
        /// </summary>
        [Tooltip("Interval time (seconds)\n间隔时间(秒)")]
        public float Interval = 1;

        /// <summary>
        /// Repeat times
        /// 重复次数
        /// </summary>
        [Tooltip("Repeat times\n重复次数")]
        public int RepeatCount = 1;

        /// <summary>
        /// Auto start
        /// 自动开始
        /// </summary>
        [Tooltip("Auto start\n自动开始")]
        public bool AutoStart = false;

        /// <summary>
        /// Auto destroy
        /// 自动销亡
        /// </summary>
        [Tooltip("Auto destroy\n自动销亡")]
        public bool AutoDestroy = true;

        /// <summary>
        /// Current time
        /// 当前时间
        /// </summary>
        [Tooltip("Current time\n当前时间")]
        public float CurrentTime = 0;

        /// <summary>
        /// Current count
        /// 当前次数
        /// </summary>
        [Tooltip("Current count\n当前次数")]
        public int CurrentCount = 0;

        /// <summary>
        /// Time interval event
        /// 计时间隔事件
        /// </summary>
        [Tooltip("Time interval event\n计时间隔事件")]
        public UnityEvent OnIntervalEvent;

        /// <summary>
        /// Time complete event
        /// 计时完成是事件
        /// </summary>
        [Tooltip("Time complete event\n计时完成是事件")]
        public UnityEvent OnCompleteEvent;

        /// <summary>
        /// Last interval
        /// 上一次间隔时间
        /// </summary>
        [Tooltip("Last interval\n上一次间隔时间")]
        private float m_LastTime = 0;

        /// <summary>
        /// Time interval event
        /// 计时间隔事件
        /// </summary>
        private MonoTimerDelegate.TimerCallback m_OnIntervalCall;

        /// <summary>
        /// Time complete event
        /// 计时完成是事件
        /// </summary>
        private MonoTimerDelegate.TimerCallback m_OnCompleteCall;

        private void Start()
        {
            enabled = AutoStart;
        }

        private void FixedUpdate()
        {
            if (!enabled) return;
            AddInterval(Time.fixedDeltaTime);
        }

        /// <summary>
        /// Add time interval
        /// 增加间隔时间
        /// </summary>
        /// <param name="deltaTime"></param>
        private void AddInterval(float deltaTime)
        {
            CurrentTime += deltaTime;

            if (CurrentTime < Delay) return;

            if (CurrentTime - m_LastTime >= Interval)
            {
                CurrentCount++;
                m_LastTime = CurrentTime;

                if (RepeatCount <= 0)
                {
                    // 无限重复
                    if (CurrentCount == int.MaxValue) ResetTimer();
                    m_OnIntervalCall?.Invoke(this);
                    OnIntervalEvent?.Invoke();
                }
                else
                {
                    if (CurrentCount < RepeatCount)
                    {
                        //计时间隔
                        m_OnIntervalCall?.Invoke(this);
                        OnIntervalEvent?.Invoke();
                    }
                    else
                    {
                        //计时结束
                        StopTimer();
                        m_OnCompleteCall?.Invoke(this);
                        OnCompleteEvent?.Invoke();
                        if (AutoDestroy && !enabled) Destroy(this);
                    }
                }
            }
        }

        /// <summary>
        /// Start timer or gose on
        /// 开始/继续计时
        /// </summary>
        public void StartTimer()
        {
            enabled = AutoStart = true;
        }

        /// <summary>
        /// Start timer
        /// 开始计时
        /// </summary>
        /// <param name="time">Time(seconds) 时间(秒)</param>
        /// <param name="onComplete">Timed completion callback event 计时完成回调事件</param>
        public void StartTimer(float time, MonoTimerDelegate.TimerCallback onComplete)
        {
            StartTimer(time, 1, null, onComplete);
        }

        /// <summary>
        /// Start timer
        /// 开始计时
        /// </summary>
        /// <param name="interval">Timing interval 计时间隔</param>
        /// <param name="repeatCount">Repeat count 重复次数</param>
        /// <param name="onComplete">Timed completion callback event 计时完成回调事件</param>
        public void StartTimer(float interval, int repeatCount, MonoTimerDelegate.TimerCallback onComplete)
        {
            StartTimer(interval, repeatCount, null, onComplete);
        }

        /// <summary>
        /// Start timer
        /// 开始计时
        /// </summary>
        /// <param name="interval">Timing interval 计时间隔</param>
        /// <param name="repeatCount">Repeat count 重复次数</param>
        /// <param name="onInterval">Time interval callback event 计时间隔回调事件</param>
        /// <param name="onComplete">Timed completion callback event 计时完成回调事件</param>
        public void StartTimer(float interval, int repeatCount, MonoTimerDelegate.TimerCallback onInterval,
            MonoTimerDelegate.TimerCallback onComplete)
        {
            Interval = interval;
            RepeatCount = repeatCount;
            m_OnIntervalCall = onInterval;
            m_OnCompleteCall = onComplete;
            ResetTimer();
            enabled = AutoStart = true;
        }

        /// <summary>
        /// stop timer
        /// 停止计时器
        /// </summary>
        public void StopTimer()
        {
            enabled = AutoStart = false;
        }

        /// <summary>
        /// Stop Timer and reset data
        /// 停止Timer并重置数据
        /// </summary>
        public void ResetTimer()
        {
            m_LastTime = CurrentTime = CurrentCount = 0;
        }

        /// <summary>
        /// Reset data and start timing again
        /// 重置数据并重新开始计时
        /// </summary>
        public void RestartTimer()
        {
            ResetTimer();
            StartTimer();
        }
    }
}