local this = class("moduleHeroData", require("ui.pages.HeroPanel.moduleHeroBase"))
local _charDataTpl = L_GameTpl:getCharDataTpl()
local _charVoiceTpl = L_GameTpl:getCharVoiceTpl()
local _charStoryTpl = L_GameTpl:getCharStoryTpl()
local _speciesTpl = L_GameTpl:getSpeciesTpl()
local _nationsTpl = L_GameTpl:getGroupsTpl()
local _heroFavorabilityExpTpl = L_GameTpl:getHeroFavorabilityExpTpl()
local _heroFavorabilityInfoTpl = L_GameTpl:getHeroFavorabilityInfoTpl()
local _charPlotTpl = L_GameTpl:getCharPlotTpl()
local animationName = {
  [L_Const.heroDataModuleType.Info] = "infoAnimation",
  [L_Const.heroDataModuleType.Story] = "storyAnimation",
  [L_Const.heroDataModuleType.Voice] = "voiceAnimation",
  [L_Const.heroDataModuleType.Drama] = "dramaAnimation"
}

function this.bind()
  return {
    infoPanel = false,
    storyPanel = false,
    voicePanel = false,
    dramaPanel = false,
    infoChoice = true,
    storyChoice = false,
    voiceChoice = false,
    dramaChoice = false,
    infoBackground = false,
    storyBackground = true,
    voiceBackground = true,
    dramaBackground = true,
    goBirthday = true,
    goCv = false,
    goStory = false,
    goDrama = false,
    goVoice = false,
    favorabilityLevel = "",
    favorabilityExp = "",
    favorabilityArea = true,
    favorabilityLevelArea = true,
    favorabilityDramaCount = "",
    head = "",
    name = "",
    birthday = "",
    nation = "",
    nationOtherText = "",
    nationActive = true,
    nationOtherActive = false,
    race = "",
    cv = "",
    resume = "",
    nationIcon = "",
    storyItemList = {
      moduleName = "pages/HeroPanel/hero/cellHeroStoryItem"
    },
    voiceItemList = {
      moduleName = "pages/HeroPanel/hero/cellHeroVoiceItem"
    },
    dramaItemList = {
      moduleName = "pages/HeroPanel/hero/cellHeroDramaItem"
    },
    resumeScrollNormalize = 1,
    storyScrollNormalize = 1,
    voiceScrollNormalize = 1,
    favorabilityLevelAreaAcive = true
  }
end

