using GadgetCore.API;
using GadgetCore.API.ConfigMenu;
using ScrapYard.API;
using System;
using System.Collections;
using System.Reflection;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace StasisPod
{
  [Gadget("StasisPod", LoadAfter: new string[] { "ScrapYard" }, Dependencies: new string[] { "ScrapYard" })]
  public class StasisPod : Gadget<StasisPod>
  {
    public const string MOD_VERSION = "1.0"; // Set this to the version of your mod.
    public const string CONFIG_VERSION = "1.0"; // Increment this whenever you change your mod's config file.

    public override IGadgetConfigMenu GetConfigMenu() { return null; }
    protected override void LoadConfig() { Config.Reset(); Config.Save(); }

    public override string GetModDescription()
    {
      return "A mod that adds a stasis pod which can be used to heal the player on the ship.";
    }

    protected override void Initialize()
    {
      Logger.Log("Stasis Pod v" + Info.Mod.Version);
      Core.logger = Logger;

      var asset = GadgetCoreAPI.LoadAssetBundle("stasispod");

      var tile = ItemUtil.CreatePlacableItem("stasisPod.png", "iStasisPod.png", "Stasis Pod", (GameObject)asset.LoadAsset("assets/resources/tileStasisPod.prefab"));

      Core.npcID = tile.GetID();
      if (Core.npcID == -1)
        throw new System.Exception("Could not register Tile " + "scrapyardmerchant");
      Core.itemStasisPodId = tile.Item.GetID();

      tile.OnInteract += OnInteractPod;

      GadgetCoreAPI.RegisterCustomRPC("SetPodInUse", delegate (object[] args)
      {
        StasisPodScript.CallEventSetRPC(args);
      });

      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(Core.itemStasisPodId, 1250));

      SceneManager.sceneLoaded += OnSceneLoaded;
    }

    internal static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
      if (scene.buildIndex == 1)
      {
        InstanceTracker.GameScript.StartCoroutine(HpLoop());
      }
    }

    private static int off = 0;

    private static IEnumerator HpLoop()
    {
      while (!Network.isServer && !Network.isClient)
      {
        yield return new WaitForSeconds(0.25f);
      }
      while (true)
      {
        off = (off + 1) % 3;
        yield return new WaitForSeconds(0.5f);
        if (PlayerScript.curInteractObj != null && PlayerScript.curInteractObj.GetComponent<StasisPodScript>() != null && PlayerScript.beamed)
        {
          if (off == 0) InstanceTracker.GameScript.RecoverHP(10);
          if (off == 1) InstanceTracker.GameScript.RecoverMana(10);
          if (off == 2) InstanceTracker.GameScript.RecoverStamina(10);
        }
        else
          yield return new WaitForSeconds(0.6f);
      }
    }

    public static readonly FieldInfo canInteractField = typeof(PlayerScript).GetField("canInteract", BindingFlags.NonPublic | BindingFlags.Instance);
    public static readonly FieldInfo interactingField = typeof(PlayerScript).GetField("interacting", BindingFlags.NonPublic | BindingFlags.Instance);
    public static readonly FieldInfo rField = typeof(PlayerScript).GetField("r", BindingFlags.NonPublic | BindingFlags.Instance);
    public static readonly FieldInfo tField = typeof(PlayerScript).GetField("t", BindingFlags.NonPublic | BindingFlags.Instance);
    //public static readonly FieldInfo interactingField = typeof(PlayerScript).GetField("interacting", BindingFlags.NonPublic | BindingFlags.Instance);

    private IEnumerator OnInteractPod()
    {
      try
      {
        var podScript = PlayerScript.curInteractObj.GetComponent<StasisPodScript>();
        if (podScript.CanUse() || PlayerScript.beamed)
        {
          var setUse = !PlayerScript.beamed;
          PlayerScript.beamed = setUse;
          InstanceTracker.PlayerScript.GetComponent<Collider>().enabled = !setUse;
          podScript.StartCallSet(setUse);
          ((Rigidbody)rField.GetValue(InstanceTracker.PlayerScript)).detectCollisions = !setUse;
          ((Rigidbody)rField.GetValue(InstanceTracker.PlayerScript)).useGravity = !setUse;
          ((Rigidbody)rField.GetValue(InstanceTracker.PlayerScript)).velocity = new Vector3(0f, 0f, 0f);
          ((Transform)tField.GetValue(InstanceTracker.PlayerScript)).position = new Vector3(PlayerScript.curInteractObj.transform.position.x, PlayerScript.curInteractObj.transform.position.y, 0f);
          //InstanceTracker.PlayerScript.playerTrigger.portal = null;
          InstanceTracker.PlayerScript.GetComponent<NetworkView>().RPC("Beam", RPCMode.All, new object[] { setUse ? 0 : 1 });
          InstanceTracker.PlayerScript.w.SetActive(true);
        }
        else
        {
          canInteractField.SetValue(InstanceTracker.PlayerScript, false);
          InstanceTracker.PlayerScript.w.SetActive(false);
        }
        interactingField.SetValue(InstanceTracker.PlayerScript, false);
      }
      catch (System.Exception e)
      {
        Core.logger.Log(e);
      }
      yield break;
    }
  }
}
