using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.Injection;
using UnityEngine;

namespace Sk0liosis_Enhanced;

[BepInPlugin(MyPluginInfo.PLUGIN_GUID, MyPluginInfo.PLUGIN_NAME, MyPluginInfo.PLUGIN_VERSION)]
public class Plugin : BasePlugin
{
    internal static new ManualLogSource Log;
    private readonly Harmony _harmony = new("Sk0liosis");
    public static ConfigEntry<bool> hardMode;

    public override void Load()
    {
        hardMode = Config.Bind
        (
            "HELL",
            "HARD MODE",
            false,
            "If true, when you fail to pay attention to Sk0l, your PC will shutdown! (will not function on Linux)"
        );
        
        Log = base.Log;
        Log.LogInfo("Did you know about THIS ureleased feature in Rec Room?");
        _harmony.PatchAll();
        
        MethodInfo registerMethod = typeof(ClassInjector)
            .GetMethods(BindingFlags.Public | BindingFlags.Static)
            .FirstOrDefault(m => m.Name == "RegisterTypeInIl2Cpp" && m.IsGenericMethodDefinition);

        IEnumerable<Type> il2cppTypes = Assembly.GetExecutingAssembly().GetTypes()
            .Where(t => t.IsClass && !t.IsAbstract && t.IsSubclassOf(typeof(MonoBehaviour)))
            .Where(t => t.Namespace == "Sk0liosis_Enhanced")
            .Where(t => t.GetConstructor(new[] { typeof(IntPtr) }) != null);

        foreach (Type type in il2cppTypes)
        {
            registerMethod?.MakeGenericMethod(type).Invoke(null, null);
        }
    }
}