local DailyChallengeManager = class("DailyChallengeManager", BaseModule)

function DailyChallengeManager:init()
    self:addEventListener(EventManager.CUSTOM_EVENT.CHANGE_MAIN_CITY_PAGE, function(idx)
        DataManager.DailyChallengeData:setShowingMainComp(idx == GConst.MainCityConst.BOTTOM_PAGE.MAIN)
    end)
    self:addEventListener(EventManager.CUSTOM_EVENT.UI_CLOSE, function(index)
		if index == UIManager.UI_PATH.MAINCITY_UI then
			DataManager.DailyChallengeData:setShowingMainComp(false)
		end
	end)
end

function DailyChallengeManager:showBattleBuffUI()
    UIManager:showUI("app/ui/battle/battle_daily_challenge_buff_ui")
end

function DailyChallengeManager:showBattleTaskUI()
    UIManager:showUI("app/ui/daily_challenge/daily_challenge_task_ui")
end

function DailyChallengeManager:getBuffDesc(id)
    local desc = I18N:getText("buff_daily_challenge", id, "desc")
    return desc
end

function DailyChallengeManager:checkDayChange()
    if not DataManager.DailyChallengeData:getIfCanReset() then
		return
	end
    if not DataManager.DailyChallengeData:isShowingMainComp() then
        return
    end

    -- 跨天了，请求新数据
    self:performWithDelayGlobal(function()
        self:onResetState()
    end, math.random())
end

-- 开始挑战
function DailyChallengeManager:startChallenge()
    -- 判断次数
    if not DataManager.DailyChallengeData:isEnoughChallengeTime() then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.DAILY_CHALLENGE_DESC_1))
        return
    end

    -- 判断体力
    if not DataManager.DailyChallengeData:isEnoughHp() then
        GFunc.showItemNotEnough(GConst.ItemConst.ITEM_ID_VIT)
        ModuleManager.CommerceManager:showBuyVitUI()
        return
    end

    -- 检查阵容
    if not DataManager.FormationData:formationIsFull(GConst.BattleConst.FORMATION_TYPE.STAGE) then
        GFunc.showToast(I18N:getGlobalText(I18N.GlobalConst.BATTLE_DESC_8))
        return
    end

    if not DataManager.DailyChallengeData:isMeetChallenge() then
        return
    end

    local parmas = {}
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterDailyChallengeStartReq, parmas, {}, self.rspStartChallenge, BIReport.ITEM_GET_TYPE.DAILY_CHALLENGE)
end

function DailyChallengeManager:rspStartChallenge(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        DataManager.DailyChallengeData:onFightCountReduce()
        DataManager.DailyChallengeData:setFixedChapterId(result.today_fixed_chapter_id)
        ModuleManager.BattleManager:playBattle(GConst.BattleConst.BATTLE_TYPE.DAILY_CHALLENGE)
    end
end

-- 挑战结束
function DailyChallengeManager:endChallenge(chapterId, combatReport, taskProgress, heroInfo, taskCurProgress)
    local parmas = {
        win = combatReport.victory,
        chapter_id = chapterId,
        hero_info = heroInfo,
        task_stat = taskProgress,
        combatReport = combatReport,
        taskCurProgress = taskCurProgress
    }

    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterDailyChallengeSettlementReq, parmas, {}, self.endChallengeFinish, BIReport.ITEM_GET_TYPE.DAILY_CHALLENGE_END)
end

function DailyChallengeManager:endChallengeFinish(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        if not result.reqData then
            return
        end
        local reqData = result.reqData
        local rewards = result.rewards
        ModuleManager.BattleManager:showBattleResultUI(GConst.BattleConst.BATTLE_TYPE.DAILY_CHALLENGE, rewards, reqData.combatReport)
        DataManager.DailyChallengeData:init(result.daily_challenge)
        ModuleManager.TaskManager:addFightTaskProgress(reqData.task_stat)

        -- bi日志上报任务完成情况
        local taskProgress = reqData.taskCurProgress or {}
        local completedCount = 0
        local taskInfo = {}
        local tasks = DataManager.DailyChallengeData:getTasks()
        for index, info in ipairs(tasks) do
            local id = info.task_id
            local idStr = tostring(id)
            taskInfo[idStr] = GFunc.getTable(info)
            taskInfo[idStr].curProgress = 0
            local progress = taskProgress[id]
            if progress then
                if type(progress) == "table" then
                    taskInfo[idStr].curProgress = progress[info.param] or 0
                else
                    taskInfo[idStr].curProgress = progress
                end
            end
            if info.claimed or DataManager.DailyChallengeData:canClaimTask(index) then
                completedCount = completedCount + 1
                if taskInfo[idStr].curProgress < (taskInfo[idStr].progress or 0) then
                    taskInfo[idStr].curProgress = taskInfo[idStr].progress or 0
                end
            end
        end
        BIReport:postDailyChallengeTaskState(completedCount, taskInfo)

        if result.reqData.win then
            ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_DAILY_CHALLENGE_SUCCESS)
        end
    end
