local this = class("moduleSpiritron", require("ui.pages.HeroPanel.moduleHeroBase"))
local moveY = 60
local spiritronRankTpl = L_GameTpl:getSpiritronRankTpl()
local _heroTpl = L_GameTpl:getHeroTpl()
local MaxColor = C_Color(0.43, 0.57, 0.87)

function this.bind()
  return {
    txt_unlockDesText = "",
    active_unlockDesText = false,
    heroInfo = true,
    go_btnReplave = true,
    go_btnRemove = true,
    go_lockBg = true,
    heroName = "",
    txt_name = "",
    txt_level = "",
    txt_levelWord = "",
    txt_skill = "",
    go_lock = false,
    spiritronInfo = false,
    spiritronNull = true,
    btnGroup = true,
    sliderValue_exp = 0,
    color_slider = C_Color.white,
    canAdd = true,
    go_weaponList = false,
    bgPos = L_Vector3.new(0, 0),
    module_buttonAdvance = L_Const.ModuleInfo.Button,
    active_buttonAdvance = true,
    module_buttonEquip = L_Const.ModuleInfo.Button,
    scrollList_spiritron = L_Const.ModuleInfo.CellIcon,
    scrollList_property = {
      moduleName = "pages/spiritron/cellSpiritronProp"
    },
    module_star = {
      moduleName = "pages/HeroPanel/moduleHeroShowRank"
    },
    module_sortWay = L_Const.ModuleInfo.FoYeFilterModule,
    spiritronCardItem = {
      moduleName = "pages/Spiritron/cellSpiritronCardItem"
    }
  }
end

function this.methods()
  return {
    onClick_lock = function(self)
      L_SpiritronStore:req_lockSpiritron(self._selectGuid)
    end,
    onClick_strength = function(self)
      L_UI:open("pageSpiritronStrength", {
        weaponGuid = self._selectGuid
      })
      self:setSpiritronListState(false)
    end,
    onClick_addSpiritron = function(self)
      self:setSpiritronListState(true)
    end,
    onClick_removeSpiritron = function(self)
      L_SpiritronStore:req_equipSpiritron(self.heroGuid, 0)
    end,
    onClick_replace = function(self)
      self:setSpiritronListState(true)
    end,
    onClick_closeWeaponList = function(self)
      self:clearReadNew()
      self:setSpiritronListState(false)
    end
  }
end

function this:open()
  self._readSpirit = {}
  local list = {
    L_Const.sortType.lv,
    L_Const.sortType.quality,
    L_Const.sortType.star
  }
  local func = function(type, order)
    self._sortParam = {type = type, order = order}
    self:updateSpiritronListData()
  end
  self.modules.module_sortWay:initModule(list, func)
  self._sortParam = {
    type = L_Const.sortType.lv,
    order = L_Const.sortOrder.DESC
  }
  L_HeroStore:listenCallFunc(L_HeroStore.event.setCurHeroGuid, self.initPage, self)
  L_SpiritronStore:listenCallFunc(L_SpiritronStore.event.refreshWeapon, self.refreshAll, self)
  L_BagStore:listenCallFunc(L_BagStore.event.refreshBag, self.refreshAll, self)
  L_HeroStore:listenCallFunc(L_HeroStore.event.heroSync, self.refreshAll, self)
end

function this:close()
  self:clearReadNew()
  L_HeroStore:unListenCallFunc(L_HeroStore.event.setCurHeroGuid, self.initPage)
  L_SpiritronStore:unListenCallFunc(L_SpiritronStore.event.refreshWeapon, self.refreshAll)
  L_BagStore:unListenCallFunc(L_BagStore.event.refreshBag, self.refreshAll, self)
  L_HeroStore:unListenCallFunc(L_HeroStore.event.heroSync, self.refreshAll, self)
end

function this:initPage()
  this.super.initPage(self)
  self.parent:setDownBg(true)
  self.parent:refreshCanChangeHero(true)
  self.heroGuid = self:getModeController():getSelectGuid()
  self.heroConfigId = self:getModeController():getSelectConfigId()
  local item_hero = L_ItemTplManager:getHeroItem(self.heroConfigId)
  if self:isPreviewMode() then
    self.bindComponents.reddotNormal.gameObject:SetActive(false)
  else
    L_ReddotManager:registerReddot(self.bindComponents.reddotNormal, string.format(L_ReddotManager.DotDef.HeroSpirit, self.heroGuid))
  end
  local tempName = item_hero.name
  if self.heroGuid == L_HeroStore:getDefaultHeroGuid() then
    tempName = L_PlayerStore:getPlayerName()
  end
  self.bind.heroName = tempName
  self:setSpiritronListState(false)
  self._selectGuid = self:getCurrHeroSpiritronGuid()
  self:updateSpiritronInfo()
  self.bind.heroInfo = not self:isPreviewMode()
  self.bind.go_btnReplave = not self:isPreviewMode()
  self.bind.go_btnRemove = not self:isPreviewMode()
  self.bind.go_lockBg = not self:isPreviewMode()
end

