local ActivityData = class("ActivityData", BaseData)

-- 活动id，目前只有这一个活动
local ACT_ID = 106
local ACT_DAYS = 7

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

function ActivityData:init()
    self.actData = {}

    ModuleManager.ActivityManager:initSummerTimer()
    ModuleManager.ActivityManager:reqSummerData()
end

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

function ActivityData:isOpen()
    if GFunc.isShenhe() then
        return false
    end
    if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.ACTIVITY, true) then
        return false
    end
    if not self:isOpenTime() then
        return
    end
    return true
end

-- 是否在活动配置时间内
function ActivityData:isOpenTime()
    local startTime = Time:getCertainTimeByStr(self:getActCfg().start_time)
    local endTime = Time:getCertainTimeByStr(self:getActCfg().end_time) + ACT_DAYS * 24 * 60 * 60
    return Time:getServerTime() >= startTime and Time:getServerTime() <= endTime
end

-- 获取活动id
function ActivityData:getActId()
    return ACT_ID
end

-- 获取活动时间配置
function ActivityData:getActCfg()
    return ConfigManager:getConfig("activity")[ACT_ID]
end

-- 获取活动战令配置
function ActivityData:getBountyCfg()
    if self.bountyCfg == nil then
        self.bountyCfg = {}
        for id, data in pairs(ConfigManager:getConfig("activity_bounty_level")) do
            if data.act_id == ACT_ID then
                data.id = id
                table.insert(self.bountyCfg, data)
            end
        end
        table.sort(self.bountyCfg, function (a, b)
            return a.id < b.id
        end)
    end

    return self.bountyCfg
end

