local DailyChallengeData = class("DailyChallengeData", BaseData)
local TASK_CFG = ConfigManager:getConfig("task_daily_challenge")
local PER_TASK = {[7] = true, [8] = true}
local FIXED_HERO_TASK = {[2] = true, [7] = true}
local MATCH_TYPE_TASK = {[5] = true, [8] = true}
local NEED_PROGRESS_TASK = {[3] = true, [4] = true, [5] = true, [7] = true, [8] = true}

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

function DailyChallengeData:init(data)
    if EDITOR_MODE then
        Logger.logHighlight("每日挑战 更新数据...")
        Logger.printTable(data)
    end
    data = data or GConst.EMPTY_TABLE
    self.maxWave = data.max_wave or 0
    self.fixedChapterId = data.today_fixed_chapter_id or 1
    self.chapterDailyId = data.rand_chapter_daily_id or 1
    self.tasks = data.tasks or GConst.EMPTY_TABLE
    self.buffIds = data.buff_id or GConst.EMPTY_TABLE
    self.totalFightCount = data.total_challenge_count or 0
    self.todayFightCount = data.today_challenge_count or 0
    self.initDay = Time:getBeginningOfServerToday()
    self.popTaskTime = LocalData:getChallengeTaskPopTime()
    self:setDirty()
end

function DailyChallengeData:onGetedTaskReward(idx)
    if self.tasks[idx] then
        self.tasks[idx].claimed = true
        self:setDirty()
    end
end

function DailyChallengeData:clear()
end

function DailyChallengeData:isOpen()
    if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.DAILY_CHALLENGE, true) then
        return false
    end
    return true
end

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

-- 是否满足挑战条件
function DailyChallengeData:isMeetChallenge()
    return self:isOpen() and self:isEnoughChallengeTime() and self:isEnoughHp()
end

-- 次数是否足够
function DailyChallengeData:isEnoughChallengeTime()
    return self:getTodayRemainLimitCount() > 0
end

-- 获取挑战次数消耗
function DailyChallengeData:getChallengeTimeCost()
    return GFunc.getConstIntValue("daily_challenge_limit")
end

-- 体力是否足够
function DailyChallengeData:isEnoughHp()
    local const = self:getChallengeHpCost()
    local constNum = nil
    if const then
        constNum =  GFunc.getRewardNum(const)
    else
        constNum = 0
    end
    return constNum <= DataManager.BagData.ItemData:getVit()
end

-- 获取挑战体力消耗
function DailyChallengeData:getChallengeHpCost()
    return GFunc.getConstReward("daily_challenge_cost")
    
end

-- 获取今日挑战场景配置
function DailyChallengeData:getMapConfig()
    return ConfigManager:getConfig("chapter_daily_challenge")[self:getChapterDailyId()]
end

function DailyChallengeData:getTaskCfg()
	if self.taskCfg == nil then
		self.taskCfg = ConfigManager:getConfig("task_daily_challenge")
	end
	return self.taskCfg
end

-- 获取今日通关次数
function DailyChallengeData:getTodayPassNum()
    return self.todayFightCount
end

-- 获取今日最高记录（最大通过波次）
function DailyChallengeData:getMaxWave()
    return self.maxWave
end

-- 获取今日增益、负面buff
function DailyChallengeData:getTodayBuffIds()
    return self.buffIds
end

-- 获取buff描述
function DailyChallengeData:getBuffDesc(buffId)
    return I18N:getText("buff_daily_challenge", buffId, "desc")
end

