local HeroEntity = class("HeroEntity", BaseData)
local ATTR_NAME = GConst.BattleConst.ATTR_NAME

function HeroEntity:ctor(cfgId, lv, skin, star)
	self.cfgId = cfgId
	self.data.isDirty = false
	self.data.lv = lv
	self.data.skin = skin
	self.data.star = star or 0
	self.config = ConfigManager:getConfig("hero")[self.cfgId]
	self.beginLv = 1 -- 激活等级
	self.isNew = false

	self.baseAttrOriginal = {}
	self.starAttr = {}
	self.skinAttr = {}
	self.allBaseAttr = {}
	self.allAttr = {}
	self.attrDirty = true
	self.attrBaseDirty = true

	-- 基础属性里有全局属性 要优先初始化
	self:_getAllBaseAttr()
end

-- region 属性
function HeroEntity:initAttr()
	self.allBaseAttr[ATTR_NAME.HP] = 0
	self.allBaseAttr[ATTR_NAME.ATK] = 0
	self.allBaseAttr[ATTR_NAME.ATK_RED] = 0
	self.allBaseAttr[ATTR_NAME.ATK_YELLOW] = 0
	self.allBaseAttr[ATTR_NAME.ATK_GREEN] = 0
	self.allBaseAttr[ATTR_NAME.ATK_BLUE] = 0
	self.allBaseAttr[ATTR_NAME.ATK_PURPLE] = 0
	self.allBaseAttr[ATTR_NAME.DMGDEC] = 0

	self:_updateAllBaseAttr()
end

function HeroEntity:onBaseAttrChange()
	self:_updateBaseAttr()
	self:_updateTotalAttr()
	self:setDirty()
end

function HeroEntity:onStarAttrChange()
	self:_updateStarAttr()
	self:_updateTotalAttr()
	self:setDirty()
end

function HeroEntity:onSkinAttrChange()
	self:_updateSkinAttr()
	self:_updateTotalAttr()
	self:setDirty()
end

function HeroEntity:setDirty()
	self.data.isDirty = not self.data.isDirty
end

function HeroEntity:setAttrDirty()
	self.attrDirty = true
end

function HeroEntity:setBaseAttrDirty()
	self.attrBaseDirty = true
end

function HeroEntity:getAllAttr()
	if self.attrDirty == true then
		self.attrDirty = false
		self:_updateAllAttr()
	end
	return self.allAttr
end

-- 更新所有属性(包括其他英雄的加成)
function HeroEntity:_updateAllAttr()
	self.allAttr = {}
	self.allBaseAttr = self:_getAllBaseAttr()
	for k, v in pairs(self.allBaseAttr) do
		self.allAttr[k] = v
	end

	-- 装备
	local equipAttr = DataManager.EquipData:getEquipAttrBySlotId(self.cfgId, self:getMatchType())
	for k, v in pairs(equipAttr) do
		self.allAttr[k] = (self.allAttr[k] or 0) + v
	end