function this.methods()
  return {
    onClick_toggleInfo = function(self)
      self:btnChoice(L_Const.heroDataModuleType.Info, true)
    end,
    onClick_toggleStory = function(self)
      self:btnChoice(L_Const.heroDataModuleType.Story, true)
    end,
    onClick_toggleVoice = function(self)
      self:btnChoice(L_Const.heroDataModuleType.Voice, true)
    end,
    onClick_toggleDrama = function(self)
      self:btnChoice(L_Const.heroDataModuleType.Drama, true)
    end,
    onClick_goHome = function(self)
      local wordsTpl = L_GameTpl:getWordsTpl()
      L_FlyMsgManager:showNormalMsg(wordsTpl:getValue("notice_system_notdo"))
    end,
    onClick_testAddExp = function(self)
      if L_BattleDataManager:checkPlayerBattle() then
        L_FlyMsgManager:showNormalMsg(L_BattleDataManager:getBattleBlockTips(L_Const.BattleBlockType.HeroFAVORExpAdd))
        return
      end
      local hero = L_HeroStore:getHero(self.heroGuid)
      local addExp = 100
      local msg = {
        command = "ADDHEROFAVOREXP",
        args = {
          L_HeroStore:getHeroConfigId(hero),
          addExp
        }
      }
      L_Net:sendMessage(MsgGenCode.CSProtoGMCommand, msg, function()
        local charDataTpl = _charDataTpl:getTplById(self.heroConfigId)
        local tempName = _charDataTpl:getCharacterName(charDataTpl)
        if self.heroGuid == L_HeroStore:getDefaultHeroGuid() then
          tempName = L_PlayerStore:getPlayerName()
        end
        local tip1 = L_WordsTpl:getValue("ui_favor_add_target", {
          [0] = tempName
        })
        local tip2 = L_WordsTpl:getValue("ui_favor_add_value", {
          [0] = addExp
        })
        local tips = tip1 .. "|" .. tip2
        L_FlyMsgManager:showFavorabilityMsg(tips)
      end)
    end,
    onClick_favorabilityDetail = function(self)
      L_UI:open("pageHeroFavorabilityDetail", {
        heroId = self.heroGuid,
        preCallback = function()
          self.bind.favorabilityLevelAreaAcive = false
        end,
        closeCallback = function()
          self.bind.favorabilityLevelAreaAcive = true
        end
      })
    end,
    storyItemList = {
      storyToggle = function(self, id, newBool)
        if newBool then
          AzurWorld.heroMgr:ReqUpdateHeroCharData(self.heroConfigId, L_Const.heroData.story, {id})
        end
        for i = 1, #self.bind.storyItemList do
          if id ~= self.bind.storyItemList:getValue(i, "id") and self.bind.storyItemList:getValue(i, "isInfoOpen") then
            self.bind.storyItemList:change(i, {isInfoOpen = false})
            self.bind.storyItemList:getItemCls(i):refresh(false)
          end
        end
        self.backScrollNormalize = self.bindComponents.storyScroll.verticalNormalizedPosition
      end
    },
    voiceItemList = {
      voiceToggle = function(self, id, newBool, audioEvent)
        if newBool then
          AzurWorld.heroMgr:ReqUpdateHeroCharData(self.heroConfigId, L_Const.heroData.voice, {id})
        end
        for i = 1, #self.bind.voiceItemList do
          if id ~= self.bind.voiceItemList:getValue(i, "id") and self.bind.voiceItemList:getValue(i, "isInfoOpen") then
            self.bind.voiceItemList:change(i, {isInfoOpen = false})
            self.bind.voiceItemList:getItemCls(i):refresh()
          end
        end
        L_HeroVoiceManager:playHeroVoice(audioEvent)
        self.backScrollNormalize = self.bindComponents.voiceScroll.verticalNormalizedPosition
      end
    },
    onValueChanged_storyItemList = function(self, _)
      if not self.lockBackVertical then
        self.backScrollNormalize = nil
      end
    end,
    onValueChanged_voiceItemList = function(self, _)
      if not self.lockBackVertical then
        self.backScrollNormalize = nil
      end
    end
  }
end

function this:created(...)
  this.super.created(self, ...)
end

function this:open()
  self._ESyncHeroServerDataHandler = handler(self, self.onEvent_refreshHero)
  AzurWorld.heroMgr:RegisterEvent(C_EHeroEvent.ESyncHeroServerData, self._ESyncHeroServerDataHandler)
  L_TaskStore:listenCallFunc(L_TaskStore.event.refreshTask, self.onEvent_refreshTask, self)
  self._ESyncHeroFavorAbilityHandler = handler(self, self.onEvent_heroFavorabilityUp)
  AzurWorld.heroMgr:RegisterEvent(C_EHeroEvent.ESyncHeroFavorAbility, self._ESyncHeroFavorAbilityHandler)
  self:initSystem()
end

function this:close()
  self:destroyAllLocker()
  AzurWorld.heroMgr:UnregisterEvent(C_EHeroEvent.ESyncHeroServerData, self._ESyncHeroServerDataHandler)
  AzurWorld.heroMgr:UnregisterEvent(C_EHeroEvent.ESyncHeroFavorAbility, self._ESyncHeroFavorAbilityHandler)
  L_TaskStore:unListenCallFunc(L_TaskStore.event.refreshTask, self.onEvent_refreshTask)
end

function this:onEvent_heroFavorabilityUp(enum, varList)
  local heroList = varList:GetObject(0)
  local res = {}
  for i = 0, heroList.Count - 1 do
    table.insert(res, {
      heroId = heroList[i][0],
      startLevel = heroList[i][1]
    })
  end
  L_UI:open("pageHeroFavorabilityLevelUp", {heroList = res})
end

