local PlayerData = class("PlayerData", BaseData)
local RECHARGE_CFG = ConfigManager:getConfig("recharge")

function PlayerData:ctor()
	self.data.dirty = false
end

function PlayerData:clear()
    DataManager:unregisterCrossDayFunc("PlayerData")
end

function PlayerData:init(data)
	local basicInfo = data.basic_info or GConst.EMPTY_TABLE
	local stat = data.stat or GConst.EMPTY_TABLE
	self.data.level = basicInfo.level or 1
	self.data.exp = basicInfo.exp or 0
	self.lvUpNeedExp = self:getNextExp(self.data.level)
	self.data.payAmount =  0
	self.data.payCount = 0
	self.data.adCount = stat.ad_count or 0
	self.pay_counts = stat.pay_counts or {}
	self.register_ts = GFunc.formatTimeStep(stat.register_ts or Time:getServerTime())
	if stat.pay_counts then
		for id, count in pairs(stat.pay_counts) do
			if RECHARGE_CFG[id] then
				self.data.payAmount = self.data.payAmount + (RECHARGE_CFG[id].price or 0) * count
				self.data.payCount = self.data.payCount + count
			end
		end
	end
	if stat.internal ~= nil then
		self.internal = stat.internal
	end
	if data.game_version then
		self.game_version = data.game_version
	end

	if self.data.playInfo == nil then
		self.data.playInfo = {}
	end
    self.data.playInfo.nickName = basicInfo.name
	self.data.playInfo.nameChanged = basicInfo.name_changed
    self.data.playInfo.usingAvatarId = basicInfo.avatar
    self.data.playInfo.usingFrameId = basicInfo.avatar_frame
	self.data.playInfo.unlockAvatar = data.bag.avatars
    self.data.playInfo.unlockFrame = data.bag.avatar_frames
	if EDITOR_MODE then
		Logger.printTable(self.data.playInfo)
	end

	-- 体力购买情况初始化
	local energyLimit = data.energy_limit or GConst.EMPTY_TABLE
	self.data.vitGemCount = energyLimit.diamond_count or 0
	self.data.vitADCount = energyLimit.ad_count or 0

	self.lastLoginTime = basicInfo.lastLoginTime or Time:getBeginningOfServerToday()
	DataManager:registerCrossDayFunc("PlayerData", function()
		self:resetOnCrossDay()
		self:markDirty()
    end)
	self.createTime = basicInfo.create_at or 0 -- 创角时间

	local time = data.now_ts or 0
	if math.abs(self.createTime - time) <= 3000 then -- 认为是新号初次登录
		local vit = self:getMaxVit()
		BIReport:postVitGet(vit, BIReport.ITEM_GET_TYPE.NEW_PLAYER_INITIAL, vit)
	end
	self:initModuleUnlockInfo()
end

-- 竞技场入场券购买情况初始化
function PlayerData:initArena(gemCount, adCount)
	self.data.arenaTicketGemCount = gemCount or 0
	self.data.arenaTicketADCount = adCount or 0
end

function PlayerData:initModuleUnlockInfo()
	self.showModuleUnlockChapter = 0
	if self.moduleUnlockChapterMap then
		return
	end
	self.moduleUnlockChapterMap = {}
	local cfg = ConfigManager:getConfig("func_open")
	for _, info in pairs(cfg) do
		if info.pop_ups == nil and info.stage then
			self.moduleUnlockChapterMap[info.stage] = true
		end
	end
	Logger.printTable(self.moduleUnlockChapterMap)
end

function PlayerData:resetOnCrossDay()
	self.data.vitGemCount = 0
	self.data.vitADCount = 0
	self.data.arenaTicketGemCount = 0
	self.data.arenaTicketADCount = 0
end

function PlayerData:markDirty()
	self.data.dirty = not self.data.dirty
end

function PlayerData:setVit(vit)
	self.vit = vit
end

function PlayerData:getVit()
	return self.vit or 0
end

function PlayerData:getMaxVit()
	if self.maxVit == nil then
		self.maxVit = ConfigManager:getConfig("recovery")[GConst.ItemConst.ITEM_ID_VIT].limit
	end
	return self.maxVit
end

function PlayerData:getMaxLv()
	return ConfigManager:getConfigNum("player_exp")
end

function PlayerData:addExp(exp)
	self.data.exp = self.data.exp + exp
	if self.data.level >= self:getMaxLv() then
		return
	end
	self:markDirty()
end

