using UnityEngine;
using Bolt;
/// 
/// 蓝图管理器
/// 蓝图分为两种,不用保存中间状态的直接执行,执行后销毁入池;需要保存状态的返回对象,由创建者销毁入池
/// 
namespace Game
{
    public enum EBpState
    {
        Enter,
        Update,
        Leave,
    }
    public class BlueprintBasicData
    {
        public int Entity;
        public int Target;
        public int Owner;
    }
    public class BlueprintPoolItem : ObjectPoolItemBase
    {
        public GameObject m_GameObject;
        public FlowMachine m_FlowMachine;
        public VariableDeclarations m_Variables;
        protected override void OnCreate()
        {
            base.OnCreate();
        }
        protected override void OnDestroy()
        {
            base.OnDestroy();
        }
    }
    public class BlueprintPoolManager : ObjectPoolBase
    {
        private readonly string m_BlueprintPath = "Blueprint/";
        private BlueprintBasicData m_DefaultBlueprintBasicData = new BlueprintBasicData();
        public void Run(string name, string trigger, BlueprintBasicData data)
        {
            var bp = CreateBlueprint(name);
            SetData(bp, data);
            bp.m_FlowMachine.TriggerUnityEvent(trigger);
            bp.Destroy();
        }
        private void SetData(BlueprintPoolItem bpItem, BlueprintBasicData data)
        {
            if (data == null)
            {
                data = m_DefaultBlueprintBasicData;
            }
            var obj = bpItem.m_Variables;
            obj.Set("entity", data.Entity);
            obj.Set("target", data.Target);
            obj.Set("owner", data.Owner);
            obj.Set("data", data);
        }
        private BlueprintPoolItem CreateBlueprint(string name)
        {
            var bpNew = Create(name, (item) =>
            {
                var go = new GameObject(name);
                var flowMacro = EnsureGetBulletFlowMacro(name);
                var flowMachine = go.AddComponent();
                flowMachine.nest.SwitchToMacro(flowMacro);
                item.m_FlowMachine = flowMachine;
                item.m_Variables = Variables.Object(go);
                go.transform.SetParent(BlueprintPoolManager.Instance.Root.transform);
                item.m_GameObject = go;
            });
            return bpNew;
        }
        private FlowMacro EnsureGetBulletFlowMacro(string path)
        {
            var pathReal = $"{m_BlueprintPath}{path}";
            return Util.Load(pathReal);
        }
    }
    public abstract partial class Util
    {
        public static void RunBp(string name, string trigger, BlueprintBasicData data)
        {
            BlueprintPoolManager.Instance.Run(name, trigger, data);
        }
        public static void RunBp(string name, string trigger)
        {
            BlueprintPoolManager.Instance.Run(name, trigger, null);
        }
    }
}