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

namespace ScrapYard
{
  [Gadget("ScrapYard")]
  public class ScrapYard : Gadget<ScrapYard>
  {
    public const string MOD_VERSION = "1.2"; // 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.

    protected override void LoadConfig()
    {
      Config.Load();

      string fileVersion = Config.ReadString("ConfigVersion", CONFIG_VERSION, comments: "The Config Version (not to be confused with mod version)");

      if (fileVersion != CONFIG_VERSION)
      {
        Config.Reset();
        Config.WriteString("ConfigVersion", CONFIG_VERSION, comments: "The Config Version (not to be confused with mod version)");
      }

      Config.Save();
    }

    public override string GetModDescription()
    {
      return "A mod that adds a scryp yard planet.";
    }

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

      Texture2D texturePlanetIcon = GadgetCoreAPI.LoadTexture2D("planetScrapYard.png");
      Texture2D texturePlanetPrevIcon = GadgetCoreAPI.LoadTexture2D("planetScrapYardPrev.png");
      Texture2D texturePortalSign = GadgetCoreAPI.LoadTexture2D("signScrapYard.png");

      Texture2D textureBG = GadgetCoreAPI.LoadTexture2D("bgScrapYard.png");
      Texture2D textureBGExtension = GadgetCoreAPI.LoadTexture2D("bgScrapYardExtension.png");
      Texture2D textureBGTop = GadgetCoreAPI.LoadTexture2D("bgScrapYardTop.png");

      Texture2D textureParalex = GadgetCoreAPI.LoadTexture2D("parallax.png");
      Texture2D textureParalex0 = GadgetCoreAPI.LoadTexture2D("bScrapYardbg0.png");
      Texture2D textureParalex1 = GadgetCoreAPI.LoadTexture2D("bScrapYardbg1.png");
      Texture2D textureParalex2 = GadgetCoreAPI.LoadTexture2D("bScrapYardbg2.png");
      Texture2D textureParalex3 = GadgetCoreAPI.LoadTexture2D("bScrapYardbg3.png");

      Texture2D textureEntrance = GadgetCoreAPI.LoadTexture2D("entranceScrapYard.png");
      Texture2D textureSmallSide = GadgetCoreAPI.LoadTexture2D("sideSmallScrapYard.png");
      Texture2D textureBigSide = GadgetCoreAPI.LoadTexture2D("sideBigScrapYard.png");

      Texture2D textureMid0 = GadgetCoreAPI.LoadTexture2D("midScrapYardChunk0.png");
      Texture2D textureMid1 = GadgetCoreAPI.LoadTexture2D("midScrapYardChunk1.png");

      Texture2D textureScrapTrophy = GadgetCoreAPI.LoadTexture2D("iScrapTrophy.png");

      Logger.Log("Loaded Textures");

      PlanetInfo scrapYardPlanet = new PlanetInfo(PlanetType.SPECIAL, "Scrap Yard", new GadgetCore.Util.Tuple<int, int>[] { new GadgetCore.Util.Tuple<int, int>(1, 100) });
      scrapYardPlanet.SetPortalInfo(texturePortalSign, texturePlanetPrevIcon, texturePlanetIcon);
      scrapYardPlanet.SetBackgroundInfo(textureParalex, textureParalex0, textureParalex1, textureParalex2, textureParalex3);
      scrapYardPlanet.SetTerrainInfo(textureEntrance, textureBG, textureMid0, textureMid1, textureBigSide, textureSmallSide);

      scrapYardPlanet.OnGenerateWorld += ScrapYardGenerator.GenarateTown;
      scrapYardPlanet.Register("Scrap Yard");

      scrapYardPlanet.PortalUses = -1;

      Logger.Log("Created Planet");

      new ItemInfo(ItemType.GENERIC, "Scrap Trophy", "A rusty trophy.\nUsed for purchasing\nspecial items.", textureScrapTrophy).Register("Scrap Trophy");

