local DailyTaskData = class("DailyTaskData", BaseData)

local DAILY_TASK_AD_ID = 1
local DAILY_TASK_FINAL_ID = 2
local DATA_NAME = "DailyTaskData"

function DailyTaskData:ctor()
	self.data.dailyTaskDirty = false
	self.data.resetFlag = false
	self.data.redPointFlag = false
	self.dailyTaskRedPoint = 0
	self.challengeTaskRedPoint = 0
	self.isInReset = false
	self.taskTypeMap = {}
	self.dailyTasks = {}
	self.isUnlockBountyDailyTask = false
end

function DailyTaskData:init(data)
	local tasks = data and data.tasks
	local cfg = self:getDailyTaskCfg()
	local taskCfg = self:getTaskCfg()
	for k, v in pairs(self.dailyTasks) do
		self.dailyTasks[k] = nil
	end
	for k, v in pairs(self.taskTypeMap) do
		for i = 1, #v do
			table.remove(v)
		end
	end
	self.isUnlockBountyDailyTask = DataManager.BountyData:getBought()
	local dailyRedPoint = 0
	local challengeRedPoint = 0
	ModuleManager.TaskManager:unRegisterAllModuleTask(DATA_NAME)
	for k, v in pairs(cfg) do
		local task = tasks and tasks[k] or GConst.EMPTY_TABLE
		local taskInfo = taskCfg[task.task_id]
		if taskInfo then
			local dailyTaskObj = {
				id = k,
				taskId = task.task_id,
				progress = task.progress,
				needProgress = taskInfo.number,
				refresh = task.refresh,
				claimed = task.claimed,
				type = v.type,
				reset = v.reset
			}
			if v.bounty then
				if self.isUnlockBountyDailyTask then
				   dailyTaskObj.lock = false
			   else
				   dailyTaskObj.lock = true
			   end
			else
				dailyTaskObj.lock = false
			end
			if dailyTaskObj.lock then
				dailyTaskObj.redPoint = false
			else
				if not dailyTaskObj.claimed and dailyTaskObj.progress >= dailyTaskObj.needProgress then
					dailyTaskObj.redPoint = true
					if dailyTaskObj.type == 1 then
						dailyRedPoint = dailyRedPoint + 1
					else
						challengeRedPoint = challengeRedPoint + 1
					end
				else
					dailyTaskObj.redPoint = false
				end
				local list = self.taskTypeMap[taskInfo.type]
				if list == nil  then
					list = {}
					self.taskTypeMap[taskInfo.type] = list
				end
				table.insert(list, dailyTaskObj)
				if #list == 1 then
					self:registerTaskWithType(taskInfo.type)
				end
			end
			self.dailyTasks[k] = dailyTaskObj
		end
	end
	self.initDay = Time:getBeginningOfServerToday()
	self.isInReset = false
	self.data.resetFlag = not self.data.resetFlag

	local redPointDirty = false
	if self.dailyTaskRedPoint ~= dailyRedPoint then
		if self.dailyTaskRedPoint > 0 and dailyRedPoint > 0 then
			self.dailyTaskRedPoint = dailyRedPoint
		else
			self.dailyTaskRedPoint = dailyRedPoint
			redPointDirty = true
		end
	end
	if self.challengeTaskRedPoint ~= challengeRedPoint then
		if self.challengeTaskRedPoint > 0 and challengeRedPoint > 0 then
			self.challengeTaskRedPoint = challengeRedPoint
		else
			self.challengeTaskRedPoint = challengeRedPoint
			redPointDirty = true
		end
	end
	if redPointDirty then
		self.data.redPointFlag = not self.data.redPointFlag
	end
end