function this:initSystem()
  self.systemToTrans = {
    [L_SystemConst.enum.heroFavorability] = {
      self.bindComponents.favorabilityUnlockArea
    },
    [L_SystemConst.enum.heroDataStory] = {
      self.bindComponents.toggleStory
    },
    [L_SystemConst.enum.heroDataVoice] = {
      self.bindComponents.toggleVoice
    }
  }
  for systemId, v in pairs(self.systemToTrans) do
    v.locker = L_SystemUnlockManager:tryGenerateLocker(systemId)
    if v.locker then
      self:refreshSystem(systemId, false)
      v.locker:setCallback(self.refreshSystem, self, self.gameObject)
    else
      for _, trans in pairs(self.systemToTrans[systemId]) do
        trans.gameObject:ActiveTrans(true)
      end
    end
  end
end

function this:destroyAllLocker()
  for _, v in pairs(self.systemToTrans) do
    local locker = v.locker
    if locker then
      L_SystemUnlockManager:removeLocker(locker)
    end
  end
end

function this:refreshSystem(systemId, isUnlock)
  local node = self.systemToTrans[systemId]
  local locker = node.locker
  for _, v in ipairs(node) do
    local isNeedShow = locker:tryShowOrHide(v, isUnlock)
    if isNeedShow then
      v.gameObject:ActiveTrans(isUnlock)
    end
  end
end

function this:initPage(params)
  this.super.initPage(self)
  local forceRefresh = true
  forceRefresh = forceRefresh and (self.heroGuid == nil or self.heroGuid == self:getModeController():getSelectGuid())
  if forceRefresh then
    self:refresh(params, true)
  else
    self.bindComponents.infoAnimation:Stop()
    self.bindComponents.infoAnimation:Play("anim_heroes_data_info_hide")
    self:animationRefresh(params)
    self.bindComponents.infoAnimation:Play("anim_heroes_data_info_show")
    self:playChangeEffect()
  end
end

function this:playChangeEffect()
  self.bindComponents.favorabilityAnimation:Stop("anim_heroes_data_favor_show")
  self.bindComponents.favorabilityAnimation:Play("anim_heroes_data_favor_show")
end

function this:onEvent_refreshHero()
  if self.delayRefreshTimer then
    return
  end
  self:refreshHeroFavorabilityInfo()
  self:refreshFavorabilityDramaCount()
  if self.curPanelEnum == L_Const.heroDataModuleType.Info then
  elseif self.curPanelEnum == L_Const.heroDataModuleType.Story then
    self:refreshStory()
  elseif self.curPanelEnum == L_Const.heroDataModuleType.Voice then
    self:refreshVoice()
  elseif self.curPanelEnum == L_Const.heroDataModuleType.Drama then
    self:refreshDrama()
  end
end

function this:refreshVoice()
  for i = 1, #self.bind.voiceItemList do
    local id = self.bind.voiceItemList:getValue(i, "id")
    local tpl = _charVoiceTpl:getTplById(id)
    local unLockCondition = _charVoiceTpl:getUnlockCondition(tpl)
    local name = _charVoiceTpl:getTitle(tpl)
    local isComp, lockIndex = self:getConditionStatus(unLockCondition)
    if lockIndex then
      name = L_GameUtil.fillColor(_charVoiceTpl:getUnlockConditionText(tpl, lockIndex), L_Const.colorHtml.grey004)
    end
    local new = not L_HeroStore:getIsCharDataRead(self.heroConfigId, L_Const.heroData.voice, id)
    if not isComp then
      new = false
    end
    self.bind.voiceItemList:change(i, {
      title = name,
      lock = not isComp,
      new = new,
      openText = isComp
    })
  end
end

function this:refreshStory()
  for i = 1, #self.bind.storyItemList do
    local id = self.bind.storyItemList:getValue(i, "id")
    local tpl = _charStoryTpl:getTplById(id)
    local unLockCondition = _charStoryTpl:getUnlockCondition(tpl)
    local name = _charStoryTpl:getTitle(tpl)
    local isComp, lockIndex = self:getConditionStatus(unLockCondition)
    if lockIndex then
      name = L_GameUtil.fillColor(_charStoryTpl:getUnlockConditionText(tpl, lockIndex), L_Const.colorHtml.grey004)
    end
    local new = not L_HeroStore:getIsCharDataRead(self.heroConfigId, L_Const.heroData.story, id)
    if not isComp then
      new = false
    end
    self.bind.storyItemList:change(i, {
      name = name,
      lock = not isComp,
      new = new,
      openText = isComp
    })
  end
