local FourteenDayData = class("FourteenDayData", BaseData)

-- 新玩家开启
local OPEN_DAYS = 7
-- 活动持续时间
local ACTIVE_DAYS = 14

function FourteenDayData:ctor()
    self:clear()
end

function FourteenDayData:clear()
    DataManager:unregisterCrossDayFunc("FourteenDayData")
    DataManager:unregisterTryOpenFunc("FourteenDayData")
end

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

function FourteenDayData:init(data)
    data = data or GConst.EMPTY_TABLE

    if EDITOR_MODE then
        Logger.logHighlight("新手14天乐数据初始化")
        Logger.printTable(data)
    end
    self:initData(data)

    -- 活动开启
    DataManager:registerTryOpenFunc("FourteenDayData", function()
        if self:isOpen() then
            DataManager:unregisterTryOpenFunc("FourteenDayData")
            self:setDirty()
        end
    end)
    -- 跨天
    DataManager:registerCrossDayFunc("FourteenDayData", function()
        if not self:isOpen() then
            return
        end
        if not self:isActiveTime() then
            return
        end
        if not self.openStatus then
            self.needSyncTaskInfo = true
            EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.MAIN_UI_CHECK_SIDE_BAR)
        end
        self.openStatus = true

        -- Logger.logHighlight("14天乐跨天")

        self.activeDays = self.activeDays + 1
        self:setDirty()
    end)

    local endTime = self:getEndTime()
    local nowTime = Time:getServerTime()
    if endTime > nowTime then
        -- 注册任务进度监听
        for id, data in ipairs(self:getTaskCfg()) do
            if data.quest then
                ModuleManager.TaskManager:registerTask("FourteenDayData", data.quest, function(count)
                    self:addTaskProgress(data.quest, count)
                end)
            end
        end
    end

    self.openStatus = false
    if self:isOpen() and self:isActiveTime() then
        self.openStatus = true
    end
end

function FourteenDayData:initData(data)
    self.openTs = GFunc.formatTimeStep(data.open_at or 0)
    self.activeDays = data.active_days or 0-- 活动开启后的登陆天数、阶段数
    self.bountyStatus = data.funds
    self.tasksStatus = data.tasks
    self.exchangeStatus = data.exchange_info
end

function FourteenDayData:getOpenStatus()
    return self.openStatus
end

function FourteenDayData:getNeedSyncData()
    return self.needSyncTaskInfo
end

function FourteenDayData:setSyncData()
    self.needSyncTaskInfo = true
end

function FourteenDayData:isOpen()
    if GFunc.isShenhe() then
        return false
    end
    -- 开启条件同七天乐
    if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.SEVEN_DAY, true) then
        return false
    end

    return true
end

-- 是否在活动时间内
function FourteenDayData:isActiveTime()
    local openTime = self:getOpenTime()
    local endTime = self:getEndTime()
    local nowTime = Time:getServerTime()

    return nowTime >= openTime and nowTime < endTime
end

-- 获取开启时间
function FourteenDayData:getOpenTime()
    local result
    if self.openTs and self.openTs > 0 then
        result = self.openTs
    else
        local registerBeginTs = Time:getBeginningOfOneDay(DataManager:getRegisterTs())
        result = math.floor(registerBeginTs + (OPEN_DAYS - 1) * 24 * 60 * 60)
    end

    -- Logger.logHighlight("开始时间："..result)
    return result
end

-- 获取结束时间
function FourteenDayData:getEndTime()
    if self.endTs == nil or self.endTs <= 0 then
        self.endTs = math.floor(self:getOpenTime() + ACTIVE_DAYS * 24 * 60 * 60)
    end

    return self.endTs
end

-- 获取活动结束剩余时间（秒）
function FourteenDayData:getEndRemainTime()
    return self:getEndTime() - Time:getServerTime()
end

-- 获取活动开启时的活跃天数
function FourteenDayData:getActiveDays()
    return self.activeDays
end

-- 是否有红点
function FourteenDayData:hasRedPoint()
    if not self:isActiveTime() then
        return false
    end

    return self:hasBountyRedPoint() or self:hasTaskRedPoint() or self:hasExchangeRedPoint() or self:hasGiftRedPoint()
end

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

-- 是否有战令红点
function FourteenDayData:hasBountyRedPoint()
    for id, data in ipairs(self:getBountyCfg()) do
        if self:canGetBountyReward(id, GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.FREE) then
            return true
        end
        if self:canGetBountyReward(id, GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.PAY) then
            return true
        end
    end

    return false
