using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using Unity.VisualScripting;


namespace MPStudio
{
    
    
    interface IEventMsg
    {
    }

    class EventMsg<T> : IEventMsg
    {
        internal Action<T> act;

        internal EventMsg(Action<T> a)
        {
            this.act += a;
        }
    }

    class EventMsg : IEventMsg
    {
        internal Action act;

        internal EventMsg(Action a)
        {
            this.act += a;
        }
    }
    
    /*
    class MyArg<T> : EventMsg<T>
    {
        public int arg = 5;
        internal MyArg(Action<T> a) : base(a)
        {
        }
    }
    */
   public class MyArg2
    {
        public int age = 5;

        public MyArg2(int age)
        {
            this.age = age;
        }
    }
   
    public class MyArg3
    {
        public int age = 5;
    }

    class EventCenter
    {
        private Dictionary<string, IEventMsg> eventDict = new Dictionary<string, IEventMsg>();

        internal void AddEvent(string eventName, Action act)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg).act += act;
            }
            else
            {
                eventDict.Add(eventName, new EventMsg(act));
            }
        }

        internal void AddEvent<T>(string eventName, Action<T> act)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg<T>).act += act;
            }
            else
            {
                eventDict.Add(eventName, new EventMsg<T>(act));
            }
        }

        internal void SendEvent(string eventName)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg).act();
            }
        }

        internal void SendEvent<T>(string eventName, T obj)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg<T>).act(obj);
            }
        }

        internal void RemoveEvent(string eventName, Action act)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg).act -= act;
            }
        }

        internal void RemoveEvent<T>(string eventName, Action<T> act)
        {
            if (eventDict.ContainsKey(eventName))
            {
                (eventDict[eventName] as EventMsg<T>).act -= act;
            }
        }

        internal void ClearEvent()
        {
            eventDict.Clear();
        }
    }
    
    [DisallowMultipleComponent]
    [DefaultExecutionOrder(-1)]
    public class EventManager : MonoBehaviour
    {
        public static EventManager Inst { get; private set; }

        private EventCenter _eventManager = new EventCenter();

        protected virtual void Awake()
        {
            if (Inst == null)
            {
                Inst = this;
            }
            else if (Inst != this)
            {
                Destroy(gameObject);
            }
        }

        protected virtual void Start()
        {
            print("hello world");
        }

        public void TestEventManager()
        {
            MyArg2 m = new MyArg2(3);
            AddEvent<MyArg2>("gStart",(arg2 =>
            {
                int myage = 3;
                if(myage==arg2.age)
                    print("f1:"+arg2.age);
            } ));
            AddEvent<MyArg2>("gStart",this.MyArgEvent);
            RemoveEvent<MyArg2>("gStart",this.MyArgEvent);
            //ClearEvent();
            AddEvent<MyArg2>("gStart",this.MyArgEvent);
            SendEvent<MyArg2>("gStart", m);
            
            AddEvent<MyArg3>("gg",this.MyArgEvent3);
            SendEvent<MyArg3>("gg",new MyArg3());
        }

        public void MyArgEvent3(MyArg3 arg2)
        {
                      //  print("f3 arg3:"+arg2.age);
        }

        public void MyArgEvent(MyArg2 arg2)
        {
            int myage = 2;
            if(myage==arg2.age)
            print("f2:"+arg2.age);
        }

        internal void AddEvent(string eventName, Action act)
        {
            _eventManager.AddEvent(eventName, act);
        }

        internal void AddEvent<T>(string eventName, Action<T> act)
        {
            _eventManager.AddEvent<T>(eventName, act);
        }

        internal void SendEvent(string eventName)
        {
            _eventManager.SendEvent(eventName);
        }

        internal void SendEvent<T>(string eventName, T obj)
        {
            _eventManager.SendEvent(eventName, obj);
        }

        internal void RemoveEvent(string eventName, Action act)
        {
            _eventManager.RemoveEvent(eventName, act);
        }

        internal void RemoveEvent<T>(string eventName, Action<T> act)
        {
            _eventManager.RemoveEvent(eventName, act);
        }
        
        internal void ClearEvent()
        {
            _eventManager.ClearEvent();
            
        }
    }
}