-- GConst.ALL_ATTR = {
-- 	ATTR_ATK_ALL = "atk_all",						-- 全体英雄攻击（固定值）
-- 	ATTR_HP_ALL = "attr_hp_all",					-- 全体英雄生命（固定值）
-- 	ATTR_DMGDEC_ALL = "attr_dmgdec_all",			-- 全体减伤（固定值）
-- 	ATTR_CRIT_ALL = "attr_crit_all",				-- 全体暴击率
-- 	ATTR_CRIT_TIME_ALL = "attr_crit_time_all",		-- 全体暴击伤害
-- 	ATTR_NORMAL_HURTP_ALL = "attr_normal_hurtp_all",-- 全体普攻增伤（百分比）
-- 	ATTR_SKILL_HURTP_ALL = "attr_skill_hurtp_all",	-- 全体技能增伤（百分比）
-- 	ATTR_ATKP_ALL = "attr_atkp_all",				-- 全体攻击（百分比）
-- }

	-- 同属性通用加成
	self.allAttr[GConst.MATCH_ALL_ATKP_NAME[self:getMatchType()]] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_ATK_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_HP_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_DMGDEC_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_CRIT_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_CRIT_TIME_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_NORMAL_HURTP_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_SKILL_HURTP_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_ATKP_ALL] = nil
	-- self.allAttr[GConst.ATTR_ALL.ATTR_HPP_ALL] = nil
	for _, v in pairs(GConst.ATTR_ALL) do
		self.allAttr[v] = nil
	end

	-- 攻击力（百分比）
	local atkType = GConst.MATCH_ATTACK_NAME[self:getMatchType()]
	-- 全局增加攻击力
	local allAtk = self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_ATK_ALL)
	local persionalAtk = self.allAttr[GConst.ATTR_PERSIONAL.ATTR_ATK] or 0
	local atk = self.allAttr[atkType] + allAtk + persionalAtk
	-- 全局元素攻击力百分比加成
	local allFactorValue = self:getGlobalAttrByType(GConst.MATCH_ALL_ATKP_NAME[self:getMatchType()])
	-- 个人攻击力百分比加成
	local factorValue = self.allAttr[GConst.MATCH_ATTACK_ADD_NAME[self:getMatchType()]] or 0
	-- 全局攻击力百分比加成
	local allAtkP = self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_ATKP_ALL)
	self.allAttr[atkType] = math.floor(atk * (1 + (factorValue + allFactorValue + allAtkP) / GConst.DEFAULT_FACTOR) + 0.0000001)
	self.allAttr[GConst.MATCH_ATTACK_ADD_NAME[self:getMatchType()]] = nil
	self.allAttr[GConst.ATTR_PERSIONAL.ATTR_ATK] = nil

	-- 生命（百分比）
	local hpType = GConst.MATCH_HP_NAME[self:getMatchType()]
	-- 全局增加生命
	local allHp = self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_HP_ALL)
	local persionalHp = self.allAttr[GConst.ATTR_PERSIONAL.ATTR_HP] or 0
	local hp = self.allAttr[hpType] + allHp + persionalHp
	-- 全局元素生命百分比加成
	local allFactorValue = self:getGlobalAttrByType(GConst.MATCH_ALL_HPP_NAME[self:getMatchType()])
	-- 个人生命百分比加成
	local factorValue = self.allAttr[GConst.MATCH_HP_ADD_NAME[self:getMatchType()]] or 0
	-- 全局生命百分比加成
	local allHpP = self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_HPP_ALL)
	self.allAttr[hpType] = math.floor(hp * (1 + (factorValue + allFactorValue + allHpP) / GConst.DEFAULT_FACTOR) + 0.0000001)
	self.allAttr[GConst.MATCH_HP_ADD_NAME[self:getMatchType()]] = nil
	self.allAttr[GConst.ATTR_PERSIONAL.ATTR_HP] = nil

	self.allAttr[ATTR_NAME.DMGDEC] = (self.allAttr[ATTR_NAME.DMGDEC] or 0) + self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_DMGDEC_ALL)
	self.allAttr[GConst.MATCH_CRIT_NAME[self:getMatchType()]] = (self.allAttr[GConst.MATCH_CRIT_NAME[self:getMatchType()]] or 0) + self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_CRIT_ALL)
	self.allAttr[GConst.MATCH_CRIT_TIME_NAME[self:getMatchType()]] = (self.allAttr[GConst.MATCH_CRIT_TIME_NAME[self:getMatchType()]] or 0) + self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_CRIT_TIME_ALL)
	self.allAttr[GConst.MATCH_NORMAL_HURTP_NAME[self:getMatchType()]] = (self.allAttr[GConst.MATCH_NORMAL_HURTP_NAME[self:getMatchType()]] or 0) + self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_NORMAL_HURTP_ALL) + self:getGlobalAttrByType(GConst.ATTR_PERSIONAL.ATTR_NORMAL_HURTP)
	self.allAttr[GConst.MATCH_SKILL_HURTP_NAME[self:getMatchType()]] = (self.allAttr[GConst.MATCH_SKILL_HURTP_NAME[self:getMatchType()]] or 0) + self:getGlobalAttrByType(GConst.ATTR_ALL.ATTR_SKILL_HURTP_ALL) + self:getGlobalAttrByType(GConst.ATTR_PERSIONAL.ATTR_SKILL_HURTP)

	self:calcPower()
