local tablex = require("core.tablex")
local colors = require("ui.colors")
local lamsIDs = require("ui.lamsConsts")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local recipeUtil = require("ui.recipeUtil")
local resourceConsts = require("ui.resourceConsts")
local util = require("ui.util")
local Pickup = game.Pickup
local FindPlayer = game.Player.FindPlayer
local IsValidName = function(gemName)
  local isValid = not util.IsStringNilOrEmpty(gemName)
  return isValid
end
local GetCurrentLevel = function(gemName)
  return Pickup.GetProfileStage(gemName) + 1
end
local GetMaxLevel = function(gemName)
  return Pickup.GetMaxStage(gemName) + 1
end
local GetWeaponSpecialLevelDisplayName = function(gemName)
  local levelText = ""
  if IsValidName(gemName) then
    local currentGemLevel = GetCurrentLevel(gemName)
    local lamsID = lamsIDs["RomanNumeral_" .. currentGemLevel]
    levelText = util.GetLAMSMsg(lamsID, gemName)
  end
  return levelText
end
local GetGemRecipeName = function(gemName, levelIndex)
  return "WeaponSpecial_" .. gemName .. "_Lvl0" .. tostring(levelIndex)
end
local RecipeExists = function(gemLevelRecipeName)
  return game.Wallets.HasRecipe(resourceConsts.WALLET_KRATOS, gemLevelRecipeName)
end
local CanPurchaseUpgrade = function(gemLevelRecipeName)
  if gemLevelRecipeName == nil then
    return false
  else
    return recipeUtil.CanPurchase(gemLevelRecipeName)
  end
end
local PurchaseUpgrade = function(currPickupName, recipeName)
  recipeUtil.Craft(recipeName, "GemCard")
  local currPickupSlotName = pickupUtil.GetSlotName(currPickupName)
  if pickupUtil.IsValidSlotName(currPickupSlotName) then
    local player = game.Player.FindPlayer()
    local pickupInSlot = pickupUtil.GetPickupNameInSlot(player, currPickupSlotName)
    if pickupUtil.IsValidName(pickupInSlot) and pickupInSlot == currPickupName then
      if player:PickupIsInCooldown(currPickupName) then
        pickupUtil.PickupAcquireWhileOnCooldown(player, currPickupName)
      else
        pickupUtil.PickupAcquire(player, currPickupName)
      end
    end
  end
end
local GetAllLevelRecipes = function(gemName)
  local maxLevel = GetMaxLevel(gemName)
  local recipeTable = {}
  local tableIndex = 1
  for levelIndex = 2, maxLevel do
    local gemLevelRecipeName = GetGemRecipeName(gemName, levelIndex)
    tablex.FastInsert(recipeTable, gemLevelRecipeName, tableIndex)
    tableIndex = tableIndex + 1
    if not RecipeExists(gemLevelRecipeName) then
      engine.Print("Weapon special level up recipe not found in wallet for special: " .. tostring(gemName) .. ". The name of the recipe requested was: " .. tostring(gemLevelRecipeName))
      return {}
    end
  end
  return recipeTable
end
local IsLevelLocked = function(gemName)
  local maxLevel = GetMaxLevel(gemName)
  local currentLevel = GetCurrentLevel(gemName)
  return maxLevel >= currentLevel
end
local IsAxeWeaponSpecial = function(gemName)
  local pickupSlotName = pickupUtil.GetSlotName(gemName)
  return pickupSlotName == pickupConsts.Slot_WeaponSpecial_Light or pickupSlotName == pickupConsts.Slot_WeaponSpecial_Heavy
end
local IsBladesWeaponSpecial = function(gemName)
  local pickupSlotName = pickupUtil.GetSlotName(gemName)
  return pickupSlotName == pickupConsts.Slot_WeaponSpecial_Blades_Light or pickupSlotName == pickupConsts.Slot_WeaponSpecial_Blades_Heavy
end
local IsLightWeaponSpecial = function(gemName)
  local pickupSlotName = pickupUtil.GetSlotName(gemName)
  return pickupSlotName == pickupConsts.Slot_WeaponSpecial_Light or pickupSlotName == pickupConsts.Slot_WeaponSpecial_Blades_Light
end
local IsHeavyWeaponSpecial = function(gemName)
  local pickupSlotName = pickupUtil.GetSlotName(gemName)
  return pickupSlotName == pickupConsts.Slot_WeaponSpecial_Heavy or pickupSlotName == pickupConsts.Slot_WeaponSpecial_Blades_Heavy
end
local IsSonSpecial = function(gemName)
  local pickupSlotName = pickupUtil.GetSlotName(gemName)
  return pickupSlotName == pickupConsts.Slot_SonSpecial
