local tablex = require("core.tablex")
local attributeUtil = require("ui.attributeUtil")
local cardComponent = require("ui.cardComponent")
local colors = require("ui.colors")
local consts = require("ui.consts")
local frame = require("ui.frame")
local gemUtil = require("ui.gemUtil")
local lamsConsts = require("ui.lamsConsts")
local mapUtil = require("ui.mapUtil")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local resourceConsts = require("ui.resourceConsts")
local resourceUtil = require("ui.resourceUtil")
local util = require("ui.util")
local UI = game.UI
local Pickup = game.Pickup
local CardComponent_Weapon_Slot = {}
setmetatable(CardComponent_Weapon_Slot, {
  __index = cardComponent.CardComponent
})
function CardComponent_Weapon_Slot.New(goParent, index)
  assert(goParent ~= nil, "GameObject parent reference entered into CardComponent_Weapon_Slot constructor was nil.")
  local newTable = {
    _name = "SpecialSlot",
    _goParent = goParent,
    _gameObject = nil,
    _goRoot = nil,
    _gameObjects = {},
    _children = {},
    _statsCount = 6,
    _height = 7,
    _index = index
  }
  local mt = {__index = CardComponent_Weapon_Slot}
  setmetatable(newTable, mt)
  return newTable
end
function CardComponent_Weapon_Slot:BaseInit(componentIndex)
  assert(self._name ~= nil, "Name was not defined in CardComponent:BaseInit")
  local name = tostring(self._name .. tostring(self._index))
  self._gameObject = self._goParent:FindSingleGOByName("CardComponent_" .. name)
  assert(self._gameObject ~= nil, "GameObject was not found with name " .. name .. " for CardComponent:BaseInit")
  self._children.goRoot = self._gameObject.Child
  assert(self._card ~= nil, "No card set for CardComponent:" .. self._name .. ", with gameObject: " .. tostring(self._gameObject:GetName()))
  assert(componentIndex ~= nil, "No componentIndex assigned to card component.")
  self._componentIndex = componentIndex
  self._frame = frame.Frame.New(self._gameObject)
  self._frame:SetHeight(self._height or 1)
end
function CardComponent_Weapon_Slot:Init()
  self._stats = {}
  for i = 1, self._statsCount do
    self._stats[i] = {}
    self._stats[i].goRefnode = self._gameObject:FindSingleGOByName("Stat" .. tostring(i))
    self._stats[i].goRefnodeChild = self._stats[i].goRefnode.Child
    self._stats[i].thName = util.GetTextHandle(self._stats[i].goRefnodeChild, "AttributeName")
    self._stats[i].thValue = util.GetTextHandle(self._stats[i].goRefnodeChild, "AttributeNumber")
    self._stats[i].thSpecial_Header = util.GetTextHandle(self._stats[i].goRefnodeChild, "AttributeHeader")
    self._stats[i].thSpecial_Value = util.GetTextHandle(self._stats[i].goRefnodeChild, "AttributeNumber_Long")
    self._stats[i].goRefnode:Show()
    self._stats[i].goRefnodeChild:Show()
  end
  self._goColoredSlotBacking = self._card._children.goAnimatedBackings
  self.thCategory = util.GetTextHandle(self._children.goRoot, "TextCategory")
  self.thName = util.GetTextHandle(self._children.goRoot, "TextName")
end
function CardComponent_Weapon_Slot:Update()
  local isReinforcementRecipe = self:GetProperty("IsReinforcementRecipe")
  if isReinforcementRecipe then
    self:SetActive(false)
    return
  else
    self:SetActive(true)
  end
  local weapon = self:GetProperty("Item")
  local slot = self:GetProperty("Slot")
  if weapon == pickupConsts.SonBow then
    if self._index == 2 or self._index == 3 then
      self:SetActive(false)
      return
    end
  else
    self._frame:SetActive(true)
  end
  local upgradeSlots = self:GetProperty("UpgradeSlots")
  local upgradeSlot = upgradeSlots[self._index]
  local character = self:GetProperty("Character")
  local creature = pickupUtil.GetCreatureFromCharacter(character)
  local pickup = pickupUtil.GetPickupNameInSlot(creature, upgradeSlot)
  local isWeaponComponent = self._index == 3
  local isWeaponSpecial = self._index == 1 or self._index == 2
  self:SetCategory(upgradeSlot)
  self:SetName(pickup, upgradeSlot)
  self:SetAttributes(pickup, isWeaponComponent, isWeaponSpecial)
  self:SetRarity(pickup, isWeaponComponent)