end

function HeroEntity:getGlobalAttrByType(attrType)
	return DataManager.HeroData:getAttrByMatchType(self:getMatchType(), attrType) or 0
end

function HeroEntity:_getAllBaseAttr()
	if self.attrBaseDirty == true then
		self.attrBaseDirty = false
		self:_updateAllBaseAttr()
	end
	return self.allBaseAttr
end

-- 更新所有属性(自己)
function HeroEntity:_updateAllBaseAttr()
	self:_updateBaseAttr()
	self:_updateLvAttr()
	self:_updateStarAttr()
	-- self:_updateSkinAttr()
	self:_updateTotalAttr()

	-- 处理全局属性
	local attr = {}
	if self.allBaseAttr[GConst.MATCH_ALL_ATKP_NAME[self:getMatchType()]] ~= nil then
		attr[GConst.MATCH_ALL_ATKP_NAME[self:getMatchType()]] = self.allBaseAttr[GConst.MATCH_ALL_ATKP_NAME[self:getMatchType()]]
	end

	-- attr[GConst.ATTR_ALL.ATTR_ATK_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_ATK_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_HP_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_HP_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_DMGDEC_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_DMGDEC_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_CRIT_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_CRIT_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_CRIT_TIME_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_CRIT_TIME_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_NORMAL_HURTP_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_NORMAL_HURTP_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_SKILL_HURTP_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_SKILL_HURTP_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_ATKP_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_ATKP_ALL]
	-- attr[GConst.ATTR_ALL.ATTR_HPP_ALL] = self.allBaseAttr[GConst.ATTR_ALL.ATTR_HPP_ALL]
	for _, v in pairs(GConst.ATTR_ALL) do
		attr[v] = self.allBaseAttr[v]
	end

	DataManager.HeroData:setHeroAttr(self:getCfgId(), attr)
end

-- 更新英雄基础属性
function HeroEntity:_updateBaseAttr()
	self.baseAttrOriginal[ATTR_NAME.HP] = self:getCfgHp()
	self.baseAttrOriginal[ATTR_NAME.ATK_RED] = 0
	self.baseAttrOriginal[ATTR_NAME.ATK_YELLOW] = 0
	self.baseAttrOriginal[ATTR_NAME.ATK_GREEN] = 0
	self.baseAttrOriginal[ATTR_NAME.ATK_BLUE] = 0
	self.baseAttrOriginal[ATTR_NAME.ATK_PURPLE] = 0
	self.baseAttrOriginal[GConst.MATCH_ATTACK_NAME[self.config.position]] = self:getCfgAtk()
end

-- 更新升级属性
function HeroEntity:_updateLvAttr()
	self.lvAttr = {}
	local lvPoint = self:getLvAttrPointList()
	for i = 1, #lvPoint do
		if self.data.lv >= lvPoint[i] then
			local attr = self:getLvAttrCfg(i)
			self.lvAttr[attr.type] = (self.lvAttr[attr.type] or 0) + attr.num
		end
	end
end

-- 更新升星属性
function HeroEntity:_updateStarAttr()
	self.starAttr = {}
	for i = 1, self.data.star do
		local attrs = self:getStarAttrCfg(i)
		for _, attr in ipairs(attrs) do
			self.starAttr[attr.type] = (self.starAttr[attr.type] or 0) + attr.num
		end
	end
end

function HeroEntity:getStarAttr()
	self:getAllAttr()
	return self.starAttr