end
local GetControllerHelpText = function(gemName)
  local returnMessage
  if IsHeavyWeaponSpecial(gemName) then
    returnMessage = util.GetLAMSMsg(lamsIDs.ButtonPrompt_HeavyWeaponSpecial)
  elseif IsLightWeaponSpecial(gemName) then
    returnMessage = util.GetLAMSMsg(lamsIDs.ButtonPrompt_LightWeaponSpecial)
  elseif IsSonSpecial(gemName) then
    returnMessage = util.GetLAMSMsg(lamsIDs.ButtonPrompt_SonSpecial)
  else
    assert(false, "Improper data was passed into gemUtil.GetControllerHelpText. Data was:" .. tostring(gemName))
  end
  return returnMessage
end
local StatsLamsIds_Name = {
  Level = lamsIDs.Level,
  Cooldown = lamsIDs.Cooldown,
  Type = lamsIDs.Type
}
local StatsLamsIds_Type = {
  {
    Tag = pickupConsts.TAG_PICKUP_SPECIALTY_TYPE1,
    Lams = 43282
  },
  {
    Tag = pickupConsts.TAG_PICKUP_SPECIALTY_TYPE2,
    Lams = 43283
  },
  {
    Tag = pickupConsts.TAG_PICKUP_SPECIALTY_TYPE3,
    Lams = 43284
  },
  {
    Tag = pickupConsts.TAG_PICKUP_SPECIALTY_TYPE4,
    Lams = 43285
  },
  {
    Tag = pickupConsts.TAG_PICKUP_SPECIALTY_TYPE5,
    Lams = 43286
  }
}
local GetStatDisplayName = function(statName)
  return util.GetLAMSMsg(StatsLamsIds_Name[statName])
end
local GetCooldownValue = function(weaponSpecial)
  local baseCooldown = -1
  local adjustedCooldown = -1
  if Pickup.GetProfileStageCooldown then
    local creature = pickupUtil.GetUICreature(pickupConsts.TAG_PICKUP_KRATOS)
    local stage = Pickup.GetProfileStage(weaponSpecial)
    if stage < 0 then
      stage = 0
    end
    baseCooldown = Pickup.GetProfileStageCooldown(creature, weaponSpecial, stage)
    if Pickup.GetProfileStageAdjustedCooldown then
      adjustedCooldown = util.Round(Pickup.GetProfileStageAdjustedCooldown(creature, weaponSpecial, stage))
    end
  end
  return adjustedCooldown, baseCooldown
end
local GetStatTypeDisplayValue = function(weaponSpecial)
  local lams = -1
  for i = 1, #StatsLamsIds_Type do
    if Pickup.HasTags(weaponSpecial, StatsLamsIds_Type[i].Tag) then
      lams = StatsLamsIds_Type[i].Lams
      break
    end
  end
  if lams == -1 then
    return "--"
  else
    return util.GetLAMSMsg(lams)
  end
end
local GetStatsTable = function(gemName, includeLevel)
  local statsTable = {}
  local index = 1
  if includeLevel then
    statsTable[index] = {
      Name = "Level",
      GetValue = function(weaponSpecial)
        return tostring(GetCurrentLevel(weaponSpecial))
      end
    }
    index = index + 1
  end
  statsTable[index] = {
    Name = "Cooldown",
    GetValue = function(weaponSpecial)
      return GetCooldownValue(weaponSpecial)
    end
  }
  index = index + 1
  statsTable[index] = {
    Name = "Type",
    GetValue = function(weaponSpecial)
      return GetStatTypeDisplayValue(weaponSpecial)
    end
  }
  index = index + 1
  return statsTable
end
return {
  GetMaxLevel = GetMaxLevel,
  GetWeaponSpecialLevelDisplayName = GetWeaponSpecialLevelDisplayName,
  GetAllLevelRecipes = GetAllLevelRecipes,
  GetCurrentLevel = GetCurrentLevel,
  CanPurchaseUpgrade = CanPurchaseUpgrade,
  PurchaseUpgrade = PurchaseUpgrade,
  IsLevelLocked = IsLevelLocked,
  IsAxeWeaponSpecial = IsAxeWeaponSpecial,
  IsBladesWeaponSpecial = IsBladesWeaponSpecial,
  IsLightWeaponSpecial = IsLightWeaponSpecial,
  IsHeavyWeaponSpecial = IsHeavyWeaponSpecial,
  IsSonSpecial = IsSonSpecial,
  GetControllerHelpText = GetControllerHelpText,
  GetStatsTable = GetStatsTable,
  GetStatDisplayName = GetStatDisplayName,
  GetCooldownValue = GetCooldownValue,
  GetStatTypeDisplayValue = GetStatTypeDisplayValue
}
