using HarmonyLib;
using GadgetCore.API;
using UnityEngine;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using System.Globalization;

namespace RecipeMenuCore.Patches
{
  [HarmonyPatch(typeof(GameScript))]
  [HarmonyPatch("HoverRecipeSelect")]
  [HarmonyGadget("RecipeMenuCore")]
  public static class Patch_GameScript_HoverRecipeSelect
  {
    [HarmonyPrefix]
    public static bool Prefix(GameScript __instance, int id, int ___craftType, ref int ___curRecipePage, GameObject ___itemexpbar, GameObject[] ___aspectObj, TextMesh ___itemName,
      GameObject ___hoverItem, TextMesh[] ___itemStat, GameObject ___txtStats, TextMesh ___itemDesc, Material ___hoverItemMat2, Material ___hoverItemMat1, GameObject ___hoverDroid,
      TextMesh[] ___txtHoverStat, TextMesh ___txtHoverStatInfo, TextMesh[] ___itemAspect, TextMesh ___itemLevel, GameObject[] ___recipeLock)
    {
      if (!Core.settingUseDialog)
        return true;

      if (___craftType == 0 || ___craftType == 1 || ___craftType == MenuRegistry.Singleton["Gadget Core:Crafter Menu"].GetID())
      {
        if (id >= 12 || ___recipeLock[id].active)
        {
          ___hoverItem.SetActive(false);
          return false;
        }
      }
      var item = new Item(GetItemId(__instance, id, ___craftType, ___curRecipePage), 1, 0, 0, 0, new int[3], new int[3]);
      var itemInfo = ItemRegistry.GetItem(item.id);

      ___txtHoverStat[0].text = string.Empty;
      ___txtHoverStat[1].text = ___txtHoverStat[0].text;
      ___txtHoverStatInfo.text = string.Empty;
      ___aspectObj[0].SetActive(false);
      ___aspectObj[1].SetActive(false);
      ___aspectObj[2].SetActive(false);
      ___itemAspect[0].text = string.Empty;
      ___itemAspect[1].text = string.Empty;
      ___itemAspect[2].text = string.Empty;
      ___itemLevel.text = string.Empty;

      if (Camera.main.ScreenToWorldPoint(Input.mousePosition).y < MenuScript.player.transform.position.y - 4.5f)
        ___hoverItem.transform.localPosition = new Vector3(5f, 0f, -4.55f);
      else
        ___hoverItem.transform.localPosition = new Vector3(5f, -4f, -4.55f);

      ___hoverDroid.SetActive(false);
      ___itemexpbar.SetActive(false);

      if (item.id > 0)
      {
        ___itemName.text = itemInfo.Name;
        ___itemName.color = Color.white;
        ___itemDesc.text = GenerateDescription(itemInfo);

        bool hasStats = false;
        int[] gearBaseStats = ItemRegistry.GetItem(item.id).Stats.GetStatArray();
        for (int i = 0; i < 6; i++)
        {
          if (gearBaseStats[i] > 0)
          {
            ___itemStat[i].text = "+" + gearBaseStats[i];
            hasStats = true;
          }
          else
            ___itemStat[i].text = string.Empty;
        }
        ___txtStats.SetActive(hasStats);
        ___hoverItem.SetActive(true);
        if (hasStats)
          ___hoverItem.GetComponent<Renderer>().material = hoverItem;
        else
          ___hoverItem.GetComponent<Renderer>().material = ___hoverItemMat1;
      }
      else
      {
        ___hoverItem.SetActive(false);
      }
      return false;
    }

    private static Material hoverItem = new Material(Shader.Find("Unlit/Transparent"))
    {
      mainTexture = GadgetCoreAPI.LoadTexture2D("hoverItem.png")
    };

    private static string GenerateDescription(ItemInfo item)
    {
      if ((item.GetID() >= 1000 && item.GetID() < 1000 + 6)
        || (item.GetID() >= 1012 && item.GetID() < 1012 + 3 * 6))
        return "";
      var desc = item.Desc;
      if (desc == null || desc.Length <= 0)
      {
        float[] ws = item.WeaponScaling;
        if (ws != null)
        {
          string o = "";
          for (int i = 0; i < ws.Length; i++)
          {
            if (ws[i] > 0)
            {
              string type = i == 0 ? "VIT" : i == 1 ? "STR" : i == 2 ? "DEX" : i == 3 ? "TEC" : i == 4 ? "MAG" : "FTH";
              o += "DMG x" + (ws[i] >= 1 ? ws[i].ToString(CultureInfo.InvariantCulture) : "1/" + (1 / ws[i])).ToString(CultureInfo.InvariantCulture) + " " + type + "\n";
            }
          }
          return o;
        }
      }
      return desc;
    }

    private static int GetItemId(GameScript __instance, int index, int craftType, int curRecipePage)
    {
      if (index >= 12)
      {
        if (craftType == 2 && curRecipePage >= 6)
          return Core.pageUltimateForgeInfoList[curRecipePage - 6].GetRecipePageEntries()[(index - 12) / 3].ItemIdExtension[(index - 12) % 3];
        return CalculateUltimaleWeapon((index - 12) % (3 * 6), (index - 12) / (3 * 6) + curRecipePage * 2);
      }

      if (craftType == 0 && curRecipePage >= 6)
        return Core.pageGearForgeInfoList[curRecipePage - 6].GetRecipePageEntries()[index].ItemIdBase;
      else if (craftType == 1 && curRecipePage >= 2)
        return Core.pageAlchemyStationInfoList[curRecipePage - 2].GetRecipePageEntries()[index].ItemIdBase;
      else if (craftType == 2 && curRecipePage >= 6)
        return Core.pageUltimateForgeInfoList[curRecipePage - 6].GetRecipePageEntries()[index].ItemIdBase;
      else if (craftType == MenuRegistry.Singleton["Gadget Core:Crafter Menu"].GetID())
        return Core.pageUniversalCrafterInfoList[curRecipePage].GetRecipePageEntries()[index].ItemIdBase;

      else if (craftType == 0 && curRecipePage < 6 && Core.pageGearForgeInfoListVanilla[curRecipePage] != null)
        return Core.pageGearForgeInfoListVanilla[curRecipePage].GetRecipePageEntries()[index].ItemIdBase;
      else if (craftType == 1 && curRecipePage < 2 && Core.pageAlchemyStationInfoListVanilla[curRecipePage] != null)
        return Core.pageAlchemyStationInfoListVanilla[curRecipePage].GetRecipePageEntries()[index].ItemIdBase;
      else if (craftType == 2 && curRecipePage < 6 && Core.pageUltimateForgeInfoListVanilla[curRecipePage] != null)
        return Core.pageUltimateForgeInfoListVanilla[curRecipePage].GetRecipePageEntries()[index].ItemIdBase;

      return __instance.GetRecipeItem(curRecipePage, index).id;
    }
    private static int CalculateUltimaleWeapon(int index, int page)
    {
      if (page == 0)
        return 312 + index;
      if (page == 1)
        return 362 + index;
      if (page == 2)
        return 412 + index;
      if (page == 3)
        return 462 + index;
      if (page == 4)
        return 512 + index;
      if (page == 5)
        return 562 + index;
      if (page == 6) //shield
        return 612 + index;
      if (page == 7) //droid
        return 1012 + index;
      if (page == 8) //helmet 1
        return 750 + index;
      if (page == 9) //helmet 2
        return 768 + index;
      if (page == 10) //armor 1
        return 850 + index;
      if (page == 11) //armor 2
        return 868 + index;
      return 0;
    }
  }
}