end

-- 更新皮肤属性
function HeroEntity:_updateSkinAttr()
	self.skinAttr = {}

	-- local hp = DataManager.SkinData:getHp(self)
	-- local atk = DataManager.SkinData:getAttack(self)
	-- local normalHurt = DataManager.SkinData:getNormalHurt(self)
	-- local skillHurt = DataManager.SkinData:getSkillHurt(self)
	-- local critPer = DataManager.SkinData:getCritPercent(self)
	-- local critHurtPer = DataManager.SkinData:getCritHurtPercent(self)
	-- local normalHurtPer = DataManager.SkinData:getNormalHurtPercent(self)
	-- local skillHurtPer = DataManager.SkinData:getSkillHurtPercent(self)
	-- local healPer = DataManager.SkinData:getHealPercent(self)

	-- self.skinAttr[GConst.MATCH_HP_NAME[self:getMatchType()]] = hp
	-- self.skinAttr[GConst.MATCH_ATTACK_NAME[self:getMatchType()]] = atk
	-- self.skinAttr[GConst.MATCH_NORMAL_HURT_NAME[self:getMatchType()]] = normalHurt
	-- self.skinAttr[GConst.MATCH_SKILL_HURT_NAME[self:getMatchType()]] = skillHurt
	-- self.skinAttr[GConst.MATCH_CRIT_NAME[self:getMatchType()]] = critPer
	-- self.skinAttr[GConst.MATCH_CRIT_TIME_NAME[self:getMatchType()]] = critHurtPer
	-- self.skinAttr[GConst.MATCH_NORMAL_HURTP_NAME[self:getMatchType()]] = normalHurtPer
	-- self.skinAttr[GConst.MATCH_SKILL_HURTP_NAME[self:getMatchType()]] = skillHurtPer
	-- self.skinAttr[GConst.MATCH_CURED_NAME[self:getMatchType()]] = healPer

	-- if EDITOR_MODE then
	-- 	local printStr = ""
	-- 	printStr = printStr .. "更新皮肤数值："..self:getCfgId() .. "\n"
	-- 	printStr = printStr .. "生命：".. hp .. "\n"
	-- 	printStr = printStr .. "攻击力：".. atk .. "\n"
	-- 	printStr = printStr .. "普攻增伤：".. normalHurt .. "\n"
	-- 	printStr = printStr .. "技能增伤：".. skillHurt .. "\n"
	-- 	printStr = printStr .. "暴击率：".. critPer .. "\n"
	-- 	printStr = printStr .. "暴击伤害百分比：".. critHurtPer .. "\n"
	-- 	printStr = printStr .. "普攻增伤百分比：".. normalHurtPer .. "\n"
	-- 	printStr = printStr .. "技能增伤百分比：".. skillHurtPer .. "\n"
	-- 	printStr = printStr .. "治疗加成百分比：".. healPer .. "\n"
	-- 	Logger.logHighlight(printStr)
	-- end
end

-- 更新总属性
function HeroEntity:_updateTotalAttr()
	self.allBaseAttr = {}
	for k, v in pairs(self.baseAttrOriginal) do
		self.allBaseAttr[k] = (self.allBaseAttr[k] or 0) + v
	end
	for k, v in pairs(self.lvAttr) do
		self.allBaseAttr[k] = (self.allBaseAttr[k] or 0) + v
	end
	for k, v in pairs(self.starAttr) do
		self.allBaseAttr[k] = (self.allBaseAttr[k] or 0) + v
	end
	-- for k, v in pairs(self.skinAttr) do
	-- 	self.allBaseAttr[k] = (self.allBaseAttr[k] or 0) + v
	-- end
end

function HeroEntity:getTotalAttrValue(name)
	local attr = self:getAllAttr()
	return attr[name] or 0
end

function HeroEntity:getAtk()
	local attr = self:getAllAttr()
	return attr[GConst.MATCH_ATTACK_NAME[self:getMatchType()]]