      { // Scrap Yard Bulding
        var scrapYardShopBuilding = Object.Instantiate((GameObject)Resources.Load("prop/2501"));
        scrapYardShopBuilding.transform.localScale *= 8;
        Texture2D texture = GadgetCoreAPI.LoadTexture2D("shopStand.png");
        var renderer = scrapYardShopBuilding.GetComponentInChildren<Renderer>();
        renderer.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = texture
        };
        GadgetCoreAPI.AddCustomResource("prop/ScrapYard/scrapYardShopBuilding", scrapYardShopBuilding);
      }

      { // Scrap Yard Shop Owner
        var scrapYardMerchant = Object.Instantiate((GameObject)Resources.Load("npc/perceval"));
        Texture2D textureBody = GadgetCoreAPI.LoadTexture2D("merchantBody.png");
        Texture2D textureHead = GadgetCoreAPI.LoadTexture2D("merchantHead.png");

        var gameObjectBody = scrapYardMerchant.transform.Find("e").Find("perceval").FindChild("Plane_002");
        var rendererBody = gameObjectBody.gameObject.GetComponentInChildren<Renderer>();
        rendererBody.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = textureBody
        };

        var gameObjectHead = scrapYardMerchant.transform.Find("e").Find("perceval").FindChild("Plane");
        var rendererHead = gameObjectHead.gameObject.GetComponentInChildren<Renderer>();
        rendererHead.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = textureHead
        };

        //scrapYardMerchant.layer = 0;

        scrapYardMerchant.transform.Find("e").rotation = Quaternion.Euler(0f, 180f, 0f);

        scrapYardMerchant.name = "scrapyardmerchant";

        Component.DestroyImmediate(scrapYardMerchant.GetComponent<npcTurnScript>());
        GadgetCoreAPI.AddCustomResource("prop/ScrapYard/scrapYardMerchant", scrapYardMerchant);

        TileInfo tile = new TileInfo(TileType.INTERACTIVE, null as Texture2D, new GameObject("scrapyardmerchant")).Register("scrapyardmerchant");
        tile.OnInteract += OnInteractMerchant;
      }

      { // Part Semicolider Platform
        var asset = GadgetCoreAPI.LoadAssetBundle("platform");
        var platform = UnityEngine.Object.Instantiate((GameObject)asset.LoadAsset("assets/resources/platform.prefab"));
        GadgetCoreAPI.AddCustomResource("prop/ScrapYard/component/platform", platform);
      }

      { // Bottom Chunk
        var gameObject = Object.Instantiate((GameObject)Resources.Load("z/chunk"));

        var rendererBody = gameObject.GetComponentInChildren<Renderer>();
        rendererBody.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = textureBG
        };

        for (int i = 0; i < 6; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(0).gameObject);
        for (int i = 0; i < 16; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(1).gameObject);

        gameObject.transform.GetChild(0).GetChild(7).localScale += new Vector3(1.5f, 0, 0);
        GameObject.DestroyImmediate(gameObject.transform.GetChild(0).GetChild(5).gameObject);
        GameObject.DestroyImmediate(gameObject.transform.GetChild(0).GetChild(1).gameObject);

        Component.DestroyImmediate(gameObject.GetComponent<Chunk>());

        var platformComponent = Object.Instantiate((GameObject)Resources.Load("prop/ScrapYard/component/platform"));
        platformComponent.transform.SetParent(gameObject.transform);
        platformComponent.transform.localScale = new Vector3(0.5625f, 10, 1);
        platformComponent.transform.localPosition = new Vector3(0, 0.25f, 0);
        platformComponent.transform.localRotation = Quaternion.Euler(90, 0, 0);

        GadgetCoreAPI.AddCustomResource("z/ScrapYard/chunkBase", gameObject);
      }

      { // Extension Chunk
        var gameObject = Object.Instantiate((GameObject)Resources.Load("z/chunk"));

        var rendererBody = gameObject.GetComponentInChildren<Renderer>();
        rendererBody.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = textureBGExtension
        };

        for (int i = 0; i < 6; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(0).gameObject);
        for (int i = 0; i < 16; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(1).gameObject);

        for (int i = 0; i < 6; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(0).GetChild(0).gameObject);

        gameObject.transform.GetChild(0).GetChild(0).localScale = new Vector3(0.4375f, 2, 1);
        gameObject.transform.GetChild(0).GetChild(0).localPosition = new Vector3(0.78125f, 0, 0);

        gameObject.transform.GetChild(0).GetChild(1).localScale = new Vector3(0.4375f, 2, 1);
        gameObject.transform.GetChild(0).GetChild(1).localPosition = new Vector3(-0.78125f, 0, 0);

        Component.DestroyImmediate(gameObject.GetComponent<Chunk>());
        GadgetCoreAPI.AddCustomResource("z/ScrapYard/chunkExtension", gameObject);
      }

      { // Top Chunk
        var gameObject = Object.Instantiate((GameObject)Resources.Load("z/chunk"));

        var rendererBody = gameObject.GetComponentInChildren<Renderer>();
        rendererBody.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = textureBGTop
        };

        for (int i = 0; i < 6; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(0).gameObject);
        for (int i = 0; i < 16; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(1).gameObject);

        for (int i = 0; i < 5; i++)
          GameObject.DestroyImmediate(gameObject.transform.GetChild(0).GetChild(0).gameObject);

        gameObject.transform.GetChild(0).GetChild(0).localPosition = new Vector3(0.78125f, 0, 0);
        gameObject.transform.GetChild(0).GetChild(0).localScale = new Vector3(0.4375f, 2, 1);

        gameObject.transform.GetChild(0).GetChild(1).localPosition = new Vector3(-0.78125f, 0, 0);
        gameObject.transform.GetChild(0).GetChild(1).localScale = new Vector3(0.4375f, 2, 1);

        gameObject.transform.GetChild(0).GetChild(2).localPosition = new Vector3(0, 0.5f, 0);
        gameObject.transform.GetChild(0).GetChild(2).localScale = new Vector3(2f, 0.5f, 1);

        Component.DestroyImmediate(gameObject.GetComponent<Chunk>());
        GadgetCoreAPI.AddCustomResource("z/ScrapYard/chunkTop", gameObject);
      }

      { // Platform
        var gameObject = Object.Instantiate((GameObject)Resources.Load("prop/2501"));
        gameObject.transform.localScale = new Vector3(12, 2, 1);
        Texture2D texture = GadgetCoreAPI.LoadTexture2D("metalPlatform.png");
        var renderer = gameObject.GetComponentInChildren<Renderer>();
        renderer.material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = texture
        };
        var platformComponent = Object.Instantiate((GameObject)Resources.Load("prop/ScrapYard/component/platform"));
        platformComponent.transform.SetParent(gameObject.transform);
        platformComponent.transform.localScale = new Vector3(2, 2, 1);
        platformComponent.transform.localPosition = new Vector3(0, 0, 0);
        GadgetCoreAPI.AddCustomResource("prop/ScrapYard/metalPlatform", gameObject);
      }

      { // Shop Stand
        var asset = GadgetCoreAPI.LoadAssetBundle("scrapyardstand");
        var scrapYardStand = UnityEngine.Object.Instantiate((GameObject)asset.LoadAsset("assets/resources/scrapyardstand.prefab"));
        scrapYardStand.SetActive(false);
        scrapYardStand.AddComponent<ScrapYardShopStandScript>();
        scrapYardStand.name = "scrapyardstand";
        GadgetCoreAPI.AddCustomResource("prop/ScrapYard/stand", scrapYardStand);

        scrapYardStand.transform.GetChild(0).GetComponent<Renderer>().material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = GadgetCoreAPI.LoadTexture2D("scrapYardStand.png")
        };

        scrapYardStand.transform.GetChild(2).GetComponent<Renderer>().material = new Material(Shader.Find("Unlit/Transparent"))
        {
          mainTexture = GadgetCoreAPI.LoadTexture2D("scrapYardStandInfo.png")
        };

        TileInfo tile = new TileInfo(TileType.INTERACTIVE, null as Texture2D, new GameObject("scrapyardstand")).Register("scrapyardstand");
        tile.OnInteract += OnInteractStand;
      }

      Logger.Log("Created Prefabes");

      // Setting up default shop platforms
      new ShopPlatform("Default Objects", ShopPlatformSpacingType.Near).Register();
      new ShopPlatform("Default Blocks", ShopPlatformSpacingType.Near).Register();
      new ShopPlatform("Default Walls", ShopPlatformSpacingType.Near).Register();

      ShopPlatform.DefaultBlocks.AddShopPlatformEntry(new ShopPlatformEntry(2000, 100));
      ShopPlatform.DefaultBlocks.AddShopPlatformEntry(new ShopPlatformEntry(2001, 100));
      ShopPlatform.DefaultBlocks.AddShopPlatformEntry(new ShopPlatformEntry(2002, 500));
      ShopPlatform.DefaultBlocks.AddShopPlatformEntry(new ShopPlatformEntry(2400, 7000));

      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2100, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2101, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2102, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2103, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2104, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2105, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2106, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2107, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2108, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2403, 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(ItemRegistry.GetItemIDByRegistryName("Gadget Core:Crafter Block"), 10));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2401, 1000));
      ShopPlatform.DefaultObjects.AddShopPlatformEntry(new ShopPlatformEntry(2402, 1000));

      ShopPlatform.DefaultWalls.AddShopPlatformEntry(new ShopPlatformEntry(2200, 50));

      Logger.Log("Added Default Objects to the Planet");

      SceneManager.sceneLoaded += OnSceneLoaded;

      Logger.Log("Added Scene Hook");
    }

    internal static void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
      if (scene.buildIndex == 1)
      {
        try
        {
          var storageMenu = GameObject.Find("Ship").transform.Find("SHIPPLACES").transform.Find("mech").localPosition = new Vector3(-130f, -5.23f, 0.6f);
          Core.logger.Log("Moved the Mech");
        }
        catch (System.Exception e) { Core.logger.LogError(e.Message); }
      }
    }

    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);

    private IEnumerator OnInteractStand()
    {
      Core.logger.Log("Start Interaction Stand");
      try
      {
        PlayerScript.curInteractObj.SendMessage("Request");
        Core.logger.Log("Requested Item");
        canInteractField.SetValue(InstanceTracker.PlayerScript, true);
        interactingField.SetValue(InstanceTracker.PlayerScript, false);
        InstanceTracker.PlayerScript.w.SetActive(true);
        Core.logger.Log("Finished Interaction Stand");
      }
      catch(System.Exception e)
      {
        Core.logger.Log(e);
      }
      yield break;
    }

    public static readonly Material merchantPortraitMaterial = new Material(Shader.Find("Unlit/Transparent"))
    {
      mainTexture = GadgetCoreAPI.LoadTexture2D("merchantPortrait.png"),
      mainTextureScale = new Vector2(0.5f, 1)
    };

    public static readonly FieldInfo curAField = typeof(GameScript).GetField("curA", BindingFlags.NonPublic | BindingFlags.Instance);
    public static readonly FieldInfo curBField = typeof(GameScript).GetField("curB", BindingFlags.NonPublic | BindingFlags.Instance);
    public static readonly FieldInfo curCField = typeof(GameScript).GetField("curC", BindingFlags.NonPublic | BindingFlags.Instance);

    private IEnumerator OnInteractMerchant()
    {
      InstanceTracker.GameScript.hoverItem.SetActive(false);

      if (GameScript.inventoryOpen)
      {
        InstanceTracker.GameScript.inventoryMain.SetActive(false);
        GameScript.inventoryOpen = false;
      }

      InstanceTracker.GameScript.talkingPortrait.GetComponent<Renderer>().material = merchantPortraitMaterial;
      InstanceTracker.GameScript.txtTalkingName[0].text = "Ito";
      InstanceTracker.GameScript.txtTalkingName[1].text = InstanceTracker.GameScript.txtTalkingName[0].text;
      InstanceTracker.GameScript.StartCoroutine(InstanceTracker.GameScript.EnterTalking2());
      InstanceTracker.GameScript.menuTalking.SendMessage("Set", "Haz a look at my warez!!!");

      canInteractField.SetValue(InstanceTracker.PlayerScript, false);
      interactingField.SetValue(InstanceTracker.PlayerScript, false);
      curAField.SetValue(InstanceTracker.GameScript, -1);
      curBField.SetValue(InstanceTracker.GameScript, -1);
      curCField.SetValue(InstanceTracker.GameScript, -1);
      yield break;
    }
  }
}