end

-- 获取战令配置
function FourteenDayData:getBountyCfg()
    return ConfigManager:getConfig("act_fourteen_bounty")
end

-- 档位是否已解锁
function FourteenDayData:isBountyGradeUnlock(grade)
    if grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.PAY then
        return DataManager.ShopData:getGiftBoughtNum(PayManager.PURCHARSE_TYPE.ACT_GIFT, GConst.FourteenDayConst.BOUNTY_GIFT_ID) > 0
    else
        return true
    end
end

-- 获取战令档位奖励
function FourteenDayData:getBountyGradeReward(id, grade)
    local cfg = self:getBountyCfg()[id]
    local result
    if cfg ~= nil then
        if grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.FREE then
            result = cfg.reward
        elseif grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.PAY then
            result = cfg.reward_pro
        end
    end

    return result
end

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

-- 战令奖励是否满足领取条件
function FourteenDayData:isReachBountyReward(id, grade)
    if self:getActiveDays() >= id then
        return self:isBountyGradeUnlock(grade)
    else
        return false
    end
end

-- 战令奖励是否已领取
function FourteenDayData:isReceivedBountyReward(id, grade)
    if self.bountyStatus == nil or self.bountyStatus.free_awarded == nil or self.bountyStatus.pay_awarded == nil then
        return false
    end

    if grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.FREE then
        return table.containValue(self.bountyStatus.free_awarded, id)
    elseif grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.PAY then
        return table.containValue(self.bountyStatus.pay_awarded, id)
    end

    return false
end

-- 战令奖励领取成功
function FourteenDayData:onReceivedBountyReward(successMap)
    for index, data in ipairs(successMap) do
        if data.grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.FREE then
            table.insert(self.bountyStatus.free_awarded, data.id)
        elseif data.grade == GConst.FourteenDayConst.BOUNTY_GRADE_TYPE.PAY then
            table.insert(self.bountyStatus.pay_awarded, data.id)
        end
    end

    self:setDirty()
end

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

-- 是否有任务红点
function FourteenDayData:hasTaskRedPoint()
    local openDay = self:getActiveDays()
    for id, data in ipairs(self:getTaskCfg()) do
        if data.stage <= openDay then
            if self:canGetTaskReward(id) then
                return true
            end
        end
    end

    return false
end

-- 获取当前应该显示的阶段
function FourteenDayData:getTaskShowStage()
    for id, data in ipairs(self:getTaskCfg()) do
        if self:getActiveDays() >= data.stage and self:canGetTaskReward(id) then
            return data.stage
        end
    end

    local curStage = self:getActiveDays()
    local maxStage = self:getTaskMaxStage()
    if curStage > maxStage then
        curStage = maxStage
    end

    return curStage
end


-- 获取任务配置
function FourteenDayData:getTaskCfg()
    return ConfigManager:getConfig("act_fourteen_quest")
end

-- 获取任务id map结构
function FourteenDayData:getTaskMap()
    if self.taskMap == nil then
        self.taskMap = {}
        for id, data in ipairs(ConfigManager:getConfig("act_fourteen_quest")) do
            if self.taskMap[data.stage] == nil then
                self.taskMap[data.stage] = {}
            end

            if data.quest ~= nil then
                if self.taskMap[data.stage].task == nil then
                    self.taskMap[data.stage].task = {}
                end
                table.insert(self.taskMap[data.stage].task, id)
            else
                self.taskMap[data.stage].stage = id
            end
        end
    end

    return self.taskMap
end

-- 获取任务最大阶段值
function FourteenDayData:getTaskMaxStage()
    return #self:getTaskMap()
end

-- 获取阶段任务id
function FourteenDayData:getStageTaskId(stage)
    local taskMap = self:getTaskMap()

    return taskMap[stage] and taskMap[stage].stage or nil
end