end

function HeroEntity:getHp()
	local attr = self:getAllAttr()
	return attr[GConst.MATCH_HP_NAME[self:getMatchType()]]
end

function HeroEntity:getCfgHp(lv)
	lv = lv or self.data.lv
	if lv > self:getMaxLv() then
		lv = self:getMaxLv()
	end
	if self.config and self.config.hp then
		return self.config.hp[lv] or 0
	end

	return 0
end

function HeroEntity:getCfgAtk(lv)
	lv = lv or self.data.lv
	if lv > self:getMaxLv() then
		lv = self:getMaxLv()
	end
	if self.config and self.config.atk then
		return self.config.atk[lv] or 0
	end

	return 0
end
-- endregion

-- region 基础
function HeroEntity:setLv(lv, onlyChangeLv)
	if not lv then
		return
	end
	if self.data.lv == lv then
		return
	end
	self.isNew = lv == 1
	self.data.lv = lv
	self:_updateAllBaseAttr()
	self:setDirty()
	self:setAttrDirty()

	if not onlyChangeLv then
		ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_HERO_LV_UP, lv)
		EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.HERO_UPGRADE_SUCCESS, self:getCfgId())
	end
end

function HeroEntity:getIsNew()
	local isNew = self.isNew
	self.isNew = false
	return isNew
end

function HeroEntity:getLv()
	return self.data.lv
end

function HeroEntity:getBeginLv()
	return self.beginLv
end

function HeroEntity:isMaxLv()
	return self.data.lv >= self:getMaxLv()
end

function HeroEntity:getMaxLv()
	if not self.maxLv then
		self.maxLv = ConfigManager:getConfigNum("hero_level")
	end
	return self.maxLv
end

-- function HeroEntity:getCurrMaxLv()
-- 	local cfg = ConfigManager:getConfig("hero_level")
-- 	local lv = self.data.lv
-- 	if lv <= 0 then
-- 		return 1
-- 	end
-- 	for i = self.data.lv, #cfg do
-- 		if cfg[i].star > self.data.star then
-- 			break
-- 		else
-- 			lv = i
-- 		end
-- 	end
-- 	return lv
-- end

function HeroEntity:getNextMaxLv()
	local cfg = ConfigManager:getConfig("hero_level")
	local lv = self.data.lv
	for i = self.data.lv + 1, #cfg do
		if self.data.star + 1 >= cfg[i].star then
			lv = i
		else
			break
		end
	end
	return lv
end

-- function HeroEntity:getNextLv()
-- 	local cfg = ConfigManager:getConfig("hero_level")
-- 	local lv = self.data.lv
-- 	for i = self.data.lv + 1, #cfg do
-- 		if self.data.star >= cfg[i].star then
-- 			lv = i
-- 		else
-- 			break
-- 		end
-- 	end
-- 	return lv
-- end

-- function HeroEntity:getIsCurLvMax()
-- 	if self:isMaxLv() then
-- 		return true
-- 	end
-- 	local cfg = ConfigManager:getConfig("hero_level")[self.data.lv + 1]
-- 	if not cfg then
-- 		return true
-- 	end
-- 	return self.data.star < cfg.star
-- end

function HeroEntity:canLvUp(showToast)
	if self:isMaxLv() then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.MAX_LV
	end

	-- if self:getIsCurLvMax() then
	-- 	return false, GConst.HeroConst.CHECK_LV_UP_STATE.NEED_STAR
	-- end

	local costNum = self:getLvUpMaterialNum()
	if not costNum then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.NO_COST
	end

	if not GFunc.checkCost(self:getLvUpCostId(), costNum, showToast) then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.FRAGMENT_NOT_ENOUGH
	end

	return true, GConst.HeroConst.CHECK_LV_UP_STATE.SUCCESS
end

function HeroEntity:isUnlock()
	if self:isActived() then
		return true
	else
		if self:canLvUp() then
			return true
		end
	end
	return false