end

function this:refreshDrama()
  for i = 1, #self.bind.dramaItemList do
    local charPlot = _charPlotTpl:getTplByHeroId(self.heroConfigId, i)
    local dramaDesc = _charPlotTpl:getTitle(charPlot)
    local isComp, lockIndex = self:getConditionStatus(_charPlotTpl:getUnlockCondition(charPlot))
    if lockIndex then
      dramaDesc = _charPlotTpl:getUnlockConditionText(charPlot, lockIndex)
    end
    self.bind.dramaItemList:change(i, {unlockTips = dramaDesc, isUnlock = isComp})
  end
end

function this:onEvent_refreshTask()
  if self.delayRefreshTimer then
    return
  end
  if self.panelEnum ~= L_Const.heroDataModuleType.Drama then
    return
  end
  self:refreshHeroFavorabilityInfo()
  self:refreshFavorabilityDramaCount()
  for i = 1, #self.bind.dramaItemList do
    local charPlot = _charPlotTpl:getTplByHeroId(self.heroConfigId, i)
    local dramaDesc = _charPlotTpl:getTitle(charPlot)
    local isComp, result = L_ConditionManager:isComplete(_charPlotTpl:getUnlockCondition(charPlot))
    if isComp then
    else
      for i, v in ipairs(result) do
        if not v then
          dramaDesc = _charPlotTpl:getUnlockConditionText(charPlot, i)
          break
        end
      end
    end
    self.bind.dramaItemList:change(i, {unlockTips = dramaDesc, isUnlock = isComp})
    self.bind.dramaItemList:getItemCls(i):refresh()
  end
end

function this:refresh(params)
  self:clearDelayAnimationRefresh()
  self.heroGuid = self:getModeController():getSelectGuid()
  self.heroConfigId = self:getModeController():getSelectConfigId()
  local hero = self:getHero(self.heroGuid)
  self.rank = L_HeroStore:getHeroRank(hero)
  if self.heroGuid == L_HeroStore:getDefaultHeroGuid() then
    L_PhotoManager:bindPhotoEntity(self.bindComponents.head.gameObject, L_PlayerStore:getAvatarTexturePath(L_Const.avatarTextureIndex.head_talk))
  else
    self.bind.head = L_GameUtil.getAvatarTexturePath(L_HeroStore:getHeroConfigId(hero), L_Const.resourceIndexOfAvatarTextureInHeroTpl.mid)
  end
  L_ReddotManager:registerReddot(self.bindComponents.reddotStory, string.format(L_ReddotManager.DotDef.HeroInfo, self.heroConfigId .. "_story"))
  L_ReddotManager:registerReddot(self.bindComponents.reddotVoice, string.format(L_ReddotManager.DotDef.HeroInfo, self.heroConfigId .. "_voice"))
  L_ReddotManager:registerReddot(self.bindComponents.reddotDrama, string.format(L_ReddotManager.DotDef.HeroInfo, self.heroConfigId .. "_drama"))
  L_ReddotManager:registerReddot(self.bindComponents.reddotFavor, string.format(L_ReddotManager.DotDef.HeroInfo, self.heroConfigId .. "_favor"))
  local openPanelEnum = L_Const.heroDataModuleType.Info
  if params and params.openPanelEnum then
    openPanelEnum = params.openPanelEnum
  end
  self:btnChoice(openPanelEnum)
  self:refreshHeroFavorabilityInfo()
end

function this:refreshPanelData(panelEnum, bForceRefresh)
  self.backScrollNormalize = nil
  self.curPanelEnum = panelEnum
  if panelEnum == L_Const.heroDataModuleType.Info then
    self:infoPanelSet()
  elseif panelEnum == L_Const.heroDataModuleType.Story then
    self:storyPanelSet()
  elseif panelEnum == L_Const.heroDataModuleType.Voice then
    self:voicePanelSet()
  elseif panelEnum == L_Const.heroDataModuleType.Drama then
    self:dramaPanelSet()
  end
end