function this:getCurrHeroSpiritronGuid()
  if self:isPreviewMode() then
    local guid = self:getModeController()._spiritronId * 10
    if self:getModeController():getIsMaxLevel() then
      guid = guid + 1
    end
    return guid
  else
    return L_HeroStore:getHeroSpiritronGuid(self:getHero(self.heroGuid))
  end
end

function this:getSpiritronItem(spiritronGuid)
  if self:isPreviewMode() then
    local isMaxLevel = spiritronGuid % 10 == 1
    return L_SpiritronManager:getPreviewSpiritronData(math.floor(spiritronGuid / 10), isMaxLevel)
  else
    return L_SpiritronStore:getSpiritronItem(spiritronGuid)
  end
end

function this:refreshAll()
  if not self.bind.go_weaponList then
    self._selectGuid = self:getCurrHeroSpiritronGuid()
  end
  self:updateSpiritronListItems()
  self:updateSpiritronInfo()
end

function this:setSpiritronListState(state)
  if self.bind.go_weaponList == state then
    return
  end
  self._selectGuid = self:getCurrHeroSpiritronGuid()
  self.bind.go_weaponList = state
  self.bind.btnGroup = not state
  self.bind.bgPos = L_Vector3.new(0, state and moveY or 0)
  self.parent:setDownBg(not state)
  self.parent:refreshCanChangeHero(not state)
  self.bind.active_buttonAdvance = not state
  if state then
    self:updateSpiritronListData()
  end
  self:refreshAll()
end