end

function HeroEntity:isActived()
	return self.data.lv >= self:getBeginLv()
end

function HeroEntity:getLvUpLv()
	local count = 0
	local costId1 = self.config.level_id[1]
	local totalCost1 = 0
	local totalCost2 = 0
	-- local nextLv = self:getNextLv()
	for i = 1, 5 do
		-- if self.data.lv + i > nextLv then
		-- 	break
		-- end
		local lv = self.data.lv + i
		local nextLvInfo = ConfigManager:getConfig("hero_level")[lv]
		if not nextLvInfo then
			break
		end
		local needCostId = self:getLvUpCostId()
		if needCostId == costId1 then
			totalCost1 = totalCost1 + self:getLvUpMaterialNum()
			if not GFunc.checkCost(needCostId, totalCost1, false) then
				break
			end
		else
			totalCost2 = totalCost2 + self:getLvUpMaterialNum()
			if not GFunc.checkCost(needCostId, totalCost2, false) then
				break
			end
		end
		count = count + 1
	end
	return count + self.data.lv, count ~= 0
end
-- endregion

-- region 配置
function HeroEntity:getConfig()
	return self.config
end

function HeroEntity:getModelId()
	-- local skinModel = DataManager.SkinData:getModelId(self:getSkinId())
	-- return skinModel or self.config.model_id
	return self.config.model_id
end

function HeroEntity:getBaseSkill()
	return self.config.base_skill
end

function HeroEntity:getHurtSkill()
	return self.config.hurt_skill
end

function HeroEntity:getFragmentId()
	return self.config.item_id
end

function HeroEntity:getIcon()
	return self.config.icon
end

function HeroEntity:getHurtNum()
	return self.config.hurt_num
end

function HeroEntity:getLvUpCostId()
	local list = self:getLvAttrPointList()
	if table.containValue(list, self.data.lv + 1) then
		return self.config.level_id[2]
	else
		return self.config.level_id[1]
	end
end

function HeroEntity:getLvUpMaterialNum()
	if self.data.lv <= 0 then
		return
	end
	local lv = self.data.lv + 1
	if lv < self:getBeginLv() then
		lv = self:getBeginLv()
	end
	local nextLvInfo = ConfigManager:getConfig("hero_level")[lv]
	if not nextLvInfo then
		return
	end
	local fieldName = "cost_" .. self:getQlt()
	return nextLvInfo[fieldName][2]
end


function HeroEntity:getCfgId()
	return self.cfgId
end

function HeroEntity:getName()
	return ModuleManager.HeroManager:getHeroName(self:getCfgId())
end

function HeroEntity:getDesc()
	return ModuleManager.HeroManager:getHeroDesc(self:getCfgId())
end

function HeroEntity:getQlt()
	return self.config.qlt
end

function HeroEntity:getMatchType()
	return self.config.position
end

function HeroEntity:getStarUpCostId()
	return self.config.star_id
end

function HeroEntity:getStarAttrCfg(star)
	local cfg = ConfigManager:getConfig("hero_star")
	return cfg[star]["attr_" .. self:getQlt()]
end

function HeroEntity:getStarAttrTxt()
	return self.config.star_txt
end

function HeroEntity:getLvAttrCfg(lvPoint)
	if lvPoint then
		return self.config.level_attr[lvPoint]
	end
	return self.config.level_attr
end

function HeroEntity:getLvAttrPointList()
	return self.config.level_point
end
-- endregion

-- function HeroEntity:getActiveRogueCount()
-- 	local lvInfo = ConfigManager:getConfig("hero_level")[self.data.lv]
-- 	if not lvInfo then
-- 		return 0
-- 	end
-- 	--@TODO 123123
-- 	-- return lvInfo.unlock_skill
-- 	return 0
-- end

-- region 技能
function HeroEntity:getUnlockRogueId()
	return self.config.rouge_skill
end

