local this = class("pageRuneCompose", G_UIPageBase)
local talentRuneTpl = L_GameTpl:getTalentRuneTpl()
local talentRuneComposeTpl = L_GameTpl:getTalentRuneComposeTpl()
local commonItemTpl = L_GameTpl:getCommonItemTpl()
local targetNumToMove = 4
local MAX_COMPOSE_NUM = 999
local DEFAULT_TARGET_NUM = 1

function this.bind()
  return {
    targetList = {
      moduleName = "pages/rune/cellRuneComposeTarget"
    },
    composeList = {
      moduleName = "pages/rune/cellComposeMaterial"
    },
    moduleSelectNum = L_Const.ModuleInfo.SelectNum,
    numSelectActive = false,
    targetFocusIndex = 1,
    composeNum = "",
    targetStarList = {},
    infoStarList = {},
    targetIcon = "",
    targetInfoIcon = "",
    targetIconBg = "",
    targetIconLight = "",
    img_composeBg = "",
    img_quality = "",
    targetItemName = "",
    targetItemDesc = "",
    hadNumText = "",
    hadNumBg = "",
    needNumText = "",
    runeNameText = "",
    infoCardBg = "",
    accessList = {
      moduleName = "pages/rune/cellRuneComposeAccess"
    },
    hadFxActive = true,
    composeBtnActive = true,
    needNumTextActive = true,
    block = false
  }
end

function this.methods()
  return {
    onClick_composeBtn = function(self)
      if not self.isSatisified then
        L_FlyMsgManager:showNormalMsgByKey("notice_shortageMaterial")
        return
      end
      if self.runeIsDrop then
        return
      end
      local callback = function(rspData)
        self.bindComponents.showAnim:Stop()
        self.bindComponents.showAnim:Play("Anim_Rune_Synthesis")
        self.bind.block = true
        Timer.once(1.0, function()
          self.bind.block = false
          L_RewardManager:showPage(rspData.rewards, rspData.src, L_Const.pageRewardType.normal)
        end, self)
      end
      local data = {
        item_id = self.curTargetId,
        num = self.targetNum
      }
      L_RuneStore:req_CSProtoComposeRune(data, callback)
    end,
    targetList = {
      onClick_item = function(self, data)
        self:switchTarget(data)
      end
    },
    composeList = {
      onClick_item = function(self, data)
        self:switchTarget(data)
      end
    },
    onClick_closeBtn = function(self)
      L_UI:close(self.pageName)
    end
  }
end

function this:preOpen(options)
  this.super.preOpen(self, options)
  L_BagStore:listenCallFunc(L_BagStore.event.refreshBag, self.onEvent_composeSuccess, self)
  self.targetList = {}
  self.options = options
  self:setTargetNum(DEFAULT_TARGET_NUM)
  self:refreshPage(options)
  self:initSelectNumModule()
end

function this:close()
  L_BagStore:unListenCallFunc(L_BagStore.event.refreshBag, self.onEvent_composeSuccess, self)
end

function this:onEvent_composeSuccess()
  self.needTargetNum = self.needTargetNum - self.targetNum
  if self.needTargetNum < 1 then
    self.needTargetNum = 1
  end
  self:setTargetNum(self.needTargetNum)
  self:refreshTarget(self.curTargetId, true, true)
  self:initSelectNumModule()
end

function this:switchTarget(data)
  self.needTargetNum = data.targetNum
  self:setTargetNum(data.targetNum)
  self:refreshTarget(data.itemId, false)
  self:initSelectNumModule()
  self.bindComponents.showAnim:Stop()
  self.bindComponents.showAnim:Play("Anim_Rune_change")
end

function this:initSelectNumModule()
  local max = function()
    local maxCompose = self:getMaxCanCompose(self.curTargetId)
    if maxCompose > self.needTargetNum then
      return maxCompose
    else
      return self.needTargetNum
    end
  end
  local min = function()
    return DEFAULT_TARGET_NUM
  end
  local func = function(num)
    self:setTargetNum(num, true)
  end
  self.modules.moduleSelectNum:initModule(func, max, min, self.targetNum)
  func(self.targetNum)
end