function PlayerData:setLv(level, exp)
	local beforeLv = self.data.level or 0
	self.data.level = level
	self.data.exp = exp
	self.lvUpNeedExp = self:getNextExp(self.data.level)
	self:markDirty()

	local data = {}
	data.player_level = self.data.level
	CS.ThinkingAnalytics.ThinkingAnalyticsAPI.UserSet(data)
	BIReport:postLvEvent(beforeLv, level)
end

function PlayerData:getLv()
	return self.data.level
end

function PlayerData:getNextExp(lv)
	lv = lv or self.data.level
	local cfg = ConfigManager:getConfig("player_exp")
	if not cfg[lv] then
		return 1
	end
	return cfg[lv].need_exp
end

function PlayerData:getExpPercent()
	return self.data.exp / self.lvUpNeedExp
end

function PlayerData:getIfCanLevelUp()
	if self.data.level >= self:getMaxLv() then
		return false
	end
	return self.data.exp >= self.lvUpNeedExp
end

function PlayerData:getAccountInfo()
	if not self.accountInfo then
		self.accountInfo = LocalData:getAccountInfo()
	end
	return self.accountInfo
end

function PlayerData:getAcountId()
	return self:getAccountInfo().id or GConst.EMPTY_STRING
end

function PlayerData:addVitGemBuyCount()
	self.data.vitGemCount = self.data.vitGemCount + 1
end

function PlayerData:addVitAdBuyCount()
	self.data.vitADCount = self.data.vitADCount + 1
end

function PlayerData:getVitGemBuyCount()
	return self.data.vitGemCount
end

function PlayerData:getVitAdBuyCount()
	return self.data.vitADCount
end

-- 获取玩家支付总额
function PlayerData:getTotalPayAmount()
	return self.data.payAmount or 0
end

-- 支付回调中调用
function PlayerData:addPayment(rechargeId)
	local cfg = ConfigManager:getConfig("recharge")[rechargeId]
	self.data.payAmount = self.data.payAmount + cfg.price
	self.data.payCount = self.data.payCount + 1
	self.pay_counts[rechargeId] = (self.pay_counts[rechargeId] or 0) + 1
	ModuleManager.TaskManager:addTaskProgress(GConst.TaskConst.TASK_TYPE.X_BUY_ANYONE)
end

function PlayerData:getPayCount()
	return self.data.payCount
end

function PlayerData:getPayCounts(rechargeId)
	return self.pay_counts[rechargeId] or 0
end

function PlayerData:addPayCount()
	self.data.payCount = self.data.payCount + 1
end

function PlayerData:getAdCount()
	return self.data.adCount
end

function PlayerData:addAdCount()
	self.data.adCount = self.data.adCount + 1
end

-- 获取创角时间
function PlayerData:getCreateTime()
	return self.createTime
end

-- 获取玩家是否可以显示功能解锁
function PlayerData:getIfCanShowModuleUnlock()
	return self.showModuleUnlockChapter > 0
end

function PlayerData:markShowModuleUnlock()
	self.showModuleUnlockChapter = 0
end

function PlayerData:getModuleUnlockChapter()
	return self.showModuleUnlockChapter
end

function PlayerData:checkIfCanShowModuleUnlock(chapterId)
	if self.moduleUnlockChapterMap == nil then
		return
	end
	if not self.moduleUnlockChapterMap[chapterId] then
		return
	end
	self.showModuleUnlockChapter = chapterId
end

-- 头像------------------------------------------------------------------------------------

-- 获取玩家昵称
function PlayerData:getNickname()
    if self.data.playInfo.nickName == nil or #self.data.playInfo.nickName == 0 then
        return I18N:getGlobalText(I18N.GlobalConst.NEW_PLAYER)
    end
    return self.data.playInfo.nickName
end

-- 设置玩家昵称
function PlayerData:setNickname(name)
	self.data.playInfo.nickName = name
	self.data.playInfo.nameChanged = true
	self:markDirty()
end

-- 是否可以免费修改昵称
function PlayerData:isFreeRename()
    return not self.data.playInfo.nameChanged
end

-- 获取修改昵称的花费
function PlayerData:getRenameCost()
    return GFunc.getConstReward("change_name_cost")
end

-- 头像------------------------------------------------------------------------------------

-- 获取玩家当前使用的头像
function PlayerData:getUsingAvatarId()
    return self.data.playInfo.usingAvatarId
end

-- 设置玩家使用的头像
function PlayerData:setAvatarUsing(id)
	self.data.playInfo.usingAvatarId = id
	self:markDirty()
end

-- 获取头像icon id
function PlayerData:getAvatarIconId(id)
	local cfg = ConfigManager:getConfig("avatar")[id]
	if cfg then
		return cfg.iconId
	end
