using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UnityEngine.Events;

namespace WS
{
    [ObjectSystem]
    public class ProcessManagerAwakeSystem : AwakeSystem<ProcessManager>
    {
        public override void Awake(ProcessManager self)
        {
            self.Awake();
        }
    }

    [ObjectSystem]
    public class ProcessManagerUpdateSystem : UpdateSystem<ProcessManager>
    {
        public override void Update(ProcessManager self)
        {
            self.Update();
        }
    }

    ///<summary>流程管理组件</summary>
    public partial class ProcessManager : WSComponent
    {
        ///<summary>流程状态</summary>
        public enum StateType
        {
            ///<summary>未开始</summary>
            NotStarted,
            ///<summary>运行中</summary>
            Runing,
            ///<summary>暂停中</summary>
            Pause
        }

        ///<summary>状态</summary>
        private StateType State;
        ///<summary>流程数据</summary>
        private List<Module> Config = new List<Module>();
        ///<summary>所有模块</summary>
        private List<ModuleComponent> Modules = new List<ModuleComponent>();
        ///<summary>任务记录</summary>
        private List<WSTaskRecord> VTaskRecords = new List<WSTaskRecord>();
        ///<summary>当前模块</summary>
        private ModuleComponent CurrentModule;
        ///<summary>分数</summary>
        public float Score;
        ///<summary>流程结束回调</summary>
        public UnityAction OnEndProcessCallback;
        ///<summary>完成任务回调</summary>
        public UnityAction<int> OnCompleteVTaskCallback;
        ///<summary>完成模块回调</summary>
        public UnityAction<string> OnCompleteModuleCallback;

        /// <summary>开始时间</summary>
        public DateTime ST;
        /// <summary>结束时间</summary>
        public DateTime ET;
        public string m = "api";
        public string md;
        public int course;
        public int branch;


        public void Awake()
        {
            StartType();
        }

        public void Update()
        {
            if (State == StateType.Runing)
            {
                if (CurrentModule != null)
                {
                    if (!CurrentModule.IsComplete)
                        CurrentModule.Update();
                    else
                        SwitchModule(CurrentModule.Id);
                }
            }
        }

        ///<summary>开始流程</summary>
        public void StartProcess(string ConfigFileName)
        {
            if (State == StateType.NotStarted)
            {
                Score = 0;
                VTaskRecords.Clear();
                Config = ConfigHelper.LoadConfig<List<Module>>($"Config/Process/{ConfigFileName}");
                for (int i = 0; i < Config.Count; i++)
                {
                    ModuleComponent module = ComponentFactory.CreateWithParent<ModuleComponent>(this);
                    module.Data = Config[i];
                    Modules.Add(module);
                }
                ST = DateTime.Now;
#if UNITY_EDITOR||DEBUG_MODEL
                Log.LogDebug("开始流程", WSLogType.橙);
#endif
                SwitchModule(0);
                State = StateType.Runing;
            }
            else
                Log.LogError("开始流程失败,流程已开始!");
        }

        ///<summary>暂停流程</summary>
        public void PauseProcess()
        {
            if (State == StateType.Runing)
                State = StateType.Pause;
            else
                Log.LogError("暂停失败,流程未运行");
        }

        ///<summary>继续流程</summary>
        public void UnPauseProcess()
        {
            if (State == StateType.NotStarted)
                Log.LogError("继续失败,流程未运行");
            else
                State = StateType.Runing;
        }

        ///<summary>结束流程</summary>
        ///<param name="initiative">主动结束</param>
        public void EndProcess(bool initiative = false)
        {
            for (int i = 0; i < Modules.Count; i++)
            {
                Score += Modules[i].Score;
                Modules[i].Dispose();
            }
            Modules.Clear();
            CurrentModule = null;
            if (!initiative)
                OnEndProcessCallback?.Invoke();
            State = StateType.NotStarted;
            ET = DateTime.Now;
#if UNITY_EDITOR||DEBUG_MODEL
            Log.LogDebug("流程结束", WSLogType.橙);
#endif
        }

        ///<summary>下一个模块</summary>
        public async Task NextModule()
        {
            if (State == StateType.Runing)
            {
                await CurrentModule.NextModule();
                CurrentModule.Settlement();
                CurrentModule.IsComplete = true;
            }
        }