function this:getMaxCanCompose(itemId)
  local composeTpl = talentRuneComposeTpl:getTplById(itemId)
  if not composeTpl then
    return MAX_COMPOSE_NUM
  end
  local items = talentRuneComposeTpl:getItems(composeTpl)
  local num = MAX_COMPOSE_NUM
  for _, item in ipairs(items) do
    local makeNum = math.floor(L_BagStore:getItemNum(item[2]) / item[3])
    if num > makeNum then
      num = makeNum
    end
  end
  return num
end

function this:refreshPage(options)
  self:refreshTarget(options.itemId, false)
end

function this:setTargetNum(targetNum, isRefresh)
  self.targetNum = targetNum
  if isRefresh then
    for i = 1, #self.bind.composeList do
      local base = self.bind.composeList:getValue(i, "baseNeed")
      if base ~= nil then
        self.bind.composeList:change(i, {
          needNum = base * targetNum
        })
      end
    end
    for _, v in ipairs(self.targetList) do
      if v.itemId == self.curTargetId then
        v.targetNum = targetNum
      end
    end
    self:refreshTargetItem(self.curTargetId, true)
    self:refreshBtnStatus()
  end
end

function this:refreshTarget(itemId, isForce, isExistAnim)
  if self.curTargetId == itemId and not isForce then
    return
  end
  self.curTargetId = itemId
  self:refreshTargetItem(itemId, isExistAnim)
  self:refreshTargetList(itemId)
  self:refreshComposeList(itemId)
  self:refreshBtnStatus()
end

function this:refreshBtnStatus()
  local hasSatisified = false
  local isSatisified = true
  if #self.bind.composeList > 0 then
    for i = 1, #self.bind.composeList do
      local hold = self.bind.composeList:getValue(i, "hadNum")
      local target = self.bind.composeList:getValue(i, "needNum")
      if hold ~= nil and target ~= nil then
        if hold < target then
          isSatisified = false
        else
          hasSatisified = true
        end
      end
    end
  end
  self.isSatisified = isSatisified
end

function this:refreshComposeList(itemId)
  self.bind.composeList:clear()
  local composeTpl = talentRuneComposeTpl:getTplById(itemId)
  if not composeTpl then
    local itemData = {}
    for i = 1, 4 do
      table.insert(itemData, {isEmpty = true})
    end
    self.bind.composeList:insert_array(itemData)
    return
  end
  local items = talentRuneComposeTpl:getItems(composeTpl)
  local itemData = {}
  for i = 1, 4 do
    local item = items[i]
    if item ~= nil then
      table.insert(itemData, {
        itemType = item[1],
        itemId = item[2],
        needNum = item[3] * self.targetNum,
        baseNeed = item[3],
        index = i,
        showType = L_Const.runeComposeType.compose,
        listSize = self.bindComponents.composeList.sizeDelta,
        hadNum = L_BagStore:getItemNum(item[2])
      })
    else
      table.insert(itemData, {isEmpty = true})
    end
  end
  self.bind.composeList:insert_array(itemData)
end