end
function CardComponent_Weapon_Slot:SetRarity(pickup, isWeaponComponent)
  if not isWeaponComponent then
    return
  end
  local rarity = resourceUtil.GetRarity(pickup)
  local color, brightColor, darkColor
  if rarity ~= nil then
    color = colors.RARITY[rarity]
    darkColor = colors.RARITY_DARK[rarity]
    brightColor = colors.RARITY_BRIGHT[rarity]
  else
    color = colors.RARITY[resourceConsts.RESOURCE_FLAG_ECONOMY]
    darkColor = colors.RARITY_DARK[resourceConsts.RESOURCE_FLAG_ECONOMY]
    brightColor = colors.RARITY_BRIGHT[resourceConsts.RESOURCE_FLAG_ECONOMY]
  end
  local material = "glowingLight_anim"
  local layer = "Layer0"
  local attribute = "cst_EmissiveTint"
  print(tostring(color))
  util.SetGameObjectColor(self._goColoredSlotBacking, darkColor, "itemCard_HeaderBacking", "Layer0", attribute)
  util.SetGameObjectColor(self._goColoredSlotBacking, brightColor, "itemCard_HeaderBacking", "Layer1", attribute)
end
function CardComponent_Weapon_Slot:SetIcon(pickup, weapon, isWeaponComponent, isWeaponSpecial)
  if isWeaponComponent then
    self._children.goUpgradeSlotIcon_Runic:Hide()
    self._children.goUpgradeSlotIcon_Hilt:Show()
    if pickup == nil then
      self._children.goUpgradeSlotIcon_Hilt_SocketBacking:Hide()
      self._children.goUpgradeSlotIcon_Hilt_Icon:Hide()
    else
      self._children.goUpgradeSlotIcon_Hilt_SocketBacking:Show()
      self._children.goUpgradeSlotIcon_Hilt_Icon:Show()
      local color = resourceUtil.GetRarityColor(pickup)
      local material = "weaponRunic_SocketColorFill"
      local layer = "LayerX"
      local attribute = "cst_EmissiveTint"
      util.SetGameObjectColor(self._children.goUpgradeSlotIcon_Hilt_SocketBacking, color, material, layer, attribute)
      self._children.goUpgradeSlotIcon_Hilt_Icon:SetMaterialSwap(pickup)
    end
  elseif isWeaponSpecial then
    self._children.goUpgradeSlotIcon_Runic:Show()
    self._children.goUpgradeSlotIcon_Hilt:Hide()
    if pickup == nil then
      self._children.goUpgradeSlotIcon_Runic_SocketBacking:Hide()
      self._children.goUpgradeSlotIcon_Runic_Icon:Hide()
    else
      self._children.goUpgradeSlotIcon_Runic_SocketBacking:Show()
      self._children.goUpgradeSlotIcon_Runic_Icon:Hide()
      local color = colors.WEAPON_SPECIALS[weapon]
      local material = "weaponRunic_SocketColorFill"
      local layer = "LayerX"
      local attribute = "cst_EmissiveTint"
      util.SetGameObjectColor(self._children.goUpgradeSlotIcon_Runic_SocketBacking, color, material, layer, attribute)
      self._children.goUpgradeSlotIcon_Runic_Icon:SetMaterialSwap(pickup)
    end
  else
    self._children.goUpgradeSlotIcon_Runic:Hide()
    self._children.goUpgradeSlotIcon_Hilt:Hide()
  end
end
function CardComponent_Weapon_Slot:SetCategory(slotName)
  UI.SetText(self.thCategory, pickupUtil.GetSlotDisplayName(slotName))
end
function CardComponent_Weapon_Slot:SetName(pickupName, pickupSlot)
  local printString = ""
  if pickupName ~= nil then
    printString = pickupUtil.GetDisplayName(pickupName)
  else
    printString = pickupUtil.GetSlotDisplayName(pickupSlot) .. " : " .. util.GetLAMSMsg(lamsConsts.Empty)
  end
  UI.SetText(self.thName, printString)
end
CardComponent_Weapon_Slot._weaponSpecialAttributes = {
  [1] = {
    Name = "Level",
    ShowSecondsAbreviation = false,
    GetValue = function(weaponSpecial)
      return pickupUtil.GetProfileStage(weaponSpecial) + 1
    end
  },
  [2] = {
    Name = "Cooldown",
    ShowSecondsAbreviation = true,
    GetValue = function(weaponSpecial)
      return gemUtil.GetCooldownValue(weaponSpecial) .. " " .. util.StyleText(util.GetLAMSMsg(lamsConsts.Sec), "ClearCaseTransform")
    end
  },
  [3] = {
    Name = "Type",
    ShowSecondsAbreviation = false,
    GetValue = function(weaponSpecial)
      return gemUtil.GetStatTypeDisplayValue(weaponSpecial)
    end
  }
}
function CardComponent_Weapon_Slot:EnableWeaponComponent(index)
  local jid = self._stats[index].goRefnodeChild:GetJointIndex("Pommel")
  self._stats[index].goRefnodeChild:ShowJoint(jid)
  jid = self._stats[index].goRefnodeChild:GetJointIndex("WeaponSpecial")
  self._stats[index].goRefnodeChild:HideJoint(jid)
  local targetTimelinePos = 1
  local animRate = 0
  for i = 1, self._statsCount do
    UI.Anim(self._stats[i].goRefnodeChild, consts.AS_ForwardCycle, "", animRate, targetTimelinePos)
  end