function this:updateSpiritronInfo()
  self.bind.active_unlockDesText = false
  if self._selectGuid == 0 then
    self.bind.spiritronNull = true
    self.bind.spiritronInfo = false
    return
  end
  self.bind.spiritronNull = false
  self.bind.spiritronInfo = true
  local serverData = self:getSpiritronItem(self._selectGuid)
  if not serverData then
    errorf("\230\178\161\230\156\137\231\129\181\229\173\144guid" .. self._selectGuid)
    return
  end
  local item = L_ItemTplManager:getSpiritronItem(serverData.spiritronId)
  local rankConfs = spiritronRankTpl:getChildren(serverData.spiritronId)
  local lvMax = rankConfs[serverData.rank].rankLevelLimit
  local currLv = serverData.spiritronLv
  local isMax = currLv == lvMax
  self.bind.sliderValue_exp = L_HeroManager:sliderChange(serverData.exp / L_SpiritronManager:getExpMax(serverData.spiritronId, serverData.spiritronLv))
  self.bind.color_slider = isMax and MaxColor or C_Color.white
  self.bind.txt_name = item.name
  self.bind.txt_level = L_GameUtil.fillColor(string.format("%s<size=34>/%s</size>", currLv, lvMax), isMax and L_Const.colorHtml.blue002 or L_Const.colorHtml.white001)
  self.bind.txt_levelWord = L_GameUtil.fillColor("Lv.", isMax and L_Const.colorHtml.blue002 or L_Const.colorHtml.white001)
  self.bind.go_lock = serverData.lock
  self.modules.spiritronCardItem:setId(serverData.spiritronId)
  self.modules.module_star:refreshStar(serverData.star)
  local propertyList = L_SpiritronManager:getAttListByGuidByItem(serverData)
  local propertyList_wear = {}
  if self:getCurrHeroSpiritronGuid() ~= 0 then
    local curServerData = self:getSpiritronItem(self:getCurrHeroSpiritronGuid())
    propertyList_wear = L_SpiritronManager:getAttListByGuidByItem(curServerData)
  end
  local proList = {}
  for k, v in pairs(propertyList) do
    local value_old = propertyList_wear[k] or 0
    table.insert(proList, {
      id = k,
      value = v,
      add = 0 < v - value_old,
      dec = v - value_old < 0
    })
  end
  L_SpiritronManager:sortAttrId(proList)
  for i, data in ipairs(proList) do
    data.bg = i % 2 == 1
  end
  self.bind.scrollList_property:clear()
  self.bind.scrollList_property:insert_array(proList)
  self.bind.txt_skill = L_SpiritronManager:getSkillDescByGuidByitem(serverData)
  local canAdvance, itemSatisfyAdvance = L_SpiritronManager:canSpiritronAdvance(self._selectGuid)
  self.bind.canAdd = serverData.spiritronLv ~= rankConfs[#rankConfs].rankLevelLimit or serverData.star < L_Const.SpiritronFullStar and not self:isPreviewMode()
  if self:isPreviewMode() or not canAdvance then
    self.modules.module_buttonAdvance:setData(L_Const.ButtonType.NONE, nil, nil, {
      size = C_Vector2(362, 78)
    })
    self.bind.active_unlockDesText = false
  else
    local rankTpl = rankConfs[serverData.rank]
    local condition = spiritronRankTpl:getCondition(rankTpl)
    local bComplete = true
    if not table.isEmpty(condition) then
      bComplete = L_ConditionManager:singleIsComplete(condition)
    end
    self.bind.active_unlockDesText = not bComplete
    if not bComplete then
      self.bind.active_unlockDesText = self.bind.active_buttonAdvance
    end
    if bComplete then
      self.modules.module_buttonAdvance:setData(itemSatisfyAdvance and L_Const.ButtonType.BLUE or L_Const.ButtonType.BLACK, L_WordsTpl:getValue("ui_moduleSpiritron_03"), handler(self, self.onClickAdvance), {
        size = C_Vector2(362, 78)
      })
    else
      self.modules.module_buttonAdvance:setData(L_Const.ButtonType.NONE, nil, nil, {
        size = C_Vector2(362, 78)
      })
      self.bind.txt_unlockDesText = L_ConditionManager:getSingleDesc(condition)
    end
  end
end

function this:onClickEquip()
  if self._selectGuid == self:getCurrHeroSpiritronGuid() or self._selectGuid == 0 then
    return
  end
  local targetWeaponWearHero = self:getSpiritronItem(self._selectGuid).spiritronHero
  local wear = function()
    L_SpiritronStore:req_equipSpiritron(self.heroGuid, self._selectGuid)
    self:setSpiritronListState(false)
  end
  if math.isEmpty(targetWeaponWearHero) then
    wear()
  else
    local hero = self:getHero(targetWeaponWearHero)
    local tpl_hero = _heroTpl:getTplById(L_HeroStore:getHeroConfigId(hero))
    local name = _heroTpl:getName(tpl_hero)
    local tip = {
      txtContent = L_WordsTpl:getValue("notice_weapon_change", {
        [0] = name
      }),
      confirmCallback = wear
    }
    L_GameUtil.showCommonTip(tip)
  end
end

function this:onClickAdvance()
  L_UI:open("pageSpiritronAdvance", {
    weaponGuid = self._selectGuid
  })
end

function this:updateSpiritronListData()
  local weaponList = L_SpiritronStore:getSpiritronList()
  local spiritronListData = {}
  for k, v in pairs(weaponList) do
    local item = L_ItemTplManager:getSpiritronItem(v.spiritronId)
    local data = {
      itemType = L_Const.resType.spiritron,
      guid = v.guid,
      callback = function()
        if self._selectGuid ~= v.guid then
          self._selectGuid = v.guid
          self:updateSpiritronListItems()
          self:updateSpiritronInfo()
        end
      end,
      activeEquip = v.guid == self:getCurrHeroSpiritronGuid(),
      isSelf = v.guid == self:getCurrHeroSpiritronGuid() and 1 or 0,
      star = v.star,
      spiritronLv = v.spiritronLv,
      quality = item.quality,
      spiritronId = v.spiritronId
    }
    table.insert(spiritronListData, data)
  end
  local isAsc = self._sortParam.order == L_Const.sortOrder.ASC
  if self._sortParam.type == L_Const.sortType.star then
    L_CommonUtil.multipleSortByKey(spiritronListData, {
      "isSelf",
      isAsc and "-star" or "star",
      "spiritronLv",
      "quality",
      "spiritronId",
      "-guid"
    })
  elseif self._sortParam.type == L_Const.sortType.lv then
    L_CommonUtil.multipleSortByKey(spiritronListData, {
      "isSelf",
      isAsc and "-spiritronLv" or "spiritronLv",
      "star",
      "quality",
      "spiritronId",
      "-guid"
    })
  elseif self._sortParam.type == L_Const.sortType.quality then
    L_CommonUtil.multipleSortByKey(spiritronListData, {
      "isSelf",
      isAsc and "-quality" or "quality",
      "spiritronLv",
      "star",
      "spiritronId",
      "-guid"
    })
  end
  self.bind.scrollList_spiritron:clear()
  self.bind.scrollList_spiritron:insert_array(spiritronListData)
  self:updateSpiritronListItems()
end

function this:updateSpiritronListItems()
  local wguid = self:getCurrHeroSpiritronGuid()
  if self._selectGuid == wguid then
    self.modules.module_buttonEquip:setData(L_Const.ButtonType.GREY, wguid == 0 and L_WordsTpl:getValue("ui_moduleSpiritron_01") or L_WordsTpl:getValue("ui_moduleSpiritron_02"))
  else
    self.modules.module_buttonEquip:setData(L_Const.ButtonType.BLUE, wguid == 0 and L_WordsTpl:getValue("ui_moduleSpiritron_01") or L_WordsTpl:getValue("ui_moduleSpiritron_02"), handler(self, self.onClickEquip), {
      size = L_Const.StandardButtonSize
    })
  end
  for _, module in ipairs(self.modules.scrollList_spiritron) do
    module:refreshView()
    module:setSelectNum(module.bind.guid == self._selectGuid and 1 or 0)
  end
end

function this:getTimelineState()
  return L_Const.heroTimelineState.None
end

function this:setRead(guid)
  self._readSpirit = self._readSpirit or {}
  self._readSpirit[guid] = true
end

function this:clearReadNew()
  if not self:isPreviewMode() then
    for id, _ in pairs(self._readSpirit or {}) do
      L_ReddotManager:clearNew(L_ReddotManager.DotDef.SpiritNew, id)
    end
  end
  table.clear(self._readSpirit)
end

function this:getShowHeroAssets()
  return false
end

return this
