local SkinData = class("SkinData", BaseData)
local DEFAULT_SKIN_QLT = 1 -- 默认皮肤品质
local DEFAULT_FACTOR = GConst.BattleConst.DEFAULT_FACTOR

function SkinData:ctor()
    self.data.isDirty = false
end

function SkinData:clear()
end

function SkinData:init(data)
    data = data or GConst.EMPTY_TABLE
    if EDITOR_MODE then
        Logger.logHighlight("皮肤解锁数据")
        Logger.printTable(data)
    end

    self.unlockList = data
end

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

function SkinData:isOpen(showToast)
    if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.SKIN, not showToast) then
        return false
    end
    return true
end

-- 获取英雄已解锁的id
function SkinData:getUnlockList()
    if self.unlockList then
        return table.keys(self.unlockList)
    end

    return nil
end

-- 是否解锁
function SkinData:isUnlock(skinId)
    return self.unlockList[skinId] or self:getSkinCfg(skinId).qlt == DEFAULT_SKIN_QLT
end

-- 是否穿戴
function SkinData:isActived(skinId)
    local heroId = self:getHeroIdBySkinId(skinId)
    return DataManager.HeroData:getHeroById(heroId):getSkinId() == skinId
end

-- 获取皮肤配置
function SkinData:getSkinCfg(skinId)
    return ConfigManager:getConfig("skin")[skinId]
end

-- 获取英雄所有皮肤id(原皮>使用中>已解锁>未解锁>id)
function SkinData:getHeroAllSkinIdsSort(heroId)
    local result = {}
    local originSkinId = self:getOriginSkinId(heroId)
    for index, skinId in ipairs(ConfigManager:getConfig("hero")[heroId].skin) do
        table.insert(result, {id = skinId, sort = skinId})
    end

    for index, info in ipairs(result) do
        local cfg = self:getSkinCfg(info.id)
        if cfg == nil then
            Logger.printTable(info)
        end
        local sort = info.id
		sort = sort + 10000000 * cfg.qlt

        if info.id == originSkinId then
            sort = sort + 500000000000
        end
		if self:isUnlock(info.id) then
			sort = sort + 300000000000
			if self:isActived(info.id) then
				sort = sort + 400000000000
			else
				sort = sort + 300000000000
			end
		else
			sort = sort + 100000000000
		end

		info.sort = sort
    end
	table.sort(result, function(a, b)
		return a.sort > b.sort
	end)

	return result
end

-- 获取皮肤id所对应英雄id
function SkinData:getHeroIdBySkinId(skinId)
    if skinId == nil then
        return nil
    end

    local cfg = self:getSkinCfg(skinId)
    return cfg and cfg.hero_id
end

-- 获取皮肤id所对应道具id
function SkinData:getItemIdBySkinId(skinId)
    if skinId == nil then
        return nil
    end

    local cfg = self:getSkinCfg(skinId)
    return cfg and cfg.item_id
end

-- 获取道具id所对应的皮肤id
function SkinData:getSkinIdByItemId(itemId)
    local data, id =  table.find(ConfigManager:getConfig("skin"), function(info)
        return info.item_id == itemId
    end)
    return id
end

-- 获取英雄原始皮肤id
function SkinData:getOriginSkinId(heroId)
    local data, id =  table.find(ConfigManager:getConfig("skin"), function(info)
        return info.hero_id == heroId and info.qlt == DEFAULT_SKIN_QLT
    end)
    return id
end

-- 获取皮肤名称
function SkinData:getName(skinId)
    local name = I18N:getText("skin", skinId, "value")
    if not name then
        return ""
    end
    return name
end

-- 获取模型id
function SkinData:getModelId(skinId)
    local cfg = self:getSkinCfg(skinId)
    return cfg and cfg.model_id
end

-- 获取icon名称
function SkinData:getIcon(skinId)
    local cfg = self:getSkinCfg(skinId)
    if cfg and cfg.icon then
        return cfg.icon
    else
        local heroInfo = ConfigManager:getConfig("hero")[self:getHeroIdBySkinId(skinId)]
        return heroInfo and heroInfo.icon or ""
    end
end

