local ChapterData = class("ChapterData", BaseData)

ChapterData.MIN_CHAPTER_ID = 1
local MIN_CHAPTER_ID = ChapterData.MIN_CHAPTER_ID

function ChapterData:ctor()
	self.data.chapterId = MIN_CHAPTER_ID
	self.data.maxChapterId = 0
	self.data.isDirty = false
end

function ChapterData:clear()
	self.data.chapterId = MIN_CHAPTER_ID
	self.data.maxChapterId = 0
	self.trailHeroId = nil
	self.trailChapterId = nil
	self.trailAtkInfo = nil
end

function ChapterData:init(data, notChangeChapterId)
	if not data then
		return
	end

	local cfg = self:getChapterCfg()[data.max_chapter_id]
	if not cfg then
		local maxChapterId = 0
		for id, info in pairs(self:getChapterCfg()) do
			if maxChapterId < id then
				maxChapterId = id
			end
		end
		data.max_chapter_id = maxChapterId
		data.max_wave = self:getChapterCfgMaxWave(data.max_chapter_id)
	end

	self.maxWave = data.max_wave or 0
	if self.maxWave >= self:getChapterCfgMaxWave(data.max_chapter_id) then
		self.data.maxChapterId = data.max_chapter_id
	else
		self.data.maxChapterId = data.max_chapter_id - 1
	end

	if not notChangeChapterId then
		self.data.chapterId = data.max_chapter_id
	end

	self.data.chapterInfo = data.chapter_info or {}
end

function ChapterData:getIsFirstChapter(chapterId)
	return chapterId == MIN_CHAPTER_ID
end

function ChapterData:getIsFinalChapter(chapterId)
	local chapterInfo = self:getChapterCfg()[chapterId]
	if chapterInfo == nil then
		return false
	end
	local chapterId = chapterInfo.next_chapter
	if chapterId == nil then
		return true
	end
	return false
end

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

function ChapterData:getChapterId()
	return self.data.chapterId
end

function ChapterData:setChapterId(chapterId)
	self.data.chapterId = chapterId
end

function ChapterData:getNextChapter(chapterId)
	local chapterInfo = self:getChapterCfg()[chapterId]
	if chapterInfo == nil then
		return 1
	end
	if chapterInfo.next_chapter == nil then
		return chapterId
	end
	return chapterInfo.next_chapter
end

function ChapterData:getNewChapterId()
	return self:getNextChapter(self:getMaxChapterId())
end

function ChapterData:isFinalChapter(chapterId)
	local chapterInfo = self:getChapterCfg()[chapterId]
	if chapterInfo == nil then
		return true
	end
	return chapterInfo.next_chapter == nil
end

function ChapterData:goNextChapter()
	local chapterId = self:getNextChapter(self.data.chapterId)
	if self.data.chapterId == chapterId then
		return false
	else
		self.data.chapterId = chapterId
	end
	return true
end

function ChapterData:goLastChapter()
	local chapterInfo = self:getChapterCfg()[self.data.chapterId]
	if chapterInfo == nil then
		return false
	end
	local chapterId = chapterInfo.before_chapter
	if chapterId == nil then
		return false
	end
	self.data.chapterId = chapterId
	return true
end

function ChapterData:getChapterCfg()
	if self.chapterCfg == nil then
		self.chapterCfg = ConfigManager:getConfig("chapter")
	end
	return self.chapterCfg
end

function ChapterData:getChapterBoxCount(chapterId)
	chapterId = chapterId or self:getChapterId()
	local cfg = self:getChapterCfg()[chapterId]
	if cfg and cfg.box_num then
		return #cfg.box_num
	end

	return 1
end

function ChapterData:getChapterBoxNum(chapterId, index)
	chapterId = chapterId or self:getChapterId()
	local cfg = self:getChapterCfg()[chapterId]
	if cfg and cfg.box_num then
		return cfg.box_num[index] or 1
	end

	return 1
end

function ChapterData:getChapterBoxRewardGot(chapterId, index)
	chapterId = chapterId or self:getChapterId()
	local info = self.data.chapterInfo[chapterId]
	if not info or not info.index then
		return false
	end

	for _, idx in ipairs(info.index) do
		if idx == index then
			return true
		end
	end

	return false
end

function ChapterData:boxCanGet(chapterId, index)
	if self:getChapterBoxRewardGot(chapterId, index) then
		return false
	end
	local needWave = DataManager.ChapterData:getChapterBoxNum(chapterId, index)
	local curMaxWave = DataManager.ChapterData:getChapterMaxWave(chapterId)
	return needWave <= curMaxWave