end

function DailyChallengeManager:onResetState()
    if not DataManager.DailyChallengeData:isOpen() then
        return
    end
    if DataManager.DailyChallengeData:getIsInReset() then
        return
    end
    DataManager.DailyChallengeData:setInReset(true)
    self:sendMessage(ProtoMsgType.FromMsgEnum.ChapterDailyChallengeResetReq, {}, {}, self.rspResetState, BIReport.ITEM_GET_TYPE.DAILY_CHALLENGE_RESET)
end

function DailyChallengeManager:rspResetState(result)
    DataManager.DailyChallengeData:setInReset(false)
    DataManager.DailyChallengeData:init(result.daily_challenge)
end

-- 获取任务（箱子）奖励
function DailyChallengeManager:getTaskReward(idx)
    self.getRewardTaskIdx = idx
    local parmas = {
        idx = idx,
    }
    self:sendMessage(ProtoMsgType.FromMsgEnum.DailyChallengeTaskAwardReq, parmas, {}, self.getTaskRewardFinish, BIReport.ITEM_GET_TYPE.DAILY_CHALLENGE_TASK_REWARD)
end

function DailyChallengeManager:getTaskRewardFinish(result)
    if result.err_code == GConst.ERROR_STR.SUCCESS then
        GFunc.showRewardBox(result.rewards)
        DataManager.DailyChallengeData:onGetedTaskReward(self.getRewardTaskIdx)
    end
end

function DailyChallengeManager:dealTaskProgress(battleController)
    local teamEntity = battleController.battleData:getAtkTeam()
    local members = teamEntity:getAllMembers()
    local heroInfo = {}
    for k, v in pairs(members) do
        heroInfo[v:getId()] = {
            skill_cast = v:getActiveSkillReleaseCount(),
            Damage = v:getDamageCount(),
        }
    end

    local comboOver10Count = battleController.taskProgress[GConst.BattleConst.BATTLE_TASK_FIELD.COMBO_OVER_10]
    local linkCountOver8Count = battleController.taskProgress[GConst.BattleConst.BATTLE_TASK_FIELD.LINK_COUNT_OVER_8]

    local skillCountMap = {}
    local damageMatchTypeMap = {}
    local damageHeroMap = {}
    local totalDmg = 0
    for heroId, info in pairs(heroInfo) do
        local entity = DataManager.HeroData:getHeroById(heroId)
        if entity then
            skillCountMap[entity:getMatchType()] = info.skill_cast
            damageMatchTypeMap[entity:getMatchType()] = info.Damage
            damageHeroMap[heroId] = info.Damage
            totalDmg = totalDmg + info.Damage
        end
    end
    if totalDmg <= 0 then
        totalDmg = 1
    end

    for matchType, damage in pairs(damageMatchTypeMap) do
        damageMatchTypeMap[matchType] = math.floor(damage / totalDmg * GConst.BattleConst.DEFAULT_FACTOR + 0.000001)
    end

    for heroId, damage in pairs(damageHeroMap) do
        damageHeroMap[heroId] = math.floor(damage / totalDmg * GConst.BattleConst.DEFAULT_FACTOR + 0.000001)
    end

    local taskProgress = {
        [3] = comboOver10Count,
        [4] = linkCountOver8Count,
        [5] = skillCountMap,
        [7] = damageHeroMap,
        [8] = damageMatchTypeMap
    }
    return taskProgress
end

function DailyChallengeManager:getCurTaskProgress(battleController)
    local taskCurProgress ={}
    local taskProgress = self:dealTaskProgress(battleController)
    local tasks = DataManager.DailyChallengeData:getTasks()
    for index, info in ipairs(tasks) do
        local id = info.task_id
        local progress = taskProgress[id]
        if progress then
            if type(progress) == "table" then
                taskCurProgress[id] = progress[info.param] or 0
            else
                taskCurProgress[id] = progress
            end
        end
    end

    return taskCurProgress
end

return DailyChallengeManager