local RunesData = class("RunesData", BaseData)
local RunesEntity = require "app/userdata/runes/runes_entity"

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

function RunesData:clear()
    DataManager:unregisterTryOpenFunc("RunesData")
end

function RunesData:init(data)
    data = data or GConst.EMPTY_TABLE
    if EDITOR_MODE then
        Logger.logHighlight("符文初始化数据")
        Logger.printTable(data)
    end

    self:updateLevelAndExp(data.level or 1, data.exp or 0)
    if data.heroes_grids then
        for heroId, grids in pairs(data.heroes_grids) do
            self:addRunes(heroId, grids.grids)
        end

        -- 处理上报
        local formation = DataManager.FormationData:getStageFormation()
        local runesChapter = {}
        for elementType, heroId in pairs(formation) do
            runesChapter[heroId] = data.heroes_grids[heroId]
        end
        BIReport:postRunes(BIReport.RUNES_FORMATION.CHAPTER, runesChapter)
    end

    -- 活动开启
    DataManager:registerTryOpenFunc("RunesData", function()
        if self:isOpen() then
            DataManager:unregisterTryOpenFunc("RunesData")
            self:setDirty()
        end
    end)
    self:setDirty()
end

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

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

function RunesData:addRunes(heroId, grids)
	if self.runes == nil then
        self.runes = {}
    end

    if self.runes[heroId] == nil then
        self.runes[heroId] = self:createEntity(heroId, grids)
    else
        self.runes[heroId]:updateGrids(grids)
    end
end

function RunesData:createEntity(heroId, grids)
	return RunesEntity:create(heroId, grids)
end

function RunesData:getRunes(heroId)
	if self.runes == nil then
        self.runes = {}
    end
    if self.runes[heroId] == nil then
        self.runes[heroId] = self:createEntity(heroId)
    end

	return self.runes[heroId]
end

-- 是否有红点
function RunesData:hasRedPoint(tempCount)
    return (tempCount or self:getMaterialCount()) > GFunc.getConstIntValue("runes_red_point")
end

-- 获取等级配置
function RunesData:getLevelConfig()
    if self.RuneCfg == nil then
        self.RuneCfg = ConfigManager:getConfig("runes_level")
    end

    return self.RuneCfg
end

-- 获取铸台最大等级
function RunesData:getMaxLevel()
    return #self:getLevelConfig()
end

-- 获取符文铸台等级
function RunesData:getLevel()
    return self.level
end

-- 获取等级当前经验
function RunesData:getLevelExp()
    return self.exp - (self:getLevelConfig()[self:getLevel()].cost or 0)
end

-- 获取总经验值
function RunesData:getExp()
    return self.exp
end

-- 根据经验获取等级
function RunesData:getLevelByExp(exp)
    local level
    for index, value in ipairs(self:getLevelConfig()) do
        if exp >= (value.cost or 0) then
            level = index
        else
            return level
        end
    end

    return level
end

-- 获取到下一档的总经验
function RunesData:getNextLevelTotalExp()
    local nextExp
    local cfg = self:getLevelConfig()[self:getLevel() + 1]
    if cfg then
        nextExp = cfg.cost or 0
    end
    local curExp = self:getLevelConfig()[self:getLevel()].cost or 0

    return nextExp - curExp
end

-- 获取需要检查锁定状态的品质的id
function RunesData:getCheckQualityIds()
    local curLevel = self:getLevel()
    local ids = {}
    if curLevel <= GConst.RunesConst.NOT_CHECK_QLT_LEVEL then
        return ids
    end

    for i = GConst.RunesConst.MAX_QUALITY_COUNT, 1, -1 do
        local weight = self:getQualityRate(self:getLevel(), i)
        if weight then
            table.insert(ids, i)
        end

        if #ids >= GConst.RunesConst.CHECK_QLT_LOCK_NUM then
            break
        end
    end
    table.sort(ids)

    return ids
end

-- 获取相应铸台等级的品质概率
function RunesData:getQualityRate(level, quality)
    local cfg = self:getLevelConfig()[level]

    local total = 0
    for i = 1, GConst.RunesConst.MAX_QUALITY_COUNT do
        total = total + (cfg["weight_"..i] or 0)
    end

    local value = cfg["weight_"..quality]
    if value then
        return string.format("%.2f",(value / total) * 100)
    end

    return nil
end

-- 获取相应套装的相应属性
function RunesData:getSuitAttr(id, heroType, suitLevel)
    local data = ConfigManager:getConfig("runes_suit")[id]
    local attrs
    if heroType == GConst.HeroConst.MATCH_TYPE.RED then
        attrs = data.red_suit_attr
    elseif heroType == GConst.HeroConst.MATCH_TYPE.YELLOW then
        attrs = data.yellow_suit_attr
    elseif heroType == GConst.HeroConst.MATCH_TYPE.GREEN then
        attrs = data.green_suit_attr
    elseif heroType == GConst.HeroConst.MATCH_TYPE.BLUE then
        attrs = data.blue_suit_attr
    elseif heroType == GConst.HeroConst.MATCH_TYPE.PURPLE then
        attrs = data.purple_suit_attr
    end

    if attrs ~= nil and attrs[suitLevel] then
        return attrs[suitLevel]
    end

    return nil
end

-- 获取锻造材料基础消耗个数
function RunesData:getMaterialCostBaseNum()
    if self.baseCostNum == nil then
        self.baseCostNum = GFunc.getConstReward("runes_cost_base").num
    end

    return self.baseCostNum