        ///<summary>跳转步骤</summary>
        ///<param name="Id">任务Id</param>
        public async Task JumpProcess(int Id)
        {
            if (State == StateType.Runing)
            {
                PauseProcess();
                if (CurrentModule.VTaskId < Id)
                {
                    for (int i = CurrentModule.Id - 1; i < Modules.Count; i++)
                    {
                        bool exists = await Modules[i].JumpVTask(Id, false);
                        if (exists)
                        {
                            CurrentModule = Modules[i];
                            break;
                        }
                    }
                }
                else
                {
                    for (int i = CurrentModule.Id - 1; i < Modules.Count; i--)
                    {
                        bool exists = await Modules[i].JumpVTask(Id, true);
                        if (exists)
                        {
                            CurrentModule = Modules[i];
                            break;
                        }
                    }
                }
                UnPauseProcess();
            }
        }

        ///<summary>上一步</summary>
        public async Task LastProcess()
        {
            if (State == StateType.Runing)
            {
                if (CurrentModule.VTaskId > 1)
                {
                    PauseProcess();
                    bool succeed = await CurrentModule.LastVTask(false);
                    if (!succeed)
                    {
                        int index = CurrentModule.Id - 1;
                        if (index > 0)
                        {
                            ModuleComponent module = Modules[index - 1];
                            await module.LastVTask(true);
                            module.IsComplete = false;
                            CurrentModule = module;
                        }
                    }
                    UnPauseProcess();
                }
            }
        }

        ///<summary>下一步</summary>
        public async Task NextProcess()
        {
            if (State != StateType.NotStarted)
            {
                PauseProcess();
                await CurrentModule.NextVTask();
                UnPauseProcess();
            }
        }

        ///<summary>提示</summary>
        public void Prompt()
        {
            CurrentModule.Prompt();
        }
        ///<summary>获取当前模块</summary>
        public ModuleComponent GetCurrentModule()
        {
            return CurrentModule;
        }
        ///<summary>当前任务是不是场景</summary>
        public bool IsScene()
        {
            var id = CurrentModule.VTaskId;
            return CurrentModule.GetVTask(id).Data.Operates[0].Component == "LoadSceneComponent";
        }
        #region -- 任务记录 --

        ///<summary>添加任务记录</summary>
        public void AddVTaskRecord(WSTaskRecord record)
        {
            if (!VTaskRecords.Exists(t => t.Id == record.Id))
            {
                VTaskRecords.Add(record);
            }
        }

        ///<summary>获取任务记录</summary>
        public WSTaskRecord GetVTaskRecord(int id)
        {
            return VTaskRecords.Find(t => t.Id == id);
        }

        ///<summary>获取错误任务记录</summary>
        public List<WSTaskRecord> GetErrorVTaskRecord()
        {
            return VTaskRecords.FindAll(t => t.IsError);
        }

        ///<summary>获取所有任务记录</summary>
        public List<WSTaskRecord> GetAllVTaskRecord()
        {
            return VTaskRecords;
        }

        #endregion

        ///<summary>创建/获取操作组件</summary>
        public BaseOperate GetOperate(Operate data, WSTaskComponent parent)
        {
            Type type = GetToType(data.Component);
            BaseOperate operate = (BaseOperate)ComponentFactory.CreateWithParent(type, parent);
            operate.Id = data.Id;
            operate.Describe = data.Describe;
            operate.InitData(data.Json);
            operate.Init();
            return operate;
        }

        ///<summary>获取任务列表</summary>
        public List<WSTaskList> GetVTaskList()
        {
            List<WSTaskList> list = new List<WSTaskList>();
            for (int i = 0; i < Config.Count; i++)
            {
                if (!Config[i].NoTaskbar)
                {
                    for (int j = 0; j < Config[i].WSTasks.Count; j++)
                    {
                        if (!Config[i].WSTasks[j].NoTaskbar)
                            list.Add(new WSTaskList { Id = Config[i].WSTasks[j].Id, Module = Config[i].Name, Name = Config[i].WSTasks[j].Name });
                    }
                }
            }
            return list;
        }

        ///<summary>获取任务</summary>
        public WSTaskComponent GetVTask(int vtaskid)
        {
            for (int i = 0; i < Modules.Count; i++)
            {
                WSTaskComponent component = Modules[i].GetVTask(vtaskid);
                if (component != null)
                    return component;
            }
            return null;
        }
        //获取流程状态
        public StateType GetProcessStatus()
        {
            return State;
        }
        ///<summary>切换模块</summary>
        private void SwitchModule(int id)
        {
            if (Modules.Count > id)
            {
                if (CurrentModule != null)
                {
                    if (!CurrentModule.NoTaskbar)
                        OnCompleteModuleCallback?.Invoke(CurrentModule.Name);
                }
                CurrentModule = Modules[id];
                CurrentModule.StartModule();
            }
            else
                EndProcess();
        }
    }
}