using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Unity.VisualScripting;
using UnityEngine;
using static UnityEngine.ParticleSystem;

public class TaskManages
{
    private static TaskManages instance = new TaskManages();
    private Dictionary<int,int> taskSize = new Dictionary<int, int>();
    private TaskManages()
    {

    }
    public static TaskManages getInstance()
    {
        return instance;
    }
    private void pushSetId(int id)
    {
        if(taskSize.ContainsKey(id)== false)
        {
            taskSize.Add(id, 1);
        }
        else
        {
            taskSize[id] = taskSize[id] + 1;
        }
        
    }
    //内部是栈维护 当栈空的时候才会继续执行队列Queue中的任务
    public void insertTask(MonoBehaviour monoBehaviour,TaskItemBack taskItemBack,params System.Object[] allparams)
    {
        Stack<Tuple<TaskItemBack, System.Object[]>> taskInfos;
        if (utilsTools.ContainsKey(monoBehaviour.gameObject, "PriorityStack") == false)
            utilsTools.getUserData<Stack<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "PriorityStack", out taskInfos, new Stack<Tuple<TaskItemBack, System.Object[]>>());
        else
            utilsTools.getUserData<Stack<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "PriorityStack", out taskInfos, null);
        taskInfos.Push(new Tuple<TaskItemBack, System.Object[]>(taskItemBack, allparams));
        utilsTools.setUserData(monoBehaviour.gameObject, "PriorityStack", taskInfos);
        pushSetId(monoBehaviour.GetInstanceID());
    }
    public void insertTask(MonoBehaviour monoBehaviour, TaskItemBack taskItemBack, System.Object param1 = null,System.Object param2 = null,System.Object param3 = null)
    {
        System.Object[] allparams = { param1,param2,param3 };
        insertTask(monoBehaviour, taskItemBack, allparams);
    }
    public void addTask(MonoBehaviour monoBehaviour, TaskItemBack taskItemBack, System.Object param = null)
    {
        System.Object[] allparams = { param };
        addTask(monoBehaviour, taskItemBack, allparams);
    }
    public void addTask(MonoBehaviour monoBehaviour, TaskItemBack taskItemBack,params  System.Object[] allparams)
    {
        Queue < Tuple<TaskItemBack, System.Object[]>> taskInfos;
        if(utilsTools.ContainsKey(monoBehaviour.gameObject, "TaskList") == false)
            utilsTools.getUserData<Queue<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "TaskList", out taskInfos, new Queue<Tuple<TaskItemBack, System.Object[]>>());
        else
            utilsTools.getUserData<Queue<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "TaskList", out taskInfos, null);
        taskInfos.Enqueue(new Tuple<TaskItemBack, object[]>(taskItemBack, allparams));
        utilsTools.setUserData(monoBehaviour.gameObject, "TaskList", taskInfos);
        pushSetId(monoBehaviour.GetInstanceID());
    }
    public void addTaskArray(MonoBehaviour monoBehaviour, TaskItemBack taskItemBack, System.Object[] allparams)
    {
        Queue<Tuple<TaskItemBack, System.Object[]>> taskInfos;
        if (utilsTools.ContainsKey(monoBehaviour.gameObject, "TaskList") == false)
            utilsTools.getUserData<Queue<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "TaskList", out taskInfos, new Queue<Tuple<TaskItemBack, System.Object[]>>());
        else
            utilsTools.getUserData<Queue<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "TaskList", out taskInfos, null);
        System.Object[] objects = allparams.ToList<System.Object>().ToArray();
        taskInfos.Enqueue(new Tuple<TaskItemBack, object[]>(taskItemBack, objects));
        utilsTools.setUserData(monoBehaviour.gameObject, "TaskList", taskInfos);
        pushSetId(monoBehaviour.GetInstanceID());
    }
    private Tuple<TaskItemBack, System.Object[]> getTask(MonoBehaviour monoBehaviour)
    {
        Tuple<TaskItemBack, System.Object[]> ret = null;
        if (utilsTools.ContainsKey(monoBehaviour.gameObject, "PriorityStack") == true)
        {
            Stack<Tuple<TaskItemBack, System.Object[]>> taskStackInfos = null;
            utilsTools.getUserData<Stack<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "PriorityStack", out taskStackInfos, null);
            if(taskStackInfos.Count > 0)
            {
                ret = taskStackInfos.Pop();
                utilsTools.setUserData(monoBehaviour.gameObject, "PriorityStack", taskStackInfos);
            }
        }
        if (ret == null)
        {
            Queue<Tuple<TaskItemBack, System.Object[]>> taskInfos;
            if (utilsTools.ContainsKey(monoBehaviour.gameObject, "TaskList") == false)
                return null;
            else
                utilsTools.getUserData<Queue<Tuple<TaskItemBack, System.Object[]>>>(monoBehaviour.gameObject, "TaskList", out taskInfos, null);
            if (taskInfos.Count == 0) return null;
            ret = taskInfos.Dequeue();
            utilsTools.setUserData(monoBehaviour.gameObject, "TaskList", taskInfos);
        }
        return ret;
    }
    public bool updateTask(MonoBehaviour monoBehaviour)
    {
        int uid = monoBehaviour.GetInstanceID();
        if(taskSize.ContainsKey(uid) == false) { return false; }
        if (taskSize[uid] <= 0) {  return false; }//尽快返回，减少组件折腾
        var task = getTask(monoBehaviour);
        if (task == null) return false;
        task.Item1(task.Item2);
        taskSize[uid] = taskSize[uid] - 1;
        return true;
    }
    public void clearAllTask(MonoBehaviour monoBehaviour)
    {
        int uid = monoBehaviour.GetInstanceID();
        if (taskSize.ContainsKey(uid) == false) return;
        utilsTools.delUserDataByKey(monoBehaviour.gameObject, "PriorityStack");
        utilsTools.delUserDataByKey(monoBehaviour.gameObject, "TaskList");
        taskSize.Remove(uid);
    }
    
}