end

function ChapterData:getChapterBoxRewards(chapterId, index)
	chapterId = chapterId or self:getChapterId()
	if not self:getChapterBoxNum(chapterId, index) then
		return
	end

	local cfg = self:getChapterCfg()[chapterId]
	if cfg then
		return cfg["box_reward_" .. index]
	end
end

function ChapterData:getChapterMaxWave(chapterId)
	chapterId = chapterId or self:getChapterId()
	if chapterId <= self.data.maxChapterId then
		return self:getChapterCfgMaxWave(chapterId)
	else
		return self.maxWave
	end
end

function ChapterData:getChapterCfgMaxWave(chapterId)
	if not self.chapterCfgMaxWaveMap then
		self.chapterCfgMaxWaveMap = {}
	end
	if not self.chapterCfgMaxWaveMap[chapterId] then
		local chapterInfo = self:getChapterCfg()[chapterId]
		if not chapterInfo then
			self.chapterCfgMaxWaveMap[chapterId] = 1
		else
			self.chapterCfgMaxWaveMap[chapterId] = #chapterInfo.monster
		end
	end

	return self.chapterCfgMaxWaveMap[chapterId]
end

function ChapterData:getChapterFightCount(chapterId)
	chapterId = chapterId or self:getChapterId()
	if self.data.chapterInfo[chapterId] then
		return self.data.chapterInfo[chapterId].total_count or 0
	end

	return 0
end

function ChapterData:getFightCost()
	return GFunc.getConstReward("chapter_cost")
end

function ChapterData:getMaxChapterId()
	return self.data.maxChapterId
end

-- 得到有奖励的最小章节，如果没有，就是当前章节
function ChapterData:getIsHaveRewardsMinId()
	local chapterBefore = MIN_CHAPTER_ID
	local chapterCfg = self:getChapterCfg()
	local chapterInfo = chapterCfg[chapterBefore]
	while true do
		if self:getIsHaveRewards(chapterBefore) then
			break
		end

		if chapterBefore == self.data.maxChapterId then
			chapterBefore = self:getNextChapter(self.data.maxChapterId)
			break
		end

		chapterBefore = chapterInfo.next_chapter
		if chapterBefore == nil then
			break
		end

		chapterInfo = chapterCfg[chapterBefore]
		if chapterInfo == nil then
			break
		end
	end

	if not chapterBefore then
		chapterBefore = self:getNextChapter(self.data.maxChapterId)
	end

	return chapterBefore
end

-- 此章节是否有可领但是未领取的奖励
function ChapterData:getIsHaveRewards(chapterId)
	if chapterId > self.data.maxChapterId + 1 then
		return false
	end
	local info = self.data.chapterInfo[chapterId]
	if not info or not info.index then
		return false
	end

	local count = self:getChapterBoxCount(chapterId)
	if info.index and #info.index == count then -- 数量一致说明都领完了
		return false
	elseif chapterId < self.data.maxChapterId then
		return true
	end
	local curMaxWave = self:getChapterMaxWave(chapterId)
	for i = 1, count do
		local needWave = self:getChapterBoxNum(chapterId, i)
		local rewardGot = self:getChapterBoxRewardGot(chapterId, i)
		if needWave <= curMaxWave and not rewardGot then -- 有可以领但是没有领的奖励
			return true
		end
	end
	return false
end

function ChapterData:getChapterPassed(chapterId)
	chapterId = chapterId or self:getChapterId()
	if chapterId <= self.data.maxChapterId then
		return true
	else
		return self.maxWave >= self:getChapterCfgMaxWave(chapterId)
	end
end

function ChapterData:openBox(chapterId, index)
	if not self.data.chapterInfo[chapterId] then
		self.data.chapterInfo[chapterId] = {
			total_count = 0,
			index = {},
			mystery_box_idx = {}
		}
	end
	for _, idx in ipairs(self.data.chapterInfo[chapterId].index) do
		if idx == index then
			return
		end
	end

	table.insert(self.data.chapterInfo[chapterId].index, index)

	self:setDirty()
end

