﻿using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using JLGames.RocketDriver.Actions.Utils;
using JLGames.RocketDriver.CSharp.Languages.Lua;

namespace JLGames.RocketDriver.Actions.Languages.Lua
{
    public class UnityEventFunctions
    {
        private const string NameKey = "{{Name}}";
        private const string PatternFormat = "function {{Name}}";

        private static readonly string[] m_UnityEventFuncs;
        private static readonly Dictionary<string, string> m_RegexPatternMap = new Dictionary<string, string>();

        static UnityEventFunctions()
        {
            m_UnityEventFuncs = new[]
            {
                "Start", "OnDestroy", "OnGUI", "OnValidate",
                "Update", "FixedUpdate", "LateUpdate",
                "OnEnable", "OnDisable",
//                "OnConnectedToServer", "OnDisconnectedFromServer", "OnMasterServerEvent", "OnNetworkInstantiate", "OnSerializeNetworkView",
//                "OnFailedToConnect", "OnFailedToConnectToMasterServer",
                "OnServerInitialized",
                "OnAnimatorIK", "OnAnimatorMove",
                "OnApplicationFocus", "OnApplicationPause", "OnApplicationQuit",
                "OnBecameVisible", "OnBecameInvisible",
                "OnCollisionEnter", "OnCollisionEnter2D", "OnCollisionExit", "OnCollisionExit2D", "OnCollisionStay", "OnCollisionStay2D",
                "OnControllerColliderHit",
//                "OnDrawGizmos", "OnDrawGizmosSelected",
                "OnJointBreak", "OnJointBreak2D",
                "OnMouseDown", "OnMouseDrag", "OnMouseEnter", "OnMouseExit", "OnMouseOver", "OnMouseUp", "OnMouseUpAsButton",
//                "OnParticleUpdateJobScheduled","OnParticleSystemStopped",
                "OnParticleCollision", "OnParticleTrigger",
                "OnPlayerConnected", "OnPlayerDisconnected",
                "OnPostRender", "OnPreCull", "OnPreRender",
                "OnRenderImage", "OnRenderObject", "OnWillRenderObject",
                "OnTransformChildrenChanged", "OnTransformParentChanged",
                "OnTriggerEnter", "OnTriggerEnter2D", "OnTriggerExit", "OnTriggerExit2D", "OnTriggerStay", "OnTriggerStay2D",
                "Reset",
            };
            foreach (var name in m_UnityEventFuncs)
            {
                m_RegexPatternMap[name] = PatternFormat.Replace(NameKey, name);
            }
        }

        public static string[] UnityEventFuncs => m_UnityEventFuncs;

        public static bool Contains(string name)
        {
            return Array.IndexOf(m_UnityEventFuncs, name) != -1;
        }

        public static string GetRegexPattern(string name)
        {
            return m_RegexPatternMap.ContainsKey(name) ? m_RegexPatternMap[name] : "";
        }

        public static HashSet<string> StatEventSet(string luaCode)
        {
            if (string.IsNullOrEmpty(luaCode)) return null;
            var rs = new HashSet<string>();
            foreach (var pair in m_RegexPatternMap)
            {
                if (!Regex.IsMatch(luaCode, pair.Value))
                    continue;
                rs.Add(pair.Key);
            }

            return rs.Count == 0 ? null : rs;
        }

        public static void TryRunLuaFunction(LuaTable env, HashSet<string> set, string name)
        {
            if (null == env) return;
            if (null == set || set.Count == 0) return;
            if (!set.Contains(name)) return;
            RunLuaFunction(env, name);
        }

        public static void TryRunLuaFunction(LuaTable env, HashSet<string> set, string name, object paramName)
        {
            if (null == env) return;
            if (null == set || set.Count == 0) return;
            if (!set.Contains(name)) return;
            RunLuaFunction(env, name, paramName);
        }

        public static void RunLuaFunction(LuaTable env, string name)
        {
            LuaInterpreter.Interpreter($"{name}()", env);
        }

        public static void RunLuaFunction(LuaTable env, string name, object paramName)
        {
            LuaInterpreter.Interpreter($"{name}({paramName})", env);
        }
    }
}