function HeroEntity:checkSkillUnlock()
	if not self.oldStar then
		return false
	end
	local needPop = false
	local isUnlock = false
	local skillIdx = 1
	for i = 1, 4 do
		local ids = self.config["rouge_skill_" .. i]
		if ids then
			for ii = #ids, 1, -1 do
				if self.data.star >= ids[ii][1] and self.oldStar < ids[ii][1] then
					skillIdx = i
					needPop = true
					isUnlock = ii == 1
					break
				end
			end
		else
			break
		end
		if needPop then
			break
		end
	end
	self.oldStar = nil
	return needPop, isUnlock, skillIdx
end

function HeroEntity:getRogueSkillList()
	if not self.rogueSkillList then
		self.rogueSkillList = {}
		local count = 1
		while true do
			local ids = self.config["rouge_skill_" .. count]
			if ids then
				for i = #ids, 1, -1 do
					if self.data.star >= ids[i][1] or i == 1 then
						table.insert(self.rogueSkillList, ids[i])
						break
					end
				end
			else
				break
			end
			count = count + 1
		end
	end

	return self.rogueSkillList
end

function HeroEntity:getUnlockSkillIdx(checkUp)
	if not checkUp then
		return
	end
	local count = 1
	while true do
		local ids = self.config["rouge_skill_" .. count]
		if ids then
			for i = #ids, 1, -1 do
				if self.data.star == ids[i][1] then
					return count
				end
			end
		else
			break
		end
		count = count + 1
	end
end

function HeroEntity:getRogueSkillListBattle()
	if not self.rogueSkillListBattle then
		self.rogueSkillListBattle = {}
		local count = 1
		while true do
			local ids = self.config["rouge_skill_" .. count]
			if ids then
				for i = #ids, 1, -1 do
					if self.data.star >= ids[i][1] then
						table.insert(self.rogueSkillListBattle, ids[i][2])
						break
					end
				end
			else
				break
			end
			count = count + 1
		end
	end

	return self.rogueSkillListBattle
end

function HeroEntity:getRogueSkillListByIdx(idx)
	local ids = self.config["rouge_skill_" .. idx]
	local lv = 0
	if ids then
		for i = #ids, 1, -1 do
			if self.data.star >= ids[i][1]then
				lv = i
				break
			end
		end
	end
	return ids, lv
end

function HeroEntity:getNextRougeLvUp(idx)
	local ids = self.config["rouge_skill_" .. idx]
	if ids then
		for i,v in ipairs(ids) do
			if self.data.star < ids[i][1] then
				return ids[i][1]
			end
		end
	end
end

function HeroEntity:getActiveRogueSkills()
	local list = {}
	local count = 1
	while true do
		local ids = self.config["rouge_skill_" .. count]
		if ids then
			for i = #ids, 1, -1 do
				if self.data.star >= ids[i][1] then
					table.insert(list, ids[i][2])
					break
				end
			end
		else
			break
		end
		count = count + 1
	end
	return list
end
-- endregion

-- region 升星相关
function HeroEntity:getStar()
	return self.data.star
end

function HeroEntity:getIsStarMax()
	local nextLvInfo = ConfigManager:getConfig("hero_star")[self.data.star + 1]
	if not nextLvInfo then
		return true
	end
	return false
end

function HeroEntity:getStarUpMaterialNum()
	local nextLvInfo = ConfigManager:getConfig("hero_star")[self.data.star + 1]
	if not nextLvInfo then
		return
	end
	local fieldName = "cost_" .. self:getQlt()
	return nextLvInfo[fieldName]
end

