using GadgetCore.API;
using HarmonyLib;
using System;
using UnityEngine;

namespace StorageExpansion.Patches
{

  [HarmonyPatch(typeof(GameScript))]
  [HarmonyPatch("InitializeStorage")]
  [HarmonyGadget("StorageExpansion")]
  public static class Patch_GameScript_InitializeStorage
  {
    [HarmonyPrefix]
    public static bool Prefix(GameScript __instance, ref Item[] ___storage, ref GameObject ___storageSelect, ref GameObject[] ___storageButton,
      ref GameObject ___menuStorage, ref GameObject[] ___storageIcon, ref GameObject[] ___storageIconBack, ref TextMesh[] ___txtQStorage, ref TextMesh[] ___txtStorageCost)
    {
      if (Core.firstPrefabPath == null)
      {
        Core.firstPrefabPath = GetPrefabname();
        SetSizes();
      }
      var path = Core.firstPrefabPath;
      try
      {
        var asset = GadgetCoreAPI.LoadAssetBundle(path);

        var storageMenuOld = GameObject.Find("Main Camera").transform.Find("menuStorage").gameObject;
        GameObject.DestroyImmediate(storageMenuOld);

        var storageMenuNew = UnityEngine.Object.Instantiate((GameObject)asset.LoadAsset("assets/resources/menustorage.prefab"));
        storageMenuNew.SetActive(false);
        storageMenuNew.name = "menuStorage";
        storageMenuNew.transform.SetParent(GameObject.Find("Main Camera").transform);
        storageMenuNew.transform.localPosition = new Vector3(8, 1.5f, 2);
        storageMenuNew.transform.localScale = new Vector3(16, 16, 1);
      }
      catch (System.Exception e) { Core.logger.Log(e.Message); }

      ___storage = new Item[Core.settingAmountPages * Core.settingAmountSlots];
      for (int i = 0; i < (Core.settingAmountPages * Core.settingAmountSlots); i++)
      {
        ___storage[i] = new Item(0, 0, 0, 0, 0, new int[3], new int[3]);
      }

      ___storageButton = new GameObject[Core.settingAmountPages];

      ___storageIcon = new GameObject[Core.settingAmountSlots];
      ___storageIconBack = new GameObject[Core.settingAmountSlots];
      ___txtQStorage = new TextMesh[Core.settingAmountSlots];

      var storageMenu = GameObject.Find("Main Camera").transform.Find("menuStorage").gameObject;
      ___menuStorage = storageMenu;
      ___storageSelect = storageMenu.transform.FindChild("-").gameObject;

      ___txtStorageCost[0] = storageMenu.transform.FindChild("bStorageU").GetChild(0).GetComponent<TextMesh>();
      ___txtStorageCost[1] = storageMenu.transform.FindChild("bStorageU").GetChild(0).GetChild(0).GetComponent<TextMesh>();

      for (int i = 0; i < Core.settingAmountSlots; i++)
      {
        ___storageIcon[i] = storageMenu.transform.FindChild("" + i).gameObject;
        ___txtQStorage[i] = storageMenu.transform.FindChild("" + i).GetChild(0).GetComponent<TextMesh>();
        ___txtQStorage[i].text = "";
        ___storageIconBack[i] = storageMenu.transform.FindChild("" + i).GetChild(1).gameObject;
      }
      for (int i = 0; i < Core.settingAmountPages; i++)
      {
        ___storageButton[i] = storageMenu.transform.FindChild("page" + i).gameObject;
      }
      postBuildQuickStackButton();
      return false;
    }

    private static void SetSizes()
    {
      switch (Core.settingSizeEnum)
      {
        //case StorageSizeEnum.UltraSmall:
        //  Core.settingAmountPages = 2;
        //  Core.settingAmountSlots = 2;
        //  break;
        //case StorageSizeEnum.Smaller:
        //  Core.settingAmountPages = 3;
        //  Core.settingAmountSlots = 3 * 3;
        //  break;
        case StorageSizeEnum.Large:
          Core.settingAmountPages = 14;
          Core.settingAmountSlots = 7 * 6;
          break;
        case StorageSizeEnum.Larger:
          Core.settingAmountPages = 14;
          Core.settingAmountSlots = 8 * 6;
          break;
        case StorageSizeEnum.MegaLarge:
          Core.settingAmountPages = 28;
          Core.settingAmountSlots = 8 * 6;
          break;
        case StorageSizeEnum.UltraLarge:
          Core.settingAmountPages = 70;
          Core.settingAmountSlots = 8 * 6;
          break;
        case StorageSizeEnum.PagesOnly:
          Core.settingAmountPages = 27;
          Core.settingAmountSlots = 5 * 6;
          break;
        default:
          Core.settingAmountPages = 14;
          Core.settingAmountSlots = 7 * 6;
          break;
      }
    }

    private static string GetPrefabname()
    {
      switch (Core.settingSizeEnum)
      {
        //case StorageSizeEnum.UltraSmall:
        //  return "menustorage2x1x2";
        //case StorageSizeEnum.Smaller:
        //  return "menustorage3x3x3";
        case StorageSizeEnum.Large:
          return "menustorage6x7x14";
        case StorageSizeEnum.Larger:
          return "menustorage6x8x14";
        case StorageSizeEnum.MegaLarge:
          return "menustorage6x8x28";
        case StorageSizeEnum.UltraLarge:
          return "menustorage6x8x70";
        case StorageSizeEnum.PagesOnly:
          return "menustorage6x5x27";
        default:
          return "menustorage6x7x14";
      }
    }

    private static void postBuildQuickStackButton()
    {
      Type t = null;
      foreach (var a in AppDomain.CurrentDomain.GetAssemblies())
      {
        if (a.FullName.StartsWith("QuickStack,"))
        {
          t = a.GetType("QuickStack.StackButtonScript");
          break;
        }
      }
      bool isEnabled = false;
      foreach (var gadget in GadgetCore.API.Gadgets.ListAllEnabledGadgets())
        if (gadget.Info?.ModName == "QuickStack")
        {
          isEnabled = true;
          break;
        }
      if (t != null && isEnabled)
      {
        var storageMenu = GameObject.Find("Main Camera").transform.Find("menuStorage").gameObject;
        var pagge0 = storageMenu.transform.Find("page0");
        var btn = UnityEngine.Object.Instantiate(pagge0, pagge0.transform.parent).gameObject;
        btn.name = "button_quick_stack";

        Component.Destroy(btn.GetComponentInChildren<ButtonMenu>());
        btn.AddComponent(t);

        btn.GetComponentInChildren<BoxCollider>().size = new Vector3(2, 2, 2);

        btn.transform.SetParent(storageMenu.transform);
        btn.transform.localPosition = new Vector3(-0.5075f, 0.3595f, 0);
        btn.transform.localScale = new Vector3(1f / 16f, 1f / 16f, 1);
      }
    }
  }
}