-- 获取最终boss配置信息
function DailyChallengeData:getFinalBossInfo()
    if not self:isOpen() then
        return
    end
    local mapCfg = self:getMapConfig()
    if not mapCfg then
        return
    end
    return ConfigManager:getConfig("monster")[mapCfg.monster[#mapCfg.monster]]
end

-- 任务是否完成
function DailyChallengeData:isTaskFinish(index)
    if not self:isOpen() then
        return false
    end
    local cfg = self:getTaskCfgInfo(self.tasks[index].task_id)
    if not cfg then
        return false
    end

    return cfg.param <= self.tasks[index].progress
end

function DailyChallengeData:getTasks()
    return self.tasks
end

function DailyChallengeData:getTaskById(taskId)
    for index, taskInfo in ipairs(self.tasks) do
        if taskInfo.task_id == taskId then
            return taskInfo
        end
    end

    return
end

-- 任务奖励是否可领取
function DailyChallengeData:canClaimTask(index)
    if not self:isOpen() then
        return false
    end
    if not self.tasks[index] then
        return false
    end
    if self.tasks[index].claimed then
        return false
    end

    return self:isTaskFinish(index)
end

function DailyChallengeData:getTaskProgresss(index)
    if not self:isOpen() then
        return 0
    end
    if not self.tasks[index] then
        return 0
    end
    return self.tasks[index].progress
end

function DailyChallengeData:getTaskCfgInfo(taskId)
    return TASK_CFG[taskId]
end

function DailyChallengeData:getTaskTotalNumber(taskId)
    if self:getTaskCfgInfo(taskId) then
        return self:getTaskCfgInfo(taskId).param
    else
        return 1 -- 容错，防止报错
    end
end

function DailyChallengeData:getTaskRewards(taskId)
    if self:getTaskCfgInfo(taskId) then
        return self:getTaskCfgInfo(taskId).reward
    end
    return nil
end

function DailyChallengeData:getTaskDesc(taskId, needProgress, customProgress)
    local desc = GConst.EMPTY_STRING
    if not I18N:getConfig("task_daily_challenge")[taskId] then
        return desc
    end
    local taskNum = self:getTaskTotalNumber(taskId)
    if PER_TASK[taskId] then
        taskNum = taskNum * 100 // GConst.BattleConst.DEFAULT_FACTOR
    end
    local taskInfo = self:getTaskById(taskId)
    if not taskInfo then
        return desc
    end

    local conditionStr
    if FIXED_HERO_TASK[taskId] then -- 具体英雄
        conditionStr = ModuleManager.HeroManager:getHeroName(taskInfo.param, true)
    elseif MATCH_TYPE_TASK[taskId] then -- 颜色英雄
        conditionStr = ModuleManager.HeroManager:getMatchTypeName(taskInfo.param, true)
    end

    if conditionStr then
        desc = I18N:getText("task_daily_challenge", taskId, "desc", conditionStr, taskNum)
    else
        desc = I18N:getText("task_daily_challenge", taskId, "desc", taskNum)
    end

    if needProgress and NEED_PROGRESS_TASK[taskId] then
        local progress = customProgress or taskInfo.progress
        if PER_TASK[taskId] then
            progress = progress * 100 // GConst.BattleConst.DEFAULT_FACTOR .. "%"
            taskNum = taskNum .. "%"
        end
        local progressStr = string.format("<color=#5FFF53>(%s/%s)</color>", progress, taskNum)
        desc = desc .. progressStr
    end
    return desc
end

function DailyChallengeData:getTodayRemainLimitCount()
    local count = self:getChallengeTimeCost() - self.todayFightCount
    if count < 0 then
        count = 0
    end
    return count
end

-- 处理主动退出的情况
function DailyChallengeData:onFightCountReduce()
    self.todayFightCount = self.todayFightCount + 1
end

function DailyChallengeData:getFixedChapterId()
    return self.fixedChapterId
end

function DailyChallengeData:getChapterDailyId()
    return self.chapterDailyId
end

function DailyChallengeData:setFixedChapterId(id)
    self.fixedChapterId = id
end

function DailyChallengeData:getTotalFightCount()
    return self.totalFightCount
end

function DailyChallengeData:getIfCanReset()
	return self.initDay < Time:getBeginningOfServerToday()
end

function DailyChallengeData:setShowingMainComp(isShow)
	self.showing = isShow
end

function DailyChallengeData:isShowingMainComp()
	return self.showing
end

function DailyChallengeData:setInReset(isInReset)
	self.isInReset = isInReset
end

function DailyChallengeData:getIsInReset()
	return self.isInReset
end

function DailyChallengeData:getIsPopTask()
    if not self:isOpen() then
        return false
    end
    return self.popTaskTime < Time:getBeginningOfServerToday()
end

function DailyChallengeData:markPopTask()
    if self.popTaskTime >= Time:getBeginningOfServerToday() then
		return
	end
	self.popTaskTime = Time:getBeginningOfServerToday()
	LocalData:setChallengeTaskPopTime(self.popTaskTime)
end

return DailyChallengeData