end
function CardComponent_Weapon_Slot:EnableWeaponSpecial(index)
  local jid = self._stats[index].goRefnodeChild:GetJointIndex("WeaponSpecial")
  self._stats[index].goRefnodeChild:ShowJoint(jid)
  jid = self._stats[index].goRefnodeChild:GetJointIndex("Pommel")
  self._stats[index].goRefnodeChild:HideJoint(jid)
end
function CardComponent_Weapon_Slot:SetAttributes(pickup, isWeaponComponent, isWeaponSpecial)
  local attributeTable = {}
  for i = 1, self._statsCount do
    self._stats[i].goRefnodeChild:Show()
  end
  if isWeaponComponent then
    for i = 1, self._statsCount do
      self:EnableWeaponComponent(i)
    end
    if pickup ~= nil then
      local stage = math.max(pickupUtil.GetProfileStage(pickup), 0)
      for i, attributeName in pairs(pickupConsts.Attributes) do
        local value = Pickup.GetAttribute(pickup, attributeName, stage)
        attributeTable[i] = {
          displayName = attributeUtil.GetShortDisplayName(attributeName),
          value = math.floor(value or 0)
        }
      end
    else
      for i, attributeName in pairs(pickupConsts.Attributes) do
        attributeTable[i] = {
          displayName = attributeUtil.GetShortDisplayName(attributeName),
          value = nil
        }
      end
    end
    local iActive = 1
    for i = 1, self._statsCount do
      local name = attributeTable[i].displayName
      local value = attributeTable[i].value
      if value ~= 0 then
        UI.SetText(self._stats[iActive].thName, name)
        UI.SetText(self._stats[iActive].thValue, tostring(value))
        UI.SetText(self._stats[iActive].thSpecial_Value, "")
        iActive = iActive + 1
        self._stats[i].goRefnodeChild:Show()
      end
    end
    for i = iActive, self._statsCount do
      self._stats[i].goRefnodeChild:Hide()
    end
  elseif isWeaponSpecial then
    for i = 1, self._statsCount do
      self:EnableWeaponSpecial(i)
    end
    for i = 1, self._statsCount do
      local iDisplay = self:GetAttributeMapping_WeaponSpecial(i)
      local name, value
      local printString = ""
      if i <= #self._weaponSpecialAttributes then
        local attribute = self._weaponSpecialAttributes[i]
        local displayName = gemUtil.GetStatDisplayName(attribute.Name)
        value = pickup ~= nil and attribute.GetValue(pickup) or "--"
        printString = tostring(displayName)
        local gameObject
        gameObject = self._stats[iDisplay].goRefnodeChild
        local jid_sec = gameObject:FindJointIndex("SecondsAbreviated")
        if attribute.ShowSecondsAbreviation then
          gameObject:ShowJoint(jid_sec)
        else
          gameObject:HideJoint(jid_sec)
        end
      end
      UI.SetText(self._stats[iDisplay].thName, "")
      UI.SetText(self._stats[iDisplay].thValue, "")
      UI.SetText(self._stats[iDisplay].thSpecial_Header, printString)
      UI.SetText(self._stats[iDisplay].thSpecial_Value, tostring(value))
    end
    local maxStats = 3
    for i = maxStats + 1, self._statsCount do
      local iDisplay = self:GetAttributeMapping_WeaponSpecial(i)
      self._stats[iDisplay].goRefnodeChild:Hide()
    end
  else
    assert(false, "No attributes can be parsed from pickup " .. tostring(pickup))
  end
end
function CardComponent_Weapon_Slot:GetAttributeMapping_WeaponSpecial(index)
  if index == 1 then
    return 1
  elseif index == 2 then
    return 3
  elseif index == 3 then
    return 5
  elseif index == 4 then
    return 2
  elseif index == 5 then
    return 4
  elseif index == 6 then
    return 6
  end
end
return {CardComponent_Weapon_Slot = CardComponent_Weapon_Slot}