function this:refreshTargetItem(itemId, isExistAnim)
  self.targetData = {
    holdNum = L_BagStore:getItemNum(itemId),
    itemId = itemId,
    showType = L_Const.runeComposeType.target,
    targetNum = self.targetNum
  }
  local item = L_ItemTplManager:getCommonItem(itemId)
  self.bind.targetIcon = item.icon
  self.bind.targetInfoIcon = item.icon
  local tpl = commonItemTpl:getTplById(itemId)
  local rarity = commonItemTpl:getRarity(tpl)
  self:setStars(rarity + 1)
  self.bind.img_quality = string.format("UI/Atlas/Home/tex_homecommontip_bg_quality_%d.png", rarity)
  self.bind.targetIconBg = string.format("UI/Atlas/HeroRune/tex_talentrunecompose_bg_hc_o0%d.png", rarity)
  self.bind.targetIconLight = string.format("UI/Atlas/HeroRune/tex_talentrunecompose_bg_hc_l0%d.png", rarity)
  self.bind.img_composeBg = string.format("UI/Atlas/HeroRune/tex_talentrunecompose_bg_hc_all0%d.png", rarity)
  self.bind.hadNumBg = string.format("UI/Atlas/HeroRune/tex_talentrunecompose_bg_sl_t0%d.png", rarity)
  self.bind.infoCardBg = string.format("UI/Atlas/HeroRune/tex_talentrunecompose_bg_xq_t0%d.png", rarity)
  self.bind.targetItemName = item.name
  self.bind.runeNameText = item.name
  self.bind.targetItemDesc = item.desc
  self.bind.hadNumText = L_WordsTpl:getValue("ui_talent_rune_compose_01", {
    [0] = self.targetData.holdNum
  })
  local needStr = tostring(self.targetData.holdNum)
  if self.needTargetNum == nil then
    self.needTargetNum = self.targetNum
  end
  if self.targetData.holdNum < self.needTargetNum then
    needStr = L_GameUtil.fillColor(needStr, L_Const.colorHtml.red009)
  end
  self.bind.needNumText = L_WordsTpl:getValue("ui_talent_rune_compose_03", {
    [0] = needStr,
    [1] = self.needTargetNum
  })
  local runeTpl = talentRuneTpl:getTplByItemId(itemId)
  local hasItems = false
  local composeTpl = talentRuneComposeTpl:getTplById(itemId)
  if composeTpl ~= nil then
    local items = talentRuneComposeTpl:getItems(composeTpl)
    hasItems = 0 < #items
  end
  self.runeIsDrop = runeTpl == nil or not math.isEmpty(talentRuneTpl:getIsDrop(runeTpl)) or not hasItems
  self.bind.numSelectActive = not self.runeIsDrop
  self.bind.hadFxActive = not self.runeIsDrop
  self.bind.composeBtnActive = not self.runeIsDrop
  self.bind.needNumTextActive = not self.runeIsDrop
  self.bind.composeNum = L_WordsTpl:getValue("notice_pageRuneCompose", {
    [0] = self:getMaxCanCompose(itemId)
  })
  if self.runeIsDrop then
    self.bind.composeNum = L_WordsTpl:getValue("ui_talent_rune_compose_04")
  end
  local accessList = commonItemTpl:getWayList(tpl)
  if not isExistAnim then
    self:refreshAccessList(accessList, itemId)
  end
end

function this:refreshAccessList(accessList, itemId)
  self.bind.go_access = not table.isEmpty(accessList)
  local tmp = {}
  local playTime = 0.1
  for _, v in ipairs(accessList) do
    if v.id ~= L_SystemConst.jumpEnum.runeCompose then
      table.insert(tmp, {
        systemId = v.id,
        txt_access = v.desc,
        itemId = itemId,
        playTime = playTime
      })
      playTime = playTime + 0.05
    end
  end
  self.bind.accessList:clear()
  self.bind.accessList:insert_array(tmp)
  for _, access in pairs(self.modules.accessList) do
    access:playFx()
  end
end

function this:setStars(num)
  if not self.isBind then
    return
  end
  local stars = {}
  for i = 1, num do
    table.insert(stars, {})
  end
  self.bind.targetStarList:clear()
  self.bind.targetStarList:insert_array(stars)
  self.bind.infoStarList:clear()
  self.bind.infoStarList:insert_array(stars)
end

function this:refreshTargetList(itemId)
  local isOld = false
  local data = {}
  for _, v in ipairs(self.targetList) do
    v.needToPlay = false
    table.insert(data, v)
    if v.itemId == itemId then
      isOld = true
      break
    end
  end
  if not isOld then
    table.insert(data, {
      itemId = itemId,
      targetIndex = #self.targetList + 1,
      showType = L_Const.runeComposeType.targetList,
      targetNum = self.targetNum,
      needToPlay = true
    })
  end
  self.targetList = data
  for _, v in ipairs(self.targetList) do
    v.isTarget = v.itemId == itemId
    v.totalIndex = #self.targetList
  end
  self.bind.targetList:clear()
  self.bind.targetList:insert_array(self.targetList)
  self.bindComponents.targetListComp.disableScroll = #self.targetList < targetNumToMove
  self.bind.targetFocusIndex = #self.targetList
end

return this