-- 获取阶段子任务id列表
function FourteenDayData:getStageSubTaskIdsSort(stage)
    local taskMap = self:getTaskMap()
    local result = {}
    if taskMap[stage] == nil or taskMap[stage].task == nil then
        return result
    end

    local canGet = {}
    local unfinish = {}
    for index, id in ipairs(taskMap[stage].task) do
        if self:isTaskFinish(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 FourteenDayData:getTaskTarget(id)
    return self:getTaskCfg()[id].num
end

-- 获取任务类型
function FourteenDayData:getTaskType(id)
    return self:getTaskCfg()[id].quest
end

-- 获取任务阶段
function FourteenDayData:getTaskStage(id)
    return self:getTaskCfg()[id].stage
end

-- 获取任务奖励
function FourteenDayData:getTaskRewards(id)
    return self:getTaskCfg()[id].reward
end

-- 获取任务icon
function FourteenDayData:getTaskIcon(id)
    return self:getTaskCfg()[id].icon
end

-- 获取任务描述
function FourteenDayData:getTaskDesc(id)
    local taskType = self:getTaskType(id)
    if taskType == GConst.TaskConst.TASK_TYPE.X_ARENA_GRADING then
        local grading = DataManager.ArenaData:getGradingName(DataManager.ArenaData:getGradingIdFromScore(self:getTaskTarget(id)))
        return I18N:getText("task_type", taskType, "desc", grading)
    elseif taskType == GConst.TaskConst.TASK_TYPE.X_DUNGEON_ARMOR then
        local cfg = DataManager.DungeonData:getDungeonDataByType(ModuleManager.MODULE_KEY.DUNGEON_ARMOR):getConfig(id)
        return I18N:getText("task_type", taskType, "desc", cfg.chapter, cfg.stage)
    else
        return I18N:getText("task_type", taskType, "desc", self:getTaskTarget(id))
    end
end

-- 任务奖励是否可领取
function FourteenDayData:canGetTaskReward(id)
    return self:isTaskFinish(id) and not self:isReceivedTaskReward(id)
end

-- 任务是否完成
function FourteenDayData:isTaskFinish(id)
    if self:getTaskType(id) ~= nil then
        return self:getTaskProgress(id) >= self:getTaskTarget(id)
    else
        local ids = self:getStageSubTaskIdsSort(self:getTaskStage(id))

        local isFinish = true
        for idx, taskId in ipairs(ids) do
            if not self:isTaskFinish(taskId) then
                isFinish = false
                break
            end
        end

        return isFinish
    end
end

-- 任务奖励是否已领取
function FourteenDayData:isReceivedTaskReward(id)
    return self.tasksStatus[id] and self.tasksStatus[id].claimed or false
end

-- 获取任务进度
function FourteenDayData:getTaskProgress(id)
    if self:getTaskType(id) == GConst.TaskConst.TASK_TYPE.X_PLAYER_LV_REACH then
        -- 玩家等级实时处理
        return DataManager.PlayerData:getLv()
    end
    return self.tasksStatus[id] and self.tasksStatus[id].progress or 0
end

-- 添加任务进度
function FourteenDayData:addTaskProgress(taskType, count)
    -- Logger.logHighlight("任务进度改变："..tostring(taskType)..","..tostring(count))
    if not self:isOpen() then
        return
    end
    if not self:isActiveTime() then
        return
    end

    for id, data in ipairs(self:getTaskCfg()) do
        if data.quest == taskType then
            if self.tasksStatus[id] == nil then
                self.tasksStatus[id] = {}
                self.tasksStatus[id].progress = 0
            end
            self.tasksStatus[id].progress = self.tasksStatus[id].progress + count
        end
    end

	self:setDirty()
end

-- 任务奖励领取成功
function FourteenDayData:onReceivedTaskReward(id)
    if self.tasksStatus[id] == nil then
        self.tasksStatus[id] = {}
    end

    self.tasksStatus[id].claimed = true
    self:setDirty()
end

-- 兑换商店--------------------------------------------------------------------------------------------------------------

-- 是否有兑换红点
function FourteenDayData:hasExchangeRedPoint()
    return not self:getTodayExchangeCheck()
end

function FourteenDayData:getTodayExchangeCheck()
    if self.todayExchangeChecked == nil then
        self.todayExchangeChecked = LocalData:getTodayFourteenDayExchangeWatched()
    end
    return self.todayExchangeChecked
end

function FourteenDayData:setTodayExchangeCheck()
    if self.todayExchangeChecked then
        return
    else
        LocalData:recordTodayFourteenDayExchangeWatched()
    end
    self.todayExchangeChecked = true
    self:setDirty()
end

-- 获取拥有的兑换道具个数
function FourteenDayData:getExchangeItemNum()
    return DataManager.BagData.ItemData:getItemNumById(GConst.ItemConst.ITEM_ID_FOURTEEN_DAY_EXCHANGE)
end

-- 获取兑换配置
function FourteenDayData:getExchangeCfg()
    return ConfigManager:getConfig("act_fourteen_exchange")
end

-- 获取显示的id列表
function FourteenDayData:getExchangeShowIdsSort()
    local result = {}
    local ids = table.keys(self:getExchangeCfg())
    for index, id in ipairs(ids) do
        local sort = id + 10000000000

        if self:isExchangeUnlock(id) then
            sort = sort - 10000000
        end

        if self:getExchangeRemainTime(id) > 0 then
            sort = sort - 10000
        end
        table.insert(result, {id = id, sort = sort})
    end

    table.sort(result, function (a, b)
        return a.sort < b.sort
    end)

    return result
end

-- 获取兑换所需最小道具数
function FourteenDayData:getExchangeMinNum()
    local minExchange
    for index, data in ipairs(self:getExchangeShowIdsSort()) do
        local temp = self:getExchangeCostNum(data.id)
        if minExchange == nil or minExchange > temp then
            minExchange = temp
        end
    end

    return minExchange
end

-- 物品是否可以兑换
function FourteenDayData:canExchange(id)
    return self:isExchangeUnlock(id) and self:getExchangeRemainTime(id) > 0 and self:getExchangeItemNum() >= self:getExchangeCostNum(id)
end

-- 兑换物品是否解锁
function FourteenDayData:isExchangeUnlock(id)
    return self:getActiveDays() >= self:getExchangeUnlockCondition(id)
end

-- 兑换物品的解锁条件
function FourteenDayData:getExchangeUnlockCondition(id)
    return self:getExchangeCfg()[id].stage
end

-- 兑换物品剩余兑换次数
function FourteenDayData:getExchangeRemainTime(id)
    return self:getExchangeCfg()[id].limit - (self.exchangeStatus[id] or 0)
end

-- 获取兑换的消耗道具个数
function FourteenDayData:getExchangeCostNum(id)
    return GFunc.getRewardNum(self:getExchangeCfg()[id].cost)
end

function FourteenDayData:getExchangeCost(id)
    return self:getExchangeCfg()[id].cost
end

-- 获取兑换的奖励道具
function FourteenDayData:getExchangeReward(id)
    return self:getExchangeCfg()[id].reward
end

-- 兑换奖励领取成功
function FourteenDayData:onReceivedExchangeReward(id, count)
    count = count or 1
    if self.exchangeStatus[id] == nil then
        self.exchangeStatus[id] = 0
    end

    self.exchangeStatus[id] = self.exchangeStatus[id] + count
    self:setDirty()
end

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

-- 是否有礼包红点
function FourteenDayData:hasGiftRedPoint()
    local gifts = DataManager.ShopData:getGiftsByType(PayManager.PURCHARSE_ACT_TYPE.FOURTEEN_DAY_GIFT)
    for id, data in pairs(gifts) do
        if data.recharge_id == nil and self:getGiftRemainTime(id) > 0 then
            return true
        end
    end

    return false
end

-- 是否是免费礼包
function FourteenDayData:isFreeGift(id)
    return DataManager.ShopData:getActGiftConfig()[id].recharge_id == nil
end

-- 获取礼包id列表
function FourteenDayData:getGiftIdsSort()
    local gifts = DataManager.ShopData:getGiftsByType(PayManager.PURCHARSE_ACT_TYPE.FOURTEEN_DAY_GIFT)

    local result = {}
    local ids = table.keys(gifts)
    for index, id in ipairs(ids) do
        local sort = id + 10000000000

        if self:isFreeGift(id) then
            sort = sort - 10000000
        end

        if self:getGiftRemainTime(id) > 0 then
            sort = sort - 10000
        end
        table.insert(result, {id = id, sort = sort})
    end

    table.sort(result, function (a, b)
        return a.sort < b.sort
    end)

    return result
end

-- 礼包剩余购买次数
function FourteenDayData:getGiftRemainTime(giftId)
    if self:isFreeGift(giftId) then
        local giftData = DataManager.ShopData:getActGiftDetailData(PayManager.PURCHARSE_TYPE.ACT_GIFT, giftId)
        if giftData and giftData.buy_count > 0 and giftData.latest_buy_at then
            if Time:getBeginningOfOneDay(Time:getServerTime()) == Time:getBeginningOfOneDay(giftData.latest_buy_at // 1000) then
                return 0
            end
        end
        return 1
    else
        return DataManager.ShopData:getGiftRemainBuyNum(giftId)
    end
end

return FourteenDayData