local RunesEntity = class("RunesEntity", BaseData)
local DEFAULT_FACTOR = GConst.BattleConst.DEFAULT_FACTOR

function RunesEntity:ctor(heroId, grids)
    self.heroId = heroId
    self.grids = grids or {}
end

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

function RunesEntity:updateGrids(grids)
    self.grids = grids or {}
    self:getHeroEntity():onRunesAttrChange()
    self:setDirty()
end

function RunesEntity:getHeroEntity()
    if self.heroEntity == nil then
        self.heroEntity = DataManager.HeroData:getHeroById(self.heroId)
    end

    return self.heroEntity
end

-- 符文栏是否锁定属性
function RunesEntity:isAttrLock(index)
    if self.grids[index] then
        return self.grids[index].lock
    end

    return false
end

-- 获取已锁定的符文栏个数
function RunesEntity:getAttrLockCount()
    local lock = 0
    for i = 1, GConst.RunesConst.MAX_ATTR_GRID_COUNT do
        if self:isAttrLock(i) then
            lock = lock + 1
        end
    end

    return lock
end

-- 是否存在品质大于s的未锁定
function RunesEntity:isUnlockHighQlt()
    for idx, data in ipairs(self.grids) do
        if table.containValue(DataManager.RunesData:getCheckQualityIds(), self:getGridQuality(idx)) and not self:isAttrLock(idx) then
            return true
        end
    end

    return false
end

-- 获取锻造的材料消耗
function RunesEntity:getMaterialCost()
    local base = GFunc.getConstReward("runes_cost_base")
    local add = GFunc.getConstReward("runes_cost_add")
    local total = {id = base.id, num = base.num, type = base.type}

    total.num = total.num + (add.num * self:getAttrLockCount())

    return total
end

-- 获取锻造的材料消耗个数
function RunesEntity:getMaterialCostNum()
    local num = DataManager.RunesData:getMaterialCostBaseNum()

    num = num + (DataManager.RunesData:getMaterialCostAddNum() * self:getAttrLockCount())

    return num
end

-- 获取格子的符文属性
function RunesEntity:getGridAttr(index)
    if self.grids[index] then
        local cfg = ConfigManager:getConfig("runes_sub")[self:getGridQuality(index)]
        local attr = cfg["attr_"..self:getGridAttrIndex(index)]
        if attr then
            return attr[self:getHeroEntity():getMatchType()]
        end
    end

    return nil
end

-- 获取格子属性下标
function RunesEntity:getGridAttrIndex(index)
    if not self:isAttrLock(index) and ModuleManager.RunesManager:isInAutoQuenching() then
        return DataManager.RunesData:getRandomGrids()[index].attr
    end

    if self.grids[index] then
        return self.grids[index].attr
    end

    return nil
end
-- 获取格子的品质
function RunesEntity:getGridQuality(index)
    if not self:isAttrLock(index) and ModuleManager.RunesManager:isInAutoQuenching() then
        return DataManager.RunesData:getRandomGrids()[index].quality
    end

    if self.grids[index] then
        return self.grids[index].quality
    end

    return nil
end

-- 获取格子的套装
function RunesEntity:getGridSuit(index)
    if not self:isAttrLock(index) and ModuleManager.RunesManager:isInAutoQuenching() then
        return DataManager.RunesData:getRandomGrids()[index].suit
    end

    if self.grids[index] then
        return self.grids[index].suit
    end

    -- Logger.logError("英雄".. self.heroId .. "未获取到格子的符文数据："..tostring(index))
    return nil
end

-- 获取套装等级,2件套是lv1,4件套是lv2，没有就是lv0
function RunesEntity:getSuitLevel(index)
    local data = table.find(self:getSuitIds(), function(value) return value.id == index end)
    local count = data and data.count or 0

    if count and count >= 4 then
        return 2
    end
    if count and count >= 2 then
        return 1
    end

    return 0
end

-- 获取已有的套装id map
function RunesEntity:getSuitIds()
    local typeCount = {}
    for i = 1, GConst.RunesConst.MAX_ATTR_GRID_COUNT do
        local t = self:getGridSuit(i)
        if t then
            local temp = table.find(typeCount, function(value) return value.id == t end)
            if temp then
                temp.count = temp.count + 1
            else
                table.insert(typeCount, {id = t, count = 1})
            end
        end
    end
    table.sort(typeCount, function(a, b)
        return a.count > b.count
    end)

    return typeCount
end

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

-- 获取所有属性加成，未经过计算加成
function RunesEntity:getAllAttr()
    if not DataManager.RunesData:isOpen() then
        return nil
    end

    local all = {}
    local func = function(attr)
        if attr == nil then
            return nil
        end

        local temp = table.find(all, function(value)
            return value.type == attr.type
        end)

        if temp then
            temp.num = temp.num + attr.num
        else
            table.insert(all, {type = attr.type, num = attr.num})
        end
    end

    -- 格子属性
    for i = 1, GConst.RunesConst.MAX_ATTR_GRID_COUNT do
        func(self:getGridAttr(i))
    end
    -- 套装属性
    local pos = self:getHeroEntity():getMatchType()
    for idx, data in pairs(self:getSuitIds()) do
        func(DataManager.RunesData:getSuitAttr(data.id, pos, self:getSuitLevel(data.id)))
    end

    return all
end

-- 是否拥有某属性
function RunesEntity:hasAttr(attrType)
    return self:getAttrValue(attrType) > 0
end

-- 获取属性 , isBase是否是基础配置的属性
function RunesEntity:getAttrValue(attrType, isBase)
    if type(attrType) ~= "string" then
        Logger.logError("获取符文属性传入格式错误")
        return 0
    end

    local result
    if not isBase and attrType == GConst.MATCH_HP_FIX_NAME[self:getHeroEntity():getMatchType()] then
        result = self:getAttrValue(GConst.MATCH_HP_FIX_NAME[self:getHeroEntity():getMatchType()], true)
        result = result + self:getHeroEntity():getTotalBaseHp() * self:getAttrValue(GConst.MATCH_HP_ADD_NAME[self:getHeroEntity():getMatchType()]) // DEFAULT_FACTOR
        return result
    elseif not isBase and attrType == GConst.MATCH_ATTACK_NAME[self:getHeroEntity():getMatchType()] then
        result = self:getAttrValue(GConst.MATCH_ATTACK_NAME[self:getHeroEntity():getMatchType()], true)
        result = result + self:getHeroEntity():getTotalBaseAtk() * self:getAttrValue(GConst.MATCH_ATTACK_ADD_NAME[self:getHeroEntity():getMatchType()]) // DEFAULT_FACTOR
        return result
    elseif not isBase and (attrType == GConst.MATCH_NORMAL_HURTP_NAME[self:getHeroEntity():getMatchType()] or attrType == GConst.MATCH_SKILL_HURTP_NAME[self:getHeroEntity():getMatchType()]) then
        result = self:getAttrValue(attrType, true)
        result = result + self:getAttrValue(GConst.MATCH_ALL_HURTP_NAME[self:getHeroEntity():getMatchType()], true)
        return result
    else
        local all = self:getAllAttr()
        if all == nil then
            return 0
        end
        result = table.find(all, function(value)
            return attrType == value.type
        end)
    end

    return result and result.num or 0
end

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

return RunesEntity