end

-- 获取锻造材料额外单个锁定消耗个数
function RunesData:getMaterialCostAddNum()
    if self.addCostNum == nil then
        self.addCostNum = GFunc.getConstReward("runes_cost_add").num
    end

    return self.addCostNum
end

-- 获取锻造材料个数
function RunesData:getMaterialCount()
    return DataManager.BagData.ItemData:getItemNumById(GConst.ItemConst.ITEM_ID_RUNES)
end

-- 是否可以一键铸造
function RunesData:canAutoMake()
    local cfg = self:getLevelConfig()[self:getLevel()]
    return cfg.auto and cfg.auto == 1
end

-- 获取自动铸造的开启等级
function RunesData:getAutoMakeOpenLevel()
    for level, data in ipairs(self:getLevelConfig()) do
        if data.auto and data.auto == 1 then
            return level
        end
    end

    return nil
end

-- 符文栏是否解锁
function RunesData:isUnlock(index)
    local level = self:getLevel()
    return index <= self:getLevelConfig()[level].grid
end

-- 获取符文栏解锁个数
function RunesData:getUnlockCount()
    local unlock = 0
    for i = 1, GConst.RunesConst.MAX_ATTR_GRID_COUNT do
        if self:isUnlock(i) then
            unlock = unlock + 1
        end
    end

    return unlock
end

-- 获取符文栏解锁等级要求
function RunesData:getUnlockLevel(index)
    for level, data in ipairs(self:getLevelConfig()) do
        if data.grid >= index then
            return level
        end
    end

    return 0
end

-- 获取套装名
function RunesData:getSuitName(index)
    if index == 1 then
        return I18N:getGlobalText(I18N.GlobalConst.RUNES_DESC_10)
    elseif index == 2 then
        return I18N:getGlobalText(I18N.GlobalConst.RUNES_DESC_11)
    elseif index == 3 then
        return I18N:getGlobalText(I18N.GlobalConst.RUNES_DESC_14)
    elseif index == 4 then
        return I18N:getGlobalText(I18N.GlobalConst.RUNES_DESC_12)
    elseif index == 5 then
        return I18N:getGlobalText(I18N.GlobalConst.RUNES_DESC_13)
    end

    return nil
end

-- 改变属性栏锁定状态成功
function RunesData:onGridLockSuccess(heroId, grids)
    self.runes[heroId]:updateGrids(grids)

    self:setDirty()
end

-- 获取随机一套grids数据
function RunesData:getRandomGrids()
    if self.fakeGrids == nil then
        self.fakeGrids = {}

        local maxQlt = self:getCheckQualityIds()[1] - 1
        for i = 1, GConst.RunesConst.FAKE_DATA_COUNT do
            self.fakeGrids[i] = {}
            for j = 1, GConst.RunesConst.MAX_ATTR_GRID_COUNT do
                local grid = {}
                grid.quality = math.random(maxQlt)
                grid.attr = math.random(GConst.RunesConst.MAX_ATTR_COUNT)
                grid.suit = math.random(GConst.RunesConst.MAX_SUITS_COUNT)
                table.insert(self.fakeGrids[i], grid)
            end
        end

        Logger.logHighlight("轮播假数据：")
        Logger.printTable(self.fakeGrids)
    end

    return self.fakeGrids[math.random(GConst.RunesConst.FAKE_DATA_COUNT)]
end

-- 获取本次同步已执行的自动淬炼次数
function RunesData:getExecutedAutoCount()
    return self.executedAutoCount
end

-- 获取当前自动淬炼的英雄
function RunesData:getAutoHeroId()
    return self.autoHeroId
end

-- 自动淬炼次数增加
function RunesData:onAutoQuenchingOnce()
    self.executedTotalAutoCount = self.executedTotalAutoCount + 1
    self.executedAutoCount = self.executedAutoCount + 1
end

-- 检查自动次数是否足够
function RunesData:checkAutoTime()
    if self.executedTotalAutoCount >= self.autoTotalCount then
        -- 剩余自动次数不足，同步并请求数据
        ModuleManager.RunesManager:reqSyncQuenching(self.isCountEnd)
    end
end

-- 淬炼成功
function RunesData:onQuenchingSuccess(level, exp, heroId, grids)
    self:updateLevelAndExp(level, exp)
    self.runes[heroId]:updateGrids(grids)

    self:setDirty()
end

-- 自动淬炼数据获取成功
function RunesData:onGetAutoQuenchingDataSuccess(heroId, count, isCountEnd)
    self.autoHeroId = heroId
    self.autoTotalCount = count
    self.executedTotalAutoCount = 0
    self.executedAutoCount = 0
    self.isCountEnd = isCountEnd

    self:setDirty()
end

-- 自动淬炼成功
function RunesData:onAutoQuenchingSuccess(level, exp, grids)
    self:updateLevelAndExp(level, exp)
    self.runes[self:getAutoHeroId()]:updateGrids(grids)
    self.executedAutoCount = 0

    self:setDirty()
end

-- 更新等级和经验
function RunesData:updateLevelAndExp(level, exp)
    if self.level and self.level ~= level then
        -- 等级变了，重置假数据
        self.fakeGrids = nil
    end

    self.level = level
    self.exp = exp
end

-- 自动淬炼失败
function RunesData:onAutoQuenchingFailed()
    self:setDirty()
end

return RunesData