using System;
using System.Reflection;

using Harmony;
// test
using Svelto.ECS;
using RobocraftX.Blocks;
using RobocraftX.Common;
using RobocraftX.SimulationModeState;

using GamecraftModdingAPI.Commands;
using GamecraftModdingAPI.Events;
using GamecraftModdingAPI.Utility;

namespace GamecraftModdingAPI.Tests
{
    // unused by design
    /// <summary>
    /// Modding API implemented as a standalone IPA Plugin.
    /// Ideally, GamecraftModdingAPI should be loaded by another mod; not itself
    /// </summary>
    public class GamecraftModdingAPIPluginTest
#if DEBUG
        : IllusionPlugin.IEnhancedPlugin
#endif
    {
        private static HarmonyInstance harmony { get; set; }

        public string[] Filter { get; } = new string[] { "Gamecraft" };

        public string Name { get; } = Assembly.GetExecutingAssembly().GetName().Name;

        public string Version { get; } = Assembly.GetExecutingAssembly().GetName().Version.ToString();

        public string HarmonyID { get; } = "org.git.exmods.modtainers.gamecraftmoddingapi";

        public void OnApplicationQuit()
        {
            GamecraftModdingAPI.Main.Shutdown();
        }

        public void OnApplicationStart()
        {
            GamecraftModdingAPI.Main.Init();
            // in case Steam is not installed/running
            // this will crash the game slightly later during startup
            //SteamInitPatch.ForcePassSteamCheck = true;
            // in case running in a VM
            //MinimumSpecsCheckPatch.ForcePassMinimumSpecCheck = true;
            // disable background music
            AudioTools.SetVolume(0.0f, "Music");

            /*if (!FMODUnity.RuntimeManager.HasBankLoaded("Modded"))
            {
                FMODUnity.RuntimeManager.LoadBank("Modded", true);
            }
            FMODUnity.RuntimeManager.PlayOneShot("event:/ModEvents/KillDashNine3D");*/

            // debug/test handlers
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("App Inited event!"); }, () => { },
                EventType.ApplicationInitialized, "appinit API debug"));
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Menu Activated event!"); },
                () => { Logging.Log("Menu Destroyed event!"); },
                EventType.Menu, "menuact API debug"));
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Menu Switched To event!"); }, () => { },
                EventType.MenuSwitchedTo, "menuswitch API debug"));
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Activated event!"); },
                () => { Logging.Log("Game Destroyed event!"); },
                EventType.Game, "gameact API debug"));
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Reloaded event!"); }, () => { },
                EventType.GameReloaded, "gamerel API debug"));
            EventManager.AddEventHandler(new SimpleEventHandlerEngine(() => { Logging.Log("Game Switched To event!"); }, () => { },
                EventType.GameSwitchedTo, "gameswitch API debug"));

            // debug/test commands
            CommandManager.AddCommand(new SimpleCustomCommandEngine(() => { UnityEngine.Application.Quit(); },
                "Exit", "Close Gamecraft without any prompts"));
            CommandManager.AddCommand(new SimpleCustomCommandEngine<float>((float d) => { UnityEngine.Camera.main.fieldOfView = d; },
                "SetFOV", "Set the player camera's field of view"));
            CommandManager.AddCommand(new SimpleCustomCommandEngine<float, float, float>(
                (x,y,z) => {
                    bool success = GamecraftModdingAPI.Blocks.Movement.MoveConnectedBlocks(
                        GamecraftModdingAPI.Blocks.BlockIdentifiers.LatestBlockID,
                        new Unity.Mathematics.float3(x, y, z));
                    if (!success)
                    {
                        GamecraftModdingAPI.Utility.Logging.CommandLogError("Blocks can only be moved in Build mode!");
                    }
                }, "MoveLastBlock", "Move the most-recently-placed block, and any connected blocks by the given offset"));
            /*CommandManager.AddCommand(new SimpleCustomCommandEngine(() => { FMODUnity.RuntimeManager.PlayOneShot("event:/ModEvents/KillDashNine2D"); },
                "Monzy", "Rap"));*/
        }

        public void OnFixedUpdate() { }

        public void OnLateUpdate() { }

        public void OnLevelWasInitialized(int level) { }

        public void OnLevelWasLoaded(int level) { }

        public void OnUpdate()
        {
            /*
            if (db != null && signalStrength != 0.0f && db.QueryUniqueEntity<SimulationModeStateEntityStruct>(SimulationModeStateExclusiveGroups.GAME_STATE_GROUP).simulationMode == SimulationMode.Simulation)
            {
                //GamecraftModdingAPI.Utility.Logging.MetaDebugLog("Simulation frame update");
                foreach (ref ElectricityEntityStruct powah in db.QueryEntities<ElectricityEntityStruct>(CommonExclusiveGroups.FUNCTIONAL_CUBES_IN_BOTH_SIM_AND_BUILD))
                {
                    ref ConductiveClusterID clusterId = ref db.QueryEntity<ConductiveClusterIdStruct>(powah.ID).clusterId;
                    GamecraftModdingAPI.Utility.Logging.MetaDebugLog($"ID {powah.ID.entityID} unmodded values: Power* {powah.powerMultiplier} Conductivity* {powah.conductivityMultiplier} Output* {powah.outputSignalMultiplier}");
                    uint operatingChannel = db.QueryEntity<SignalOperatingChannelStruct>(powah.ID).operatingChannel;
                    if (operatingChannel != 0)
                    {
                        EGID eGID = new EGID(operatingChannel, CommonExclusiveGroups.CHANNEL_OUTPUT_SIGNAL_GROUPS + clusterId.ID);
                        if (db.Exists<ChannelOutputSignalDataStruct>(eGID))
                        {
                            db.QueryEntity<ChannelOutputSignalDataStruct>(eGID).outputSignal = signalStrength;
                        }                        
                    }
                }
            }*/
        }
    }
}