using Serein.Library;
using Serein.Library.Api;
using Serein.Library.Utils;
using Serein.NodeFlow.Model;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.Reflection;

namespace Serein.NodeFlow
{

    /// <summary>
    /// 流程环境需要的扩展方法
    /// </summary>
    public static class FlowNodeExtension
    {
        /// <summary>
        /// 判断是否为基础节点
        /// </summary>
        /// <returns></returns>
        public static bool IsBaseNode(this NodeControlType nodeControlType)
        {
            
            var nodeDesc = EnumHelper.GetAttribute<NodeControlType, DescriptionAttribute>(nodeControlType);
           if("base".Equals(nodeDesc?.Description, StringComparison.OrdinalIgnoreCase))
            {
                return true;
            }
            return false;
        }


        /// <summary>
        /// 创建节点
        /// </summary>
        /// <param name="env">运行环境</param>
        /// <param name="nodeControlType">节点类型</param>
        /// <param name="methodDetails">方法描述</param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public static IFlowNode CreateNode(IFlowEnvironment env, NodeControlType nodeControlType,
            MethodDetails? methodDetails = null)
        {

            // 尝试获取需要创建的节点类型

            if (!env.NodeMVVMManagement.TryGetType(nodeControlType, out var nodeMVVM) || nodeMVVM.ModelType == null)
            {
                throw new Exception($"无法创建{nodeControlType}节点，节点类型尚未注册。");
            }

            // 生成实例
            var nodeObj = Activator.CreateInstance(nodeMVVM.ModelType, env);
            if (nodeObj is not IFlowNode nodeModel)
            {
                throw new Exception($"无法创建目标节点类型的实例[{nodeControlType}]");
            }

            // 配置基础的属性
            nodeModel.ControlType = nodeControlType;
            if (methodDetails == null) // 不存在方法描述时，可能是基础节点（表达式节点、条件表达式节点）
            {
                methodDetails = new MethodDetails();
            }
            var md = methodDetails.CloneOfNode(nodeModel);
            nodeModel.DisplayName = md.MethodAnotherName;
            nodeModel.MethodDetails = md;
            nodeModel.OnCreating();
            return nodeModel;
        }




        /// <summary>
        /// 程序集封装依赖
        /// </summary>
        /// <param name="libraryInfo"></param>
        /// <returns></returns>
        public static NodeLibraryInfo ToLibrary(this NodeLibraryInfo libraryInfo)
        {
            return new NodeLibraryInfo
            {
                AssemblyName = libraryInfo.AssemblyName,
                FileName = libraryInfo.FileName,
                FilePath = libraryInfo.FilePath,
            };
        }

        /// <summary>
        /// 触发器运行后状态转为对应的后继分支类别
        /// </summary>
        /// <param name="flowStateType"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public static ConnectionInvokeType ToContentType(this FlipflopStateType flowStateType)
        {
            return flowStateType switch
            {
                FlipflopStateType.Succeed => ConnectionInvokeType.IsSucceed,
                FlipflopStateType.Fail => ConnectionInvokeType.IsFail,
                FlipflopStateType.Error => ConnectionInvokeType.IsError,
                FlipflopStateType.Cancel => ConnectionInvokeType.None,
                _ => throw new NotImplementedException("未定义的流程状态")
            };
        }

        /// <summary>
        /// 判断 触发器节点 是否存在上游分支
        /// </summary>
        /// <param name="node"></param>
        /// <returns></returns>
        public static bool NotExitPreviousNode(this SingleFlipflopNode node)
        {
            ConnectionInvokeType[] ct = [ConnectionInvokeType.IsSucceed,
                                   ConnectionInvokeType.IsFail,
                                   ConnectionInvokeType.IsError,
                                   ConnectionInvokeType.Upstream];
            foreach (ConnectionInvokeType ctType in ct)
            {
                if (node.PreviousNodes[ctType].Count > 0)
                {
                    return false;
                }
            }
            return true;
        }


        ///// <summary>
        ///// 从节点类型枚举中转为对应的 Model 类型
        ///// </summary>
        ///// <param name="nodeControlType"></param>
        ///// <returns></returns>
        //public static Type? ControlTypeToModel(this NodeControlType nodeControlType)
        //{
        //    // 确定创建的节点类型
        //    Type? nodeType = nodeControlType switch
        //    {
        //        NodeControlType.Action => typeof(SingleActionNode),
        //        NodeControlType.Flipflop => typeof(SingleFlipflopNode),

        //        NodeControlType.ExpOp => typeof(SingleExpOpNode),
        //        NodeControlType.ExpCondition => typeof(SingleConditionNode),
        //        NodeControlType.ConditionRegion => typeof(CompositeConditionNode),
        //        _ => null
        //    };
        //    return nodeType;
        //}
        //public static NodeControlType ModelToControlType(this NodeControlType nodeControlType)
        //{
        //    var type = nodeControlType.GetType();
        //    NodeControlType controlType = type switch
        //    {
        //        Type when type == typeof(SingleActionNode) => NodeControlType.Action,
        //        Type when type == typeof(SingleFlipflopNode) => NodeControlType.Flipflop,

        //        Type when type == typeof(SingleExpOpNode) => NodeControlType.ExpOp,
        //        Type when type == typeof(SingleConditionNode) => NodeControlType.ExpCondition,
        //        Type when type == typeof(CompositeConditionNode) => NodeControlType.ConditionRegion,
        //        _ => NodeControlType.None,
        //    };
        //    return controlType;
        //}
    }

}
