local SignMonthData = class("SignMonthData", BaseData)

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

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

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

function SignMonthData:initData(data)
	data = data or {}
	if EDITOR_MODE then
		Logger.logHighlight("30天签到")
		Logger.printTable(data)
	end

	self.curDay = data.day or 0
	self.lastAT = data.last_at or nil
	self.isAgain = data.again or false
	self.accum = data.accum or {}

	-- 初始化配置
	self:initConfig()
	self:setDirty()
	DataManager:registerCrossDayFunc("SignMonthData", function()
		if	self.curDay == self:getConfigCount() then
			self.curDay = 0
			self.accum = {}
		end
		self.isAgain = false
		self:setDirty()
    end)
	-- 如果功能未开启 注册功能开启监听
    if not self:isOpen() then
        DataManager:registerTryOpenFunc("SignMonthData", function()
            if not self:isOpen(false, true) then
                return
            end
            DataManager:unregisterTryOpenFunc("SignMonthData")
			self:setDirty()
        end)
    end
end

-- 初始化排序后的配置列表
function SignMonthData:initConfig()
	self.boxList = {}
	self.configList = {}
	for id, data in pairs(self:getConfig()) do
		if data.count_reward~= nil then
			table.insert(self.boxList, id)
		end
		table.insert(self.configList, data)
	end
	table.sort(self.boxList, function (a, b)
		return a < b
	end)
end

function SignMonthData:getConfig(id)
    if self._monthSigninCfg == nil then
        self._monthSigninCfg = ConfigManager:getConfig("act_month_signin")
    end
	if id then
		return self._monthSigninCfg[id]
	else
		return self._monthSigninCfg
	end
end

-- 是否开启
function SignMonthData:isOpen(showToast)
	if GFunc.isShenhe() then
		return false
	end
	if not ModuleManager:getIsOpen(ModuleManager.MODULE_KEY.SIGN_MONTH, not showToast) then
        return false
    end
	return true
end

-- 签到成功 天数+1
function SignMonthData:setSignSucceed()
	self.curDay = self:getCurDay() + 1
	self.lastAT = Time:getServerTime()
	self:setDirty()
end

function SignMonthData:setSignAgainSucceed()
	self.isAgain = true
	self:setDirty()
end

-- 获得已签到天数
function SignMonthData:getCurDay()
	return self.curDay
end

-- 宝箱领取成功
function SignMonthData:setAccumClaimSucceed(day)
	table.insert(self.accum, day)
	self:setDirty()
end

function SignMonthData:getAccumClaimID(index)
	return self.boxList[index] 
end

function SignMonthData:showRedPoint()
	if not self:isOpen() then
		return false
	end
	if self:getCanSign() then
		return true
	end
	for i = 1, #self.boxList do
		if self:getBoxState(i) == GConst.SignConst.BOX_STATE.CAN_CLAIM then
			return true
		end
	end
	return false
end

-- 获取奖励
function SignMonthData:getReward(type, day)
	local cfg = self.configList[day]
	if type == GConst.SignConst.MONTH_REWARD_TYPE.SIGN then
		return cfg.reward
	elseif type == GConst.SignConst.MONTH_REWARD_TYPE.BOX then
		return cfg.count_reward
	end
end

-- 获取循环时间
function SignMonthData:getCycleDay()
	return 30
end

function SignMonthData:getConfigCount()
	return #self.configList
end

--今天是否可以签到
function SignMonthData:getCanSign()
    if self.lastAT == nil then
        return true
    end
    return not Time:getTimeIsToday(self.lastAT)
end

--获取是否可以广告再次签到
function SignMonthData:getCanSignAgain()
	return self.isAgain
end

-- 当前签到是否是今天
function SignMonthData:getIsSignDay(day)
	if self:getCanSign() and day == self:getCurDay() + 1 then
		return true
	end
	return false
end

function SignMonthData:getIsSignAgainDay(day)
	if not self:getCanSign() and not self:getCanSignAgain() and day == self:getCurDay() then
		return true
	end
	return false
end

-- 是否已经领取
function SignMonthData:getHasGotReward(type, day)
	if type == GConst.SignConst.MONTH_REWARD_TYPE.SIGN then
		return day <= self.getCurDay()
	elseif type == GConst.SignConst.MONTH_REWARD_TYPE.BOX then
		return self.accum[day] or false
	end
end

-- 是否可领取
function SignMonthData:getSignState(day)
	if self:getIsSignDay(day) then --可以签到
		return GConst.SignConst.SIGN_STATE.CAN_SIGN
	else
		if self:getIsSignAgainDay(day) then --可以再次签到
			return GConst.SignConst.SIGN_STATE.CAN_SIGN_AD
		else
			if day > self:getCurDay() then
				return GConst.SignConst.SIGN_STATE.UNABLE_SIGN
			else
				return GConst.SignConst.SIGN_STATE.SIGNEDIN
			end
		end
	end
end

function SignMonthData:getBoxState(index)
	local day = self.boxList[index]
	if day then
		local isClaimed = false
		for k, v in pairs(self.accum) do
			if day == v then
				isClaimed = true
				break
			end
		end
		if isClaimed then
			return GConst.SignConst.BOX_STATE.CLAIMED
		else
			if day <= self:getCurDay() then
				return GConst.SignConst.BOX_STATE.CAN_CLAIM
			else
				return GConst.SignConst.BOX_STATE.UNABLE_CLAIM
			end
		end
	end
	return GConst.SignConst.BOX_STATE.UNABLE_CLAIM
end

function SignMonthData:getSliderValue()
	local curDay = self:getCurDay()
	local startDay = 0
	local rangeIndex = 1
	for i, day in ipairs(self.boxList) do
		if curDay <= day  then
			rangeIndex = i
            break
			--需要补充return
		else
			startDay = day
		end
	end
	local percentRange = GConst.SignConst.SIGN_MONTH_SLIDER_RANG[rangeIndex]
    if not percentRange then
        -- 如果找不到对应的范围，返回默认值或处理错误
        return 0
    end
	    -- 计算区间的起始天数和结束天数
    local endDay = self.boxList[rangeIndex]

    -- 计算在区间内的比例（避免除零错误）
    local ratio = 0
    if endDay > startDay then
        ratio = (curDay - startDay) / (endDay - startDay)
    end

    -- 线性插值计算最终百分比
    return percentRange[1] + ratio * (percentRange[2] - percentRange[1])
end

return SignMonthData