using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

[ExecuteInEditMode]
public class DelayAction : MonoBehaviour
{
	private static DelayAction _instace;

	public static DelayAction instance
	{
		get
		{
			if (_instace == null)
			{
				_instace = new GameObject("DelayAction").AddComponent<DelayAction>();
			}
			return _instace;
		}
	}
	
	class DelayActionStruct
	{
		public float beginTime;
		public float duration;
		public Action action;
	}
	private List<DelayActionStruct> m_DelayActions = new List<DelayActionStruct>();
	
	
	public void DelayDoAction(float time,Action _action)
	{
        //GameDebug.Log($"准备执行：{Time.realtimeSinceStartup}  延迟时间:{testTime}  ");

        DelayActionStruct newAction = new DelayActionStruct
		{
			beginTime = Time.realtimeSinceStartup,
			duration = time,
			action = ()=>
			{
                //GameDebug.Log($"时间到 执行：{Time.realtimeSinceStartup}  ");
                try
                {
                    _action?.Invoke();
                }
                catch(Exception e)
                {
                    GameDebug.LogError(e);
                }
			}
		};
		m_DelayActions.Add(newAction);
	}

	public static void DelayDo(float time, Action _action)
	{
		instance.DelayDoAction(time,_action);
	}

	void CheckDelayAction()
	{
		if (m_DelayActions == null)
		{
			m_DelayActions = new List<DelayActionStruct>();
		}
		
		if(m_DelayActions.Count > 0)
		{
			for (int i = 0; i < m_DelayActions.Count; )
			{
				if (Time.realtimeSinceStartup - m_DelayActions[i].beginTime >= m_DelayActions[i].duration)
				{
					m_DelayActions[i].action?.Invoke();
					m_DelayActions.RemoveAt(i);
				}
				else
				{
					i++;
				}
			}
		}
		
	}

#if DEBUG
	private int testSeq;
	public float testTime = 5;
	[ContextMenu("Test")]
	void Test()
	{
		int cur = testSeq++;
		GameDebug.Log($"准备执行：{Time.realtimeSinceStartup}  延迟时间:{testTime}  testSeq:{cur}");
		DelayDoAction(testTime, () =>
		{
			GameDebug.Log($"时间到 执行：{Time.realtimeSinceStartup}  testSeq:{cur}");
		});
	}
#endif

	
	// Update is called once per frame
	void Update ()
	{
		 CheckDelayAction();

	}
}