function HeroEntity:canStarUp(showToast)
	if self:getIsStarMax() then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.MAX_LV
	end

	-- if not self:getIsCurLvMax() then
	-- 	return false, GConst.HeroConst.CHECK_LV_UP_STATE.NEED_LV
	-- end

	local costNum = self:getStarUpMaterialNum()
	if not costNum then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.NO_COST
	end

	if not GFunc.checkCost(self:getStarUpCostId(), costNum, showToast) then
		return false, GConst.HeroConst.CHECK_LV_UP_STATE.FRAGMENT_NOT_ENOUGH
	end
	-- local itemCost = cost[2] or 0
	-- if not GFunc.checkCost(self:getStarUpCostId(), itemCost, showToast) then
	-- 	return false, GConst.HeroConst.CHECK_LV_UP_STATE.COIN_NOT_ENOUGH
	-- end

	return true, GConst.HeroConst.CHECK_LV_UP_STATE.SUCCESS
end

function HeroEntity:onHeroStarUp()
	self.oldStar = self.data.star
	self.data.star = self.data.star + 1
	self:setBaseAttrDirty()
	self:setDirty()
	self:setAttrDirty()
end

function HeroEntity:getMaxStar()
	return #self:getStarCfg()
end

function HeroEntity:getStarCfg()
	return ConfigManager:getConfig("hero_star")
end

function HeroEntity:getStarUnlockSkillId(star)
	local count = 1
	while true do
		local ids = self.config["rouge_skill_" .. count]
		if ids then
			for i = #ids, 1, -1 do
				if star == ids[i][1] then
					return ids[i][2]
				end
			end
		else
			break
		end
		count = count + 1
	end
end
-- endregion

-- region 皮肤相关

-- 获取当前穿戴皮肤
function HeroEntity:getSkinId()
	if self.data.skin == nil or self.data.skin == 0 then
		return DataManager.SkinData:getOriginSkinId(self:getCfgId())
	end
	return self.data.skin
end

-- 穿戴皮肤
function HeroEntity:onChangeSkin(skinId)
	self.data.skin = skinId
	self:setDirty()
end

function HeroEntity:getSkins()
	return self.unlockSkins
end

function HeroEntity:setSkins(skinIds)
	self.unlockSkins = skinIds
	self:getTotalAttrValue() -- 防止报错
	self:onSkinAttrChange()
end
-- endregion

--@region 战力
function HeroEntity:setPowerDirty()
	self.data.isPowerDirty = not self.data.isPowerDirty
end

function HeroEntity:getPower()
	if not self.curPower or self.attrDirty then
		self:getAllAttr()
	end
	return self.curPower
end

-- 计算战斗力
function HeroEntity:calcPower()
	if self.lastPower then
		self.lastPower = self.curPower
	end
	self.curPower = math.floor(self:_getAttrPower())
	if not self.lastPower then
		self.lastPower = self.curPower
	end

	if self.lastPower ~= self.curPower then
		self:setPowerDirty()
	end
end

function HeroEntity:_getAttrPower()
	local power = 0
	for attrName, attrNum in pairs(self:getAllAttr()) do
		local cfg = GFunc.getAttrNameCfg()[attrName]
		if cfg then
			local realValue = attrNum
			-- 特殊处理，玩家基础暴击伤害不算
			if attrName == GConst.BattleConst.ATTR_NAME.CRIT_TIME then
				realValue = attrNum - 15000
			end

			power = power + math.floor(realValue * cfg.power / GConst.DEFAULT_FACTOR + 0.0000001)
		end
	end

	return power
end
--@endregion

--@region 红点
function HeroEntity:showRedPointEntrance()
	return self:canLvUp() or self:canStarUp()
end

function HeroEntity:showRedPoint(page, formationType)
	if page == GConst.HeroConst.PANEL_TYPE.HERO then
		return self:canLvUp()
	elseif page == GConst.HeroConst.PANEL_TYPE.STAR then
		return self:canStarUp()
	elseif page == GConst.HeroConst.PANEL_TYPE.EQUIP then
		self.curFormation = DataManager.FormationData:getFormation(formationType)
		if self.curFormation[self:getMatchType()] ~= self:getCfgId() then
			return false
		end
		return DataManager.EquipData:hasEquipRedPoint(self:getMatchType())
	end
end
--@endregion
return HeroEntity