function this:animationRefresh(params)
  local animation
  if self.panelEnum ~= nil then
    local name = animationName[self.panelEnum]
    if name then
      animation = self.bindComponents[name]
    end
  end
  if animation == nil then
    self:refresh(params)
    return
  end
  self:refresh(params)
  self:clearDelayAnimationRefresh()
end

function this:unBind()
  self.super.unBind(self)
  self:clearDelayAnimationRefresh()
end

function this:clearDelayAnimationRefresh()
  if self.delayRefreshTimer then
    Timer.remove(self.delayRefreshTimer)
    self.delayRefreshTimer = nil
  end
end

function this:delayAnimationRefresh(params)
  local animation
  if self.panelEnum ~= nil then
    local name = animationName[self.panelEnum]
    if name then
      animation = self.bindComponents[name]
    end
  end
  if animation then
  end
  self:refresh(params)
end

function this:btnChoice(panelEnum, bCheckPanel)
  if panelEnum == self.panelEnum and bCheckPanel then
    return
  end
  self.panelEnum = panelEnum
  self.bind.infoPanel = panelEnum == L_Const.heroDataModuleType.Info
  self.bind.storyPanel = panelEnum == L_Const.heroDataModuleType.Story
  self.bind.voicePanel = panelEnum == L_Const.heroDataModuleType.Voice
  self.bind.dramaPanel = panelEnum == L_Const.heroDataModuleType.Drama
  self.bind.infoChoice = panelEnum == L_Const.heroDataModuleType.Info
  self.bind.storyChoice = panelEnum == L_Const.heroDataModuleType.Story
  self.bind.voiceChoice = panelEnum == L_Const.heroDataModuleType.Voice
  self.bind.dramaChoice = panelEnum == L_Const.heroDataModuleType.Drama
  self.bind.infoBackground = panelEnum ~= L_Const.heroDataModuleType.Info
  self.bind.storyBackground = panelEnum ~= L_Const.heroDataModuleType.Story
  self.bind.voiceBackground = panelEnum ~= L_Const.heroDataModuleType.Voice
  self.bind.dramaBackground = panelEnum ~= L_Const.heroDataModuleType.Drama
  self:refreshPanelData(self.panelEnum)
end

function this:infoPanelSet()
  local charDataTpl = _charDataTpl:getTplById(self.heroConfigId) or _charDataTpl:getTplById(101003)
  local tempName = _charDataTpl:getCharacterName(charDataTpl)
  if self.heroGuid == L_HeroStore:getDefaultHeroGuid() then
    tempName = L_PlayerStore:getPlayerName()
  end
  self.bind.name = tempName
  self.bind.birthday = _charDataTpl:getCharacterBirthday(charDataTpl)
  if self.heroConfigId == L_GameUtil.getDefaultHeroId(L_PlayerStore:getSex()) then
    local baseInfo = L_PlayerStore:getPlayerBaseInfo()
    local birthday = L_FriendStore:getPlayerBirthday(baseInfo)
    local notSetBirth = table.isEmpty(birthday)
    if not notSetBirth then
      self.bind.birthday = L_WordsTpl:getValue("notice_playercard_birthday", {
        month = birthday.month,
        day = birthday.day
      })
    else
      self.bind.birthday = L_WordsTpl:getValue("notice_playercard_birthday", {month = "\239\188\159", day = "\239\188\159"})
    end
  end
  local nationId = _charDataTpl:getCharacterNation(charDataTpl)
  self.bind.nation = _nationsTpl:getName(_nationsTpl:getTplById(nationId))
  self.bind.nationOtherText = _nationsTpl:getName(_nationsTpl:getTplById(nationId))
  local raceId = _charDataTpl:getCharacterRace(charDataTpl)
  self.bind.race = _speciesTpl:getName(_speciesTpl:getTplById(raceId))
  local voiceSettingId = L_SettingStore:getSetData(L_Const.settingType.language)
  local voiceLang = L_Const.settingText[L_Const.settingType.language][tonumber(voiceSettingId)]
  local cvName = L_Config:provider(charDataTpl["cv_" .. voiceLang])
  self.bind.cv = cvName
  self.bind.resume = _charDataTpl:getIntroduction(charDataTpl)
  self.bind.resumeScrollNormalize = 1
  self.bind.nationActive = nationId ~= L_Const.nations.other
  self.bind.nationOtherActive = nationId == L_Const.nations.other
  if nationId ~= L_Const.nations.other then
    local groupsTpl = L_GameTpl:getGroupsTpl()
    local iconPath = groupsTpl:getIcon(groupsTpl:getTplById(nationId), L_Const.nationTextureIndex.heroNation)
    self.bind.nationIcon = iconPath
  end