function ChapterData:fightChapter(chapterId, maxChapterId, maxWave, mysteryBoxIdx)
	if not self.data.chapterInfo[chapterId] then
		self.data.chapterInfo[chapterId] = {
			total_count = 0,
			index = {},
			mystery_box_idx = {}
		}
	end
	self.data.chapterInfo[chapterId].total_count = (self.data.chapterInfo[chapterId].total_count or 0) + 1

	if maxChapterId <= self.data.maxChapterId then
		return
	end

	self.data.chapterId = maxChapterId
	self.maxWave = maxWave
	if self.maxWave >= self:getChapterCfgMaxWave(maxChapterId) then
		self.data.maxChapterId = maxChapterId
	else
		self.data.maxChapterId = maxChapterId - 1
	end

	for _, idx in ipairs(mysteryBoxIdx) do
		if not self:getChapterMysteryBoxIsGot(chapterId, idx) then
			table.insert(self.data.chapterInfo[chapterId].mystery_box_idx, idx)
		end
	end

	self:setDirty()
end

function ChapterData:getChapterMysteryBoxReward(chapterId)
	local cfg = self:getChapterCfg()[chapterId]
	if not cfg then
		return
	end
	return cfg.mystery_box_reward
end

function ChapterData:getChapterMysteryBoxRewardCount(chapterId)
	local cfg = self:getChapterCfg()[chapterId]
	if not cfg then
		return 0
	end
	if cfg.mystery_box_reward then
		return #cfg.mystery_box_reward
	else
		return 0
	end
end

function ChapterData:getChapterMysteryBoxIsGot(chapterId, index)
	if not self.data.chapterInfo[chapterId] then
		return false
	end
	if not self.data.chapterInfo[chapterId].mystery_box_idx then
		return false
	end
	for _, idx in ipairs(self.data.chapterInfo[chapterId].mystery_box_idx) do
		if idx == index then
			return true
		end
	end
	return false
end

function ChapterData:getGoldDrop()
	local info = self:getChapterCfg()[self:getMaxChapterId()]
	if info == nil then
		return 0
	end
	return info.idle_gold
end

function ChapterData:getExpDrop()
	local info = self:getChapterCfg()[self:getMaxChapterId()]
	if info == nil then
		return 0
	end
	return info.idle_exp
end

function ChapterData:getChapterMysteryBoxGotCount(chapterId)
	if not self.data.chapterInfo[chapterId] then
		return 0
	end
	if not self.data.chapterInfo[chapterId].mystery_box_idx then
		return 0
	end
	return #self.data.chapterInfo[chapterId].mystery_box_idx
end

function ChapterData:getNeedShowTouchCancelTips()
	if not self.linkTouchCancelCount then
		self.linkTouchCancelCount = LocalData:getLinkTouchCancelCount()
		self.linkTouchCancelHideCount = GFunc.getConstIntValue("canle_link_hide")
	end

	if self.linkTouchCancelCount >= self.linkTouchCancelHideCount then
		return false
	end

	if not self.showTouchCancelChapter then
		self.showTouchCancelChapter = GFunc.getConstIntValue("cancle_link_show")
	end
	return self:getChapterPassed(self.showTouchCancelChapter)
end

function ChapterData:addLinkTouchCancelCount()
	self:getNeedShowTouchCancelTips()
	local newCount = self.linkTouchCancelHideCount + 1
	if self.linkTouchCancelCount < self.linkTouchCancelHideCount and newCount >= self.linkTouchCancelHideCount then
		LocalData:setLinkTouchCancelCount(newCount)
	end
	self.linkTouchCancelCount = newCount
end

function ChapterData:cacheTrailHeroIdAndChapterId(heroId, chapterId)
	if self.markTrailHeroTag == nil then
		self.markTrailHeroTag = LocalData:GetMarktrailHero() == 1
	end
	if self.markTrailHeroTag then
		self.trailHeroId = nil
		self.trailChapterId = nil
		return
	end

	local heroEntity = DataManager.HeroData:getHeroById(heroId)
	if not heroEntity or heroEntity:isActived() then -- 不存在或者已经激活
		self.trailHeroId = nil
		self.trailChapterId = nil
		return
	end
	self.trailHeroId = heroId
	self.trailChapterId = chapterId
end

function ChapterData:MarkTrailHero()
	self.markTrailHeroTag = true
	LocalData:MarkTrailHero()
end

function ChapterData:getCacheTrialHeroIdAndChapterId()
	local heroEntity = DataManager.HeroData:getHeroById(self.trailHeroId)
	if not heroEntity or heroEntity:isActived() then -- 不存在或者已经激活
		self.trailHeroId = nil
		self.trailChapterId = nil
	end
	return self.trailHeroId, self.trailChapterId
end

function ChapterData:cacheTrailAtkInfo(atkInfo)
	self.trailAtkInfo = atkInfo
end

function ChapterData:getCacheTrailAtkInfo()
	return self.trailAtkInfo
end

return ChapterData