end

-- 头像是否解锁
function PlayerData:isAvatarUnlock(id)
	if self.data.playInfo.unlockAvatar == nil then
		return false
	end
    return self.data.playInfo.unlockAvatar[id] ~= nil
end

-- 设置头像解锁
function PlayerData:setAvatarUnlock(id)
	Logger.logHighlight("解锁头像："..id)
	if self.data.playInfo.unlockAvatar == nil then
		self.data.playInfo.unlockAvatar = {}
	end
    self.data.playInfo.unlockAvatar[id] = Time:getServerTime()
	self:setNewAvatarStatus(id, true)
end

-- 获取头像描述
function PlayerData:getAvatarDesc(id)
    return I18N:getText("avatar", id, "desc")
end

-- 是否有新头像
function PlayerData:hasNewAvatar()
	local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.avatar == nil or #newIds.avatar == 0 then
		return false
	end
    return true
end

-- 是否是新头像
function PlayerData:isNewAvatar(id)
    local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.avatar ~= nil then
		return table.containValue(newIds.avatar, id)
	end
    return false
end

-- 设置新头像状态
function PlayerData:setNewAvatarStatus(id, isNew)
    local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.avatar == nil then
		newIds.avatar = {}
	end

	if isNew then
		table.insert(newIds.avatar, id)
	else
		table.removebyvalue(newIds.avatar, id, true)
	end
    LocalData:setNewAvatarAndFrame(newIds)
	self:markDirty()
end

-- 是否显示头像(已解锁+未解锁可显示)
function PlayerData:isShowAvatar(id)
	if self:isAvatarUnlock(id) then
		return true
	end
	-- 判断未解锁时是否显示
    return not ConfigManager:getConfig("avatar")[id].unlock_show
end

-- 获取可以显示的所有头像id
function PlayerData:getShowAvatarIds()
	local unlockIds = table.keys(self.data.playInfo.unlockAvatar)
	local lockIds = {}
	for id, data in pairs(ConfigManager:getConfig("avatar")) do
		if (not self:isAvatarUnlock(id)) and self:isShowAvatar(id) then
			table.insert(lockIds, id)
		end
	end
	table.sort(unlockIds, function(a, b)
		return a < b
	end)
	table.sort(lockIds, function(a, b)
		return a < b
	end)
    return table.addArray(unlockIds, lockIds)
end

-- 获取可解锁的头像id列表
function PlayerData:getCanUnlockAvatarIds(checkData)
	local ids = {}
	if type(checkData) == "table" then
		-- 判断items解锁
		for index, reward in ipairs(checkData) do
			if reward.type == GConst.REWARD_TYPE.ITEM then
				local itemCfg = ConfigManager:getConfig("item")[reward.item.id]
				-- 头像道具、皮肤道具可解锁头像
				if itemCfg.type == GConst.ItemConst.ITEM_TYPE.AVATAR or itemCfg.type == GConst.ItemConst.ITEM_TYPE.SKIN then
					for id, data in pairs(ConfigManager:getConfig("avatar")) do
						if not self:isAvatarUnlock(id) and data.item == reward.item.id then
							table.insert(ids, id)
						end
					end
				end
			end
		end
	elseif type(checkData) == "number" then
		-- 判断hero解锁
		for id, data in pairs(ConfigManager:getConfig("avatar")) do
			if not self:isAvatarUnlock(id) and data.hero == checkData then
				table.insert(ids, id)
			end
		end
	end
	return ids
end

-- 获取头像背景
function PlayerData:getAvatarBg(id)
	local cfg = ConfigManager:getConfig("avatar")[id]
	if cfg and cfg.hero then
		-- hero来源
		local hero = ConfigManager:getConfig("hero")[cfg.hero]
    	return hero and GConst.HERO_SMALL_FRAME_QLT[hero.qlt]
	elseif cfg and cfg.item then
		-- item来源
		local item = ConfigManager:getConfig("item")[cfg.item]
    	return item and GConst.HERO_SMALL_FRAME_QLT[item.qlt]
	end
	return nil
end

-- 头像框-----------------------------------------------------------------------------------

-- 获取玩家当前使用的头像框
function PlayerData:getUsingFrameId()
    return self.data.playInfo.usingFrameId
end

-- 设置玩家使用的头像框
function PlayerData:setFrameUsing(id)
	self.data.playInfo.usingFrameId = id
	self:markDirty()
end

-- 获取框icon id
function PlayerData:getFrameIconId(id)
	local cfg = ConfigManager:getConfig("avatar_frame")[id]
	if cfg then
		return cfg.iconId
	end