end

function this:storyPanelSet()
  self.bind.storyItemList:clear()
  self.bind.storyScrollNormalize = 1
  local charDataTpl = _charDataTpl:getTplById(self.heroConfigId)
  local storyTable = _charDataTpl:getCharacterStory(charDataTpl)
  local temp = {}
  for i, v in ipairs(storyTable) do
    local tpl = _charStoryTpl:getTplById(v)
    local unLockCondition = _charStoryTpl:getUnlockCondition(tpl)
    local name = _charStoryTpl:getTitle(tpl)
    local isComp, lockIndex = self:getConditionStatus(unLockCondition)
    if lockIndex then
      name = L_GameUtil.fillColor(_charStoryTpl:getUnlockConditionText(tpl, lockIndex), L_Const.colorHtml.grey004)
    end
    local new = not L_HeroStore:getIsCharDataRead(self.heroConfigId, L_Const.heroData.story, v)
    if not isComp then
      new = false
    end
    table.insert(temp, {
      id = v,
      name = name,
      lock = not isComp,
      new = new,
      openText = isComp,
      infoText = _charStoryTpl:getText(tpl),
      heroStory = Unity.Vector2(480, 115),
      isInfoOpen = false
    })
  end
  self.bind.storyItemList:insert_array(temp)
end

function this:voicePanelSet(keepPos)
  self.bind.voiceItemList:clear()
  if not keepPos then
    self.bind.voiceScrollNormalize = 1
  end
  local charDataTpl = _charDataTpl:getTplById(self.heroConfigId)
  local voiceTable = _charDataTpl:getCharacterVoice(charDataTpl)
  local temp = {}
  self.voiceNew = false
  for _, v in ipairs(voiceTable) do
    local tpl = _charVoiceTpl:getTplById(v)
    local unLockCondition = _charVoiceTpl:getUnlockCondition(tpl)
    local name = _charVoiceTpl:getTitle(tpl)
    local isComp, lockIndex = self:getConditionStatus(unLockCondition)
    if lockIndex then
      name = L_GameUtil.fillColor(_charVoiceTpl:getUnlockConditionText(tpl, lockIndex), L_Const.colorHtml.grey004)
    end
    local new = not L_HeroStore:getIsCharDataRead(self.heroConfigId, L_Const.heroData.voice, v)
    if not isComp then
      new = false
    end
    table.insert(temp, {
      id = v,
      title = name,
      action = _charVoiceTpl:getAction(_charVoiceTpl:getTplById(v)),
      audioEvent = _charVoiceTpl:getAudioEvent(_charVoiceTpl:getTplById(v)),
      lock = not isComp,
      new = new,
      infoText = _charVoiceTpl:getText(_charVoiceTpl:getTplById(v)),
      openText = isComp,
      heroVoice = Unity.Vector2(480, 115),
      isInfoOpen = false
    })
  end
  self.bind.voiceItemList:insert_array(temp)
end

function this:getConditionStatus(unLockCondition)
  local isComp, results = L_ConditionManager:isComplete(unLockCondition)
  if not isComp then
    for k, result in ipairs(results) do
      if not result then
        return isComp, k
      end
    end
  end
  return isComp
end

function this:refreshFavorabilityDramaCount()
  local charPlots = _charPlotTpl:getChildren(self.heroGuid)
  local unlockCount = 0
  for _, charPlot in ipairs(charPlots) do
    local isComp, _ = L_ConditionManager:isComplete(_charPlotTpl:getUnlockCondition(charPlot))
    if isComp then
      local taskId = _charPlotTpl:getTaskId(charPlot)
      local taskFinish = true
      if taskId and taskId ~= 0 then
        taskFinish = L_TaskStore:checkTaskIsFinished(taskId)
      end
      if taskFinish then
        unlockCount = unlockCount + 1
      end
    else
    end
  end
  self.bind.favorabilityDramaCount = unlockCount .. "/" .. #charPlots