-- 是否在活动时间内
function ActivityData:isActive()
    if self.actData == nil or self.actData.activated_at == nil or self.actData.activated_at <= 0 then
        return false
    end

    local startTime = Time:getBeginningOfOneDay(self.actData.activated_at // 1000)
    local endTime = startTime + ACT_DAYS * 24 * 60 * 60
    return Time:getServerTime() >= startTime and Time:getServerTime() <= endTime
end

-- 获取活动开启剩余时间（秒）
function ActivityData:getStartRemainTime()
    local startTime = Time:getCertainTimeByStr(self:getActCfg().start_time)
    return startTime - Time:getServerTime()
end

-- 获取活动结束剩余时间（秒）
function ActivityData:getEndRemainTime()
    if self.actData == nil or self.actData.activated_at == nil or self.actData.activated_at <= 0 then
        return 0
    end

    local startTime = Time:getBeginningOfOneDay(self.actData.activated_at // 1000)
    local endTime = startTime + ACT_DAYS * 24 * 60 * 60
    return math.floor(endTime) - Time:getServerTime()
end

-- 当前为活动第几天
function ActivityData:getActDay()
    if self.actData == nil or self.actData.activated_at == nil or self.actData.activated_at <= 0 then
        return 0
    end

    local days = Time:getDistanceDays(self.actData.activated_at // 1000)
    if days < 0 then
        days = -days
    end
    return days + 1
end

-- 获取活动标题
function ActivityData:getActTitle()
    return I18N:getGlobalText(I18N.GlobalConst.ACT_DESC_2)
end

-- 获取活动标题背景
function ActivityData:getActTitleBg()
    return GConst.ATLAS_PATH.ACT_SUMMER, "act_summer_title_1"
end

-- 是否有入口红点
function ActivityData:hasEntryRedPoint()
    return self:hasTaskRedPoint() or self:hasBountyRedPoint() or self:hasSkinRedPoint() or self:hasHeroRedPoint()
end

-- 获取活动数据成功
function ActivityData:onGetActData(data)
    self.actData = data

    
    if self:isActive() then
        -- 注册任务进度监听
        for id, data in ipairs(ConfigManager:getConfig("activity_bounty_task")) do
            ModuleManager.TaskManager:registerTask("ActivityData", data.type, function(count)
                self:addTaskProgress(data.type, count)
            end)
        end
        self:markGiftPop()
    end

    if EDITOR_MODE then
        Logger.logHighlight("夏日活动：".. self:getActDay())
        Logger.printTable(data)
    end

    self:setDirty()
end

-- 任务--------------------------------------------------------------------------------------------------

-- 获取今日任务列表
function ActivityData:getTaskListSort()
    local canGet = {}
    local unfinish = {}
    local result = {}

    for index, id in ipairs(table.keys(ConfigManager:getConfig("activity_bounty_task"))) do
        if self:canGetTaskReward(id) then
            -- 已完成
            if self:isReceivedTaskReward(id) then
                -- 已领取
                table.insert(result, id)
            else
                -- 未领取
                table.insert(canGet, id)
            end
        else
            --未完成
            table.insert(unfinish, id)
        end
    end

    unfinish = table.addArray(canGet, unfinish)
    result = table.addArray(unfinish, result)

    return result
end

-- 获取任务目标
function ActivityData:getTaskTarget(id)
    return ConfigManager:getConfig("activity_bounty_task")[id].number[self:getTaskStage(id)]
end

-- 获取任务奖励
function ActivityData:getTaskRewardNum(id)
    return ConfigManager:getConfig("activity_bounty_task")[id].reward[self:getTaskStage(id)]
end

-- 获取任务icon
function ActivityData:getTaskIcon(id)
    return ConfigManager:getConfig("activity_bounty_task")[id].icon
end

-- 获取任务描述
function ActivityData:getTaskDesc(id)
    local cfg = I18N:getConfig("activity_bounty_task")
    if cfg == nil then
        return GConst.EMPTY_STRING
    end
	return cfg[id].desc
end

-- 获取任务类型
function ActivityData:getTaskType(id)
    return ConfigManager:getConfig("activity_bounty_task")[id].type
end

-- 获取任务总阶段数
function ActivityData:getTaskTotalStageNum(id)
    local cfg = ConfigManager:getConfig("activity_bounty_task")[id]
    if #cfg.number ~= #cfg.reward then
        Logger.logError("活动任务阶段和奖励数量不一致，让策划检查配置！")
    end

    return #cfg.number
end

-- 获取任务所处阶段
function ActivityData:getTaskStage(id)
    local stage = 1
    local maxStage = self:getTaskTotalStageNum(id)
    stage = self:getTaskClaimedStage(id) + 1
    if stage > maxStage then
        stage = maxStage
    end
    return stage
end

-- 获取任务进度
function ActivityData:getTaskProgress(id)
    local taskType = self:getTaskType(id)
    if self.actData and self.actData.task_info and self.actData.task_info.summer_task and self.actData.task_info.summer_task[taskType] then
        return self.actData.task_info.summer_task[taskType]
    end
    return 0
end

-- 获取任务已领取的最大阶段
function ActivityData:getTaskClaimedStage(id)
    local taskType = self:getTaskType(id)
    if self.actData and self.actData.task_info and self.actData.task_info.claimed_stage and self.actData.task_info.claimed_stage[taskType] then
        return self.actData.task_info.claimed_stage[taskType]
    end
    return 0
end

-- 任务是否完成
function ActivityData:canGetTaskReward(id)
    return self:getTaskProgress(id) >= self:getTaskTarget(id)
end

-- 任务奖励是否已领取
function ActivityData:isReceivedTaskReward(id)
    return self:getTaskClaimedStage(id) >= self:getTaskStage(id)
end

-- 是否有任务红点
function ActivityData:hasTaskRedPoint()
    for index, id in ipairs(table.keys(ConfigManager:getConfig("activity_bounty_task"))) do
        if self:canGetTaskReward(id) and not self:isReceivedTaskReward(id) then
            return true
        end
    end
    return false
end

-- 添加任务进度
function ActivityData:addTaskProgress(taskType, count)
    if self.actData.task_info.summer_task[taskType] == nil then
        self.actData.task_info.summer_task[taskType] = 0
    end
    self.actData.task_info.summer_task[taskType] = self.actData.task_info.summer_task[taskType] + count

	self:setDirty()
end

-- 领取任务奖励成功
function ActivityData:onReceivedTaskReward(id, getMaxStage, level, exp)
    local taskType = self:getTaskType(id)
    self.actData.task_info.claimed_stage[taskType] = getMaxStage
    self.actData.level = level
    self.actData.exp = exp
    self:setDirty()
end

-- 战令--------------------------------------------------------------------------------------------------

-- 战令档位是否已解锁
function ActivityData:isBountyGradeUnlock(grade)
    if grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE then
        return true
    elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
        return DataManager.ShopData:getGiftBoughtNum(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.ActivityConst.BOUNTY_GIFT_ID_1) > 0
    elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
        return DataManager.ShopData:getGiftBoughtNum(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.ActivityConst.BOUNTY_GIFT_ID_2) > 0
    end
    return false
end

-- 获取战令档位礼包配置
function ActivityData:getBountyGradeGiftCfg(gradeType)
    if gradeType == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
        return DataManager.ShopData:getActGiftConfig()[GConst.ActivityConst.BOUNTY_GIFT_ID_1]
    elseif gradeType == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
        return DataManager.ShopData:getActGiftConfig()[GConst.ActivityConst.BOUNTY_GIFT_ID_2]
    end
end

-- 战令最大等级
function ActivityData:getBountyMaxLevel()
    return #self:getBountyCfg()
end

-- 获取战令等级
function ActivityData:getBountyLevel()
    if self.actData == nil or self.actData.level == nil then
        return 1
    end

    if self.actData.level <= self:getBountyMaxLevel() then
        return self.actData.level
    else
        return self:getBountyMaxLevel()
    end
end

-- 获取当前等级战令积分
function ActivityData:getBountyLevelScore()
    if self.actData == nil or self.actData.exp == nil then
        return 0
    end
    return self.actData.exp
end

-- 获取当前升级所需总积分
function ActivityData:getBountyUpgradeScore()
    return self:getBountyCfg()[self:getBountyLevel()].exp or 0
end

-- 是否满足购买战令等级的条件
function ActivityData:canBuyBountyLevel()
    return self:getActDay() >= GFunc.getConstIntValue("activity_bounty_day")
end

-- 购买战令等级的消耗
function ActivityData:getBuyBountyLevelCost()
    return GFunc.getConstReward("activity_bounty_cost")
end

-- 是否有战令红点
function ActivityData:hasBountyRedPoint()
    local curLevel = self:getBountyLevel()
    local lv = 0
    for idx, data in ipairs(self:getBountyCfg()) do
        lv = lv + 1
        if lv > curLevel then
            break
        end

        if self:canGetBountyReward(lv, GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE) then
            return true
        end
        if self:canGetBountyReward(lv, GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1) then
            return true
        end
        if self:canGetBountyReward(lv, GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2) then
            return true
        end
    end

    return false
end

-- 获取战令档位所有奖励，排序
function ActivityData:getBountyGradeAllRewardSort(grade)
    local rewards = {}
    for idx, data in ipairs(self:getBountyCfg()) do
        if grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE then
            table.insert(rewards, data.reward)
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
            table.insert(rewards, data.reward_pro)
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
            table.insert(rewards, data.reward_pro_max)
        end
    end
    rewards = GFunc.mergeRewards(rewards)
    table.sort(rewards, function(a, b)
        return a.id > b.id
    end)

    return rewards
end

-- 获取战令档位奖励
function ActivityData:getBountyGradeReward(level, grade)
    local cfg = self:getBountyCfg()[level]
    local result
    if cfg ~= nil then
        if grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE then
            result = cfg.reward
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
            result = cfg.reward_pro
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
            result = cfg.reward_pro_max
        end
    end
    return result
end

-- 战令奖励是否满足领取条件
function ActivityData:isReachBountyReward(level, grade)
    local curLevel = self:getBountyLevel()
    if curLevel >= level then
        return self:isBountyGradeUnlock(grade)
    else
        return false
    end
end

-- 战令奖励可领取
function ActivityData:canGetBountyReward(level, grade)
    return self:isReachBountyReward(level, grade) and not self:isReceivedBountyReward(level, grade)
end

-- 战令奖励是否已领取
function ActivityData:isReceivedBountyReward(level, grade)
    local id = self:getBountyCfg()[level].id
    if self.actData == nil or self.actData.collected == nil or self.actData.collected[id] == nil then
        return false
    end

    if grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE then
        return self.actData.collected[id].normal
    elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
        return self.actData.collected[id].superior
    elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
        return self.actData.collected[id].superior_max
    end
end

-- 战令档位购买成功
function ActivityData:onBuyBountyGrade(giftId)
    local grade
    if giftId == GConst.ActivityConst.BOUNTY_GIFT_ID_1 then-- 解锁1档
        grade = GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1
    elseif giftId == GConst.ActivityConst.BOUNTY_GIFT_ID_2 then-- 解锁2档
        grade = GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2
    end

    ModuleManager.ActivityManager:reqSummerBountyReward(0, grade)-- 请求档位全部奖励

    self:setDirty()
end

-- 战令奖励领取成功
function ActivityData:onReceivedBountyReward(successMap)
    for id, grade in pairs(successMap) do
        if self.actData.collected[id] == nil then
            self.actData.collected[id] = {}
        end
    
        if grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.FREE then
            self.actData.collected[id].normal = true
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY1 then
            self.actData.collected[id].superior = true
        elseif grade == GConst.ActivityConst.BOUNTY_GRADE_TYPE.PAY2 then
            self.actData.collected[id].superior_max = true
        end
    end

    self:setDirty()
end

-- 解锁战令等级成功
function ActivityData:onBoughtBountyLevel()
    self.actData.level = self.actData.level + 1
    self:setDirty()
end

-- 礼包--------------------------------------------------------------------------------------------------

-- 标记礼包弹出状态
function ActivityData:markGiftPop()
    if DataManager.ShopData:getGiftRemainBuyNum(GConst.ActivityConst.SKIN_GIFT_ID_1) > 0 then
        DataManager.ShopData:markPopUpGift(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.ActivityConst.SKIN_GIFT_ID_1)
    elseif DataManager.ShopData:getGiftRemainBuyNum(GConst.ActivityConst.SKIN_GIFT_ID_2) > 0 then
        DataManager.ShopData:markPopUpGift(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.ActivityConst.SKIN_GIFT_ID_2)
    end
    if DataManager.ShopData:getGiftRemainBuyNum(GConst.ActivityConst.HERO_GIFT_ID_1) > 0 then
        DataManager.ShopData:markPopUpGift(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.ActivityConst.HERO_GIFT_ID_1)
    end
end

-- 皮肤礼包是否有红点
function ActivityData:hasSkinRedPoint()
    return not LocalData:getTodayActSummerWatchedSkin()
end

-- 英雄礼包是否有红点
function ActivityData:hasHeroRedPoint()
    return not LocalData:getTodayActSummerWatchedHero()
end

return ActivityData