-- 获取皮肤来源
function SkinData:getSource(skinId)
    return I18N:getGlobalText("SKIN_GOT_" .. self:getSkinCfg(skinId).got)
end

-- 获取皮肤属性
function SkinData:getAttr(skinId)
    return self:getSkinCfg(skinId).bonus
end

-- 皮肤属性相关接口start------------------------------------------------------------------------------------

-- 英雄是否拥有某属性
function SkinData:hasAttr(heroEntity, attrType)
    if table.containValue(GConst.MATCH_HP_FIX_NAME, attrType) then
        return self:getHp(heroEntity) > 0
    end
    if table.containValue(GConst.MATCH_ATTACK_NAME, attrType) then
        return self:getAttack(heroEntity) > 0
    end
    return table.find(self:getOwnAllAttr(heroEntity), function(value)
        return value.type == attrType
    end) ~= nil
end

-- 获取该英雄已拥有的所有皮肤属性（未经过计算，仅配置的属性数据）
function SkinData:getOwnAllAttr(heroEntity)
    local result = {}
    local unlockList = heroEntity:getSkins() or self:getUnlockList()
    if unlockList then
        for idx, skinId in pairs(unlockList) do
            local hero = self:getHeroIdBySkinId(skinId)
            local attrs = self:getAttr(skinId)
            if attrs and hero == heroEntity:getCfgId() then
                for index, attr in ipairs(attrs) do
                    local temp = table.find(result, function(value)
                        return value.type == attr.type
                    end)
    
                    if temp then
                        temp.num = temp.num + attr.num
                    else
                        table.insert(result, attr)
                    end
                end
            end
        end
    end

    return result
end

-- 获取基础生命值
function SkinData:getBaseHp(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_HP_FIX_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取加成后生命值
function SkinData:getHp(heroEntity)
    local result = self:getBaseHp(heroEntity)
    result = result + heroEntity:getTotalBaseHp() * self:getHpPercent(heroEntity) // DEFAULT_FACTOR
    return result
end

-- 获取基础攻击力
function SkinData:getBaseAttack(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_ATTACK_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取加成后攻击力
function SkinData:getAttack(heroEntity)
    local result = self:getBaseAttack(heroEntity)
    result = result + heroEntity:getTotalBaseAtk() * self:getAtkPercent(heroEntity) // DEFAULT_FACTOR
    return result
end

-- 获取攻击加成百分比
function SkinData:getAtkPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_ATTACK_ADD_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取生命值加成百分比
function SkinData:getHpPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_HP_ADD_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取普攻伤害
function SkinData:getNormalHurt(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_NORMAL_HURT_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取皮肤技能伤害
function SkinData:getSkillHurt(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_SKILL_HURT_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取暴击率百分比
function SkinData:getCritPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_CRIT_NAME, value.type)
    end)
    return result and result.num or 0
end

--获取暴击伤害百分比
function SkinData:getCritHurtPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_CRIT_TIME_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取治疗百分比
function SkinData:getHealPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_CURED_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取普攻增伤百分比
function SkinData:getNormalHurtPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_NORMAL_HURTP_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 获取技能增伤百分比
function SkinData:getSkillHurtPercent(heroEntity)
    local result = table.find(self:getOwnAllAttr(heroEntity), function(value)
        return table.containValue(GConst.MATCH_SKILL_HURTP_NAME, value.type)
    end)
    return result and result.num or 0
end

-- 皮肤属性相关接口end------------------------------------------------------------------------------------

-- 事件 --------------------------------------------------------------------------------------------------

-- 解锁皮肤
function SkinData:onUnlockSkin(itemId)
    local skinId = self:getSkinIdByItemId(itemId)
    if skinId == nil then
        return
    end
    local heroId = self:getHeroIdBySkinId(skinId)
    if heroId == nil then
        return
    end

    self.unlockList[skinId] = Time:getServerTime()
    DataManager.HeroData:getHeroById(heroId):onSkinAttrChange()

    self:setDirty()
end

-- 使用皮肤
function SkinData:onUseSkin(heroId, skinId)
    DataManager.HeroData:getHeroById(heroId):onChangeSkin(skinId)
    self:setDirty()
end

return SkinData