end

function this:dramaPanelSet()
  self.bind.dramaItemList:clear()
  local charPlots = _charPlotTpl:getChildren(self.heroConfigId)
  local temp = {}
  local jumpIndex = 1
  for i, charPlot in ipairs(charPlots) do
    local dramaDesc = _charPlotTpl:getTitle(charPlot)
    local isComp, lockIndex = self:getConditionStatus(_charPlotTpl:getUnlockCondition(charPlot))
    if lockIndex then
      dramaDesc = _charPlotTpl:getUnlockConditionText(charPlot, lockIndex)
    end
    local charId = _charPlotTpl:getId(charPlot)
    table.insert(temp, {
      id = charId,
      heroId = self.heroGuid,
      heroConfigId = self.heroConfigId,
      unlockTips = dramaDesc,
      isUnlock = isComp,
      isPreview = self:isPreviewMode()
    })
    local taskId = _charPlotTpl:getTaskId(charPlot)
    local taskFinish = L_TaskStore:checkTaskIsFinished(taskId)
    if jumpIndex == 1 and isComp and not taskFinish then
      local new = not L_HeroStore:getIsCharDataRead(self.heroConfigId, L_Const.heroData.drama, charId)
      if new then
        jumpIndex = i
      end
    end
  end
  self.bind.dramaItemList:insert_array(temp)
  self.bindComponents.dramaTableView:FocusItemIndex(jumpIndex - 1)
  self:refreshFavorabilityDramaCount()
end

function this:refreshHeroFavorabilityInfo()
  local heroTpl = L_GameTpl.getHeroTpl()
  local tpl = heroTpl:getTplById(self.heroConfigId)
  local haveFavor = heroTpl:getFavor(tpl) == 1
  local showFavorabilityInfo = self:getModeController():checkShowFavorabilityInfo() and haveFavor
  self.bind.favorabilityArea = showFavorabilityInfo
  self.bind.goDrama = showFavorabilityInfo and L_SystemUnlockStore:getSystemIsOpen(L_SystemConst.enum.heroDataDrama)
  if not showFavorabilityInfo then
    return
  end
  local hero = self:getHero(self.heroGuid)
  local favorabilityLevel = L_HeroStore:getHeroFavorAbilityLevel(hero)
  local isMaxLevel = favorabilityLevel >= _heroFavorabilityExpTpl:getMaxFavorabilityLevel()
  self.bind.favorabilityLevel = string.format("%02d", favorabilityLevel)
  if favorabilityLevel == 0 then
    self.bind.favorabilityLevel = "0"
  end
  if isMaxLevel then
    self.bind.favorabilityExp = L_WordsTpl:getValue("menu_common_lvMax")
  else
    local maxExp = _heroFavorabilityExpTpl:getFavorabilityTotalExp(favorabilityLevel)
    local favorabilityExp = L_HeroStore:getHeroFavorAbilityExp(hero)
    local curExp = _heroFavorabilityExpTpl:getFavorabilityTotalExp(favorabilityLevel - 1) + favorabilityExp
    self.bind.favorabilityExp = curExp .. "/" .. maxExp
  end
  self.bind.favorabilityLevelArea = true
end

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

function this:checkItemPos(uiBinding, isInfoOpen, scrollName)
  local scroll = self.bindComponents[scrollName]
  if not scroll then
    return
  end
  if isInfoOpen then
    local isVisible, jumpY, clearBack = L_EffectUtil.isElementVerticalVisible(uiBinding, scroll.viewport, scroll.content)
    local contenSize = scroll.content.sizeDelta
    local viewPortRectSize = scroll.viewport.rect.size
    if not isVisible then
      self.lockBackVertical = true
      scroll.verticalNormalizedPosition = 1 - (jumpY - 10) / (contenSize.y - viewPortRectSize.y)
      FrameScheduler.add(function()
        self.lockBackVertical = false
      end, 1, uiBinding)
      if clearBack then
        self.backScrollNormalize = nil
      end
    end
  else
    if self.backScrollNormalize then
      local y = self.backScrollNormalize
      scroll.verticalNormalizedPosition = y
    end
    self.backScrollNormalize = nil
  end
end

return this