function DailyTaskData:refreshDailyTask(task)
	local id = task.id
	local dailyTaskObj = self.dailyTasks[id]
	if dailyTaskObj == nil then
		return
	end
	local taskInfo = self:getTaskCfg()[task.task_id]
	if taskInfo == nil then
		return
	end
	local originTaskInfo = self:getTaskCfg()[dailyTaskObj.taskId]
	if originTaskInfo == nil then
		return
	end
	local dailyTaskInfo = self:getDailyTaskCfg()[id]
	if dailyTaskInfo == nil then
		return
	end
	dailyTaskObj.id = task.id
	dailyTaskObj.taskId = task.task_id
	dailyTaskObj.progress = task.progress
	dailyTaskObj.needProgress = taskInfo.number
	dailyTaskObj.refresh = task.refresh
	dailyTaskObj.claimed = task.claimed
	dailyTaskObj.type = dailyTaskInfo.type
	dailyTaskObj.reset = dailyTaskInfo.reset
	local redPoint = false
	if not dailyTaskObj.lock and not dailyTaskObj.claimed and dailyTaskObj.progress >= dailyTaskObj.needProgress then
		redPoint = true
	end
	local originTaskType = originTaskInfo.type
	if not dailyTaskObj.lock and originTaskType ~= taskInfo.type then -- 任务类型变了
		self:unregisterTask(id, originTaskType)
		self:registerTask(dailyTaskObj, taskInfo.type)
	end
	self:markDailyTaskDirty()

	if dailyTaskObj.redPoint ~= redPoint then
		dailyTaskObj.redPoint = redPoint
		if redPoint then
			if dailyTaskObj.type == 1 then
				self.dailyTaskRedPoint = self.dailyTaskRedPoint + 1
			else
				self.challengeTaskRedPoint = self.challengeTaskRedPoint + 1
			end
			if self.dailyTaskRedPoint + self.challengeTaskRedPoint == 1 then
				self.data.redPointFlag = not self.data.redPointFlag
			end
		else
			if dailyTaskObj.type == 1 then
				self.dailyTaskRedPoint = self.dailyTaskRedPoint - 1
			else
				self.challengeTaskRedPoint = self.challengeTaskRedPoint - 1
			end
			if self.dailyTaskRedPoint + self.challengeTaskRedPoint == 0 then
				self.data.redPointFlag = not self.data.redPointFlag
			end
		end
	end
end

function DailyTaskData:getIsOpen()
	return ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.TASK, true)
end

function DailyTaskData:getDailyResetTime()
	return 86400 - Time:getServerTime() % 86400
end

function DailyTaskData:getDailyTaskAdReward()
	local task = self.dailyTasks[DAILY_TASK_AD_ID]
	if task == nil then
		return nil
	end
	local cfg = self:getTaskCfg()
	return cfg[task.taskId].reward
end

function DailyTaskData:getDailyTaskAdId()
	return DAILY_TASK_AD_ID
end

function DailyTaskData:getDailyTaskFinalReward()
	local task = self.dailyTasks[DAILY_TASK_FINAL_ID]
	if task == nil then
		return nil
	end
	local cfg = self:getTaskCfg()
	return cfg[task.taskId].reward
end

function DailyTaskData:getDailyTaskFinalId()
	return DAILY_TASK_FINAL_ID
end

function DailyTaskData:markDailyTaskDirty()
	self.data.dailyTaskDirty = not self.data.dailyTaskDirty
end

function DailyTaskData:getDailyTaskProgress(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return 0, 1
	end
	return task.progress, task.needProgress
end

function DailyTaskData:getDailyTaskDesc(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return GConst.EMPTY_STRING
	end
	local cfg = self:getTaskI18NCfg()
	return cfg[task.taskId].desc
end

function DailyTaskData:getDailyTaskIsLock(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return nil
	end
	return task.lock
end

function DailyTaskData:getDailyTaskCanRefresh(id)
	local cfg = self:getDailyTaskCfg()[id]
	if cfg == nil then
		return false
	end
	return cfg.ad_refresh
end

function DailyTaskData:getDailyTaskIsAdType(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return false
	end
	local cfg = self:getTaskCfg()
	return cfg[task.taskId].type == GConst.TaskConst.TASK_TYPE.DAILY_TASK_WATCH_AD_SPECIAL
end

function DailyTaskData:getDailyTaskCanClaimTask(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return false
	end
	return self:getIfCanClaimTask(task)
end

function DailyTaskData:getDailyTaskIcon(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return GConst.EMPTY_STRING
	end
	local cfg = self:getTaskCfg()
	return cfg[task.taskId].icon
end

function DailyTaskData:getDailyTaskReward(id)
	local task = self.dailyTasks[id]
	if task == nil then
		return GConst.EMPTY_STRING
	end
	local cfg = self:getTaskCfg()
	return cfg[task.taskId].reward
end

function DailyTaskData:getDailyTasks()
	return self.dailyTasks
end

function DailyTaskData:getTaskI18NCfg()
	return I18N:getConfig("task")
end

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

function DailyTaskData:getDailyTaskCfg()
	if self.dailyTaskCfg == nil then
		self.dailyTaskCfg = ConfigManager:getConfig("task_daily")
	end
	return self.dailyTaskCfg
end

function DailyTaskData:getTaskListByType(taskType)
    return self.taskTypeMap[taskType] or GConst.EMPTY_TABLE
end

function DailyTaskData:getDailyTaskCalaimed(id)
	local task = self.dailyTasks[id]
	if not task then
		return false
	end
	return task.claimed
end

function DailyTaskData:getIfCanClaimTask(task)
    if task.claimed then
        return false
    end
    return task.progress >= task.needProgress
end

function DailyTaskData:addTaskProgress(task, taskType, count)
	if task.lock then
		return
	end
	local currProgress = task.progress
	if currProgress >= task.needProgress then
		return
	end
	local can = self:getIfCanClaimTask(task)
	task.progress = task.progress + count
    if not can and self:getIfCanClaimTask(task) then
		EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.DAILY_TASK_COMPLETE, task.id, task.taskId, currProgress, task.needProgress)
		if task.type == 1 and task.reset == 1 and taskType ~= GConst.TaskConst.TASK_TYPE.COMPLETED_DALY_TASK then
			ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.COMPLETED_DALY_TASK)
		end
        BIReport:postDailyTaskFinish(BIReport.TASK_TYPE.DAILY,  task.id, task.taskId, task.refresh)
		task.redPoint = true
		if task.type == 1 then
			self.dailyTaskRedPoint = self.dailyTaskRedPoint + 1
		else
			self.challengeTaskRedPoint = self.challengeTaskRedPoint + 1
		end
		if self.dailyTaskRedPoint + self.challengeTaskRedPoint == 1 then
			self.data.redPointFlag = not self.data.redPointFlag
		end
    end
	self:markDailyTaskDirty()
end

function DailyTaskData:registerTaskWithType(taskType)
	ModuleManager.TaskManager:registerTask(DATA_NAME, taskType, function(count)
        local list = self:getTaskListByType(taskType)
		if #list > 0 then
			for _, task in ipairs(list) do
				self:addTaskProgress(task, taskType, count)
			end
		end
    end)
end

function DailyTaskData:unregisterTask(id, taskType)
	local taskList = self.taskTypeMap[taskType]
	if taskList then
		for k, v in ipairs(taskList) do
			if v.id == id then
				table.remove(taskList, k)
				break
			end
		end
		if #taskList == 0 then
			self:unregisterTaskWithType(taskType)
		end
	end
end

function DailyTaskData:unregisterTaskWithType(taskType)
	ModuleManager.TaskManager:unRegisterTask(DATA_NAME, taskType)
end

function DailyTaskData:registerTask(dailyTaskObj, taskType)
	local taskList = self.taskTypeMap[taskType]
	if taskList == nil  then
		taskList = {}
		self.taskTypeMap[taskType] = taskList
	end
	table.insert(taskList, dailyTaskObj)
	if #taskList == 1 then
		self:registerTaskWithType(taskType)
	end
end

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

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

function DailyTaskData:getIsInReset()
	return self.isInReset
end

function DailyTaskData:getIsShowRedPoint()
	return self.dailyTaskRedPoint > 0 or self.challengeTaskRedPoint > 0
end

function DailyTaskData:getIsShowDailyTaskRedPoint()
	return self.dailyTaskRedPoint > 0
end

function DailyTaskData:getIsShowChallengeTaskRedPoint()
	return self.challengeTaskRedPoint > 0
end

function DailyTaskData:unlockBountyTask()
	if self.isUnlockBountyDailyTask then
		return
	end
	self.isUnlockBountyDailyTask = true
	local dirty = false
	local taskCfg = self:getTaskCfg()
	for k, v in pairs(self.dailyTasks) do
		if v.lock then -- 有锁的要解锁
			v.lock = false
			dirty = true
			self:registerTask(v, taskCfg[v.taskId].type)
		end
	end
	if dirty then
		self:markDailyTaskDirty()
	end
end

return DailyTaskData