end

-- 头像框是否解锁
function PlayerData:isFrameUnlock(id)
    if self.data.playInfo.unlockFrame == nil then
		return false
	end
    return self.data.playInfo.unlockFrame[id] ~= nil
end

-- 设置头像框解锁
function PlayerData:setFrameUnlock(id)
	Logger.logHighlight("解锁头像框："..id)
	if self.data.playInfo.unlockFrame == nil then
		self.data.playInfo.unlockFrame = {}
	end
    self.data.playInfo.unlockFrame[id] = Time:getServerTime()
	self:setNewFrameStatus(id, true)
end

-- 获取头像框描述
function PlayerData:getFrameDesc(id)
    return I18N:getText("avatar_frame", id, "desc")
end

-- 是否有新头像框
function PlayerData:hasNewFrame()
	local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.frame == nil or #newIds.frame == 0 then
		return false
	end
    return true
end

-- 是否是新头像框
function PlayerData:isNewFrame(id)
	local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.frame ~= nil then
		return table.containValue(newIds.frame, id)
	end
    return false
end

-- 设置新头像框状态
function PlayerData:setNewFrameStatus(id, isNew)
	local newIds = LocalData:getNewAvatarAndFrame()
	if newIds.frame == nil then
		newIds.frame = {}
	end

	if isNew then
		table.insert(newIds.frame, id)
	else
		table.removebyvalue(newIds.frame, id, true)
	end
    LocalData:setNewAvatarAndFrame(newIds)
	self:markDirty()
end

-- 是否显示头像框(已解锁+未解锁可显示)
function PlayerData:isShowFrame(id)
    if self:isFrameUnlock(id) then
		return true
	end
	-- 判断未解锁时是否显示
	local lock_show = ConfigManager:getConfig("avatar_frame")[id].unlock_show
	if lock_show ~= nil then
		return not lock_show
	else
		return true
	end
end

-- 获取可以显示的所有头像框id(已解锁小id>已解锁大id>未解锁小id>未解锁大id)
function PlayerData:getShowFrameIds()
    local unlockIds = table.keys(self.data.playInfo.unlockFrame)
	local lockIds = {}
	for id, data in pairs(ConfigManager:getConfig("avatar_frame")) do
		if (not self:isFrameUnlock(id)) and self:isShowFrame(id) then
			table.insert(lockIds, id)
		end
	end
	table.sort(unlockIds, function(a, b)
		return a < b
	end)
	table.sort(lockIds, function(a, b)
		return a < b
	end)
    return table.addArray(unlockIds, lockIds)
end

-- 获取可解锁的头像框id列表
function PlayerData:getCanUnlockFrameIds(checkData)
	local ids = {}
	if type(checkData) == "table" then
		-- 判断items解锁
		for index, reward in ipairs(checkData) do
			if reward.type == GConst.REWARD_TYPE.ITEM and ConfigManager:getConfig("item")[reward.item.id].type == GConst.ItemConst.ITEM_TYPE.FRAME  then
				for id, data in pairs(ConfigManager:getConfig("avatar_frame")) do
					if not self:isFrameUnlock(id) and data.item == reward.item.id then
						table.insert(ids, id)
					end
				end
			end
		end
	end
	return ids
end

-- 竞技场入场券

function PlayerData:getArenaTicket()
	return self.arenaTicket or 0
end

function PlayerData:getArenaTicketGemBuyCount()
	return self.data.arenaTicketGemCount
end

function PlayerData:getArenaTicketAdBuyCount()
	return self.data.arenaTicketADCount
end

function PlayerData:setArenaTicket(ticket)
	self.arenaTicket = ticket
end

function PlayerData:getMaxArenaTicket()
	if self.maxArenaTicket == nil then
		self.maxArenaTicket = ConfigManager:getConfig("recovery")[GConst.ItemConst.ITEM_ID_ARENA_TICKET].limit
	end
	return self.maxArenaTicket
end

function PlayerData:addArenaTicketGemBuyCount()
	self.data.arenaTicketGemCount = self.data.arenaTicketGemCount + 1
end

function PlayerData:addArenaTicketAdBuyCount()
	self.data.arenaTicketADCount = self.data.arenaTicketADCount + 1
end

function PlayerData:getRegisterTs()
	return self.register_ts or Time:getServerTime()
end

function PlayerData:getIsInternal()
	return self.internal
end

-- 服务器下发的版本号，跟客户端版本号不一致
function PlayerData:getGameVersion()
	return self.game_version
end

return PlayerData