local RollToastManager = class("RollToastManager", BaseModule)

local HUNDRED_PIXEL_TIME = 0.4
local MIN_SPACING = 100
local SECONDS_PRE_MINUTE = 60
local THREE_MINITE_SECOND = 180
local FOUR_MINITE_SECOND = 240
local FIVE_MINITE_SECOND = 300
local TEN_MINITE_SECOND = 600
local FIFTEEN_MINITE_SECOND = 900

function RollToastManager:ctor()
	self.curIndex = 0
	self.toastList = {}
end

function RollToastManager:clear(dontClearUpdateContent)
	self.curIndex = 0
	self.toastList = {}
    if not dontClearUpdateContent then
        self.updateContent = nil
    end
    self:clearSeq()
end

function RollToastManager:showToast(str)
    if self.updateContent then
        return
    end

    local mainUIOn = false
    local uiList = UIManager:getUIList()
    for _, uiObj in ipairs(uiList) do
        if uiObj:getUIIndex() == UIManager.UI_PATH.MAINCITY_UI then
            mainUIOn = uiObj:isVisible()
            break
        end
    end

    if not mainUIOn then
        return
    end

	if not self.curIndex or not self.toastList or self.curIndex >= #self.toastList then
		self.toastList = {}
		self.curIndex = 0
	end

	table.insert(self.toastList, str)

    self:tryShowToast(true)
end

function RollToastManager:tryShowToast(ignoreMainUI)
    if not ignoreMainUI then
        local mainUIOn = false
        local uiList = UIManager:getUIList()
        for _, uiObj in ipairs(uiList) do
            if uiObj:getUIIndex() == UIManager.UI_PATH.MAINCITY_UI then
                mainUIOn = uiObj:isVisible()
                break
            end
        end

        if not mainUIOn then
            return
        end
    end

    if not self.curIndex or not self.toastList or self.curIndex >= #self.toastList then
		self.toastList = {}
		self.curIndex = 0
	end

    if self.updateContent then
        self:_showToast(self.updateContent, true)
        self.toastList = {}
		self.curIndex = 0
        return  -- 有维护更新时，强制显示更新，并且清除所有缓存
    end

    local index = self.curIndex + 1
    if self.toastList[index] then
        self:_showToast(self.toastList[index])
    end
end

function RollToastManager:_showToast(str, isUpdateConetnt)
	UIManager:getRollToast(function(prefabObject)
        prefabObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = true
        local seq, content = self:getIdleSeq(prefabObject)
        if seq then
            if not isUpdateConetnt then
                self.curIndex = self.curIndex + 1
            end
            content:setText(str)
            content:setSizeDeltaX(content:getComponent(GConst.TYPEOF_UNITY_CLASS.UI_TEXT_MESH_PRO).preferredWidth)
            content:setAnchoredPositionX(0)
            local targetPos = prefabObject:getSizeDeltaX() + content:getSizeDeltaX()
            local tryShowNextPosX = content:getSizeDeltaX() + MIN_SPACING

            seq:Append(content:getTransform():DOAnchorPosX(-targetPos, (targetPos / 100) * HUNDRED_PIXEL_TIME):SetEase(CS.DG.Tweening.Ease.Linear))
            seq:InsertCallback((tryShowNextPosX / 100) * HUNDRED_PIXEL_TIME, function()
                self:tryShowToast()
            end)
        end
	end)
end

function RollToastManager:getIdleSeq(rollToastObj)
    local uiMap = rollToastObj:genAllChildren()
    local content1 = uiMap["roll_toast.content_1"]
    local content2 = uiMap["roll_toast.content_2"]
    if not self.seq1 then
        local canCreate = true
        if self.seq2 and (content2:getAnchoredPosition().x + content2:getSizeDeltaX() > -MIN_SPACING) then
            canCreate = false
        end
        if canCreate then
            self.seq1 = content1:createBindTweenSequence()
            self.seq1:OnComplete(function()
                self.seq1 = nil
                self:tryShowToast()
                self:tryHide()
            end)
            if not self.seq2 then
                content2:setText(GConst.EMPTY_STRING)
            end
            return self.seq1, content1
        end
    end

    if not self.seq2 then
        local canCreate = true
        if self.seq1 and (content1:getAnchoredPosition().x + content1:getSizeDeltaX() > -MIN_SPACING) then
            canCreate = false
        end
        if canCreate then
            self.seq2 = content2:createBindTweenSequence()
            self.seq2:OnComplete(function()
                self.seq2 = nil
                self:tryShowToast()
                self:tryHide()
            end)
            if not self.seq1 then
                content1:setText(GConst.EMPTY_STRING)
            end
            return self.seq2, content2
        end
    end
end

function RollToastManager:tryHide()
    if self.curIndex >= #self.toastList and not self.updateContent and not self.seq1 and not self.seq2 then
        UIManager:getRollToast(function(prefabObject)
            prefabObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false
        end)
    end
end

function RollToastManager:clearSeq()
    if self.seq1 then
        self.seq1:Kill()
        self.seq1 = nil
    end
    if self.seq2 then
        self.seq2:Kill()
        self.seq2 = nil
    end
end

function RollToastManager:showUpdateToast(cd)
    UIManager:getRollToast(function(prefabObject)
        prefabObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS).enabled = false

        if prefabObject._updateToastSequence then
            prefabObject._updateToastSequence:Kill()
            prefabObject._updateToastSequence = nil
        end

        prefabObject._updateToastSequence = prefabObject:createBindTweenSequence()
        prefabObject._updateToastSequence:SetUpdate(CS.DG.Tweening.UpdateType.Normal, true)

        self.updateContent = nil
        if cd >= FIFTEEN_MINITE_SECOND - SECONDS_PRE_MINUTE then  -- 大于等于14分钟
            local intervalTime = cd - FIFTEEN_MINITE_SECOND + SECONDS_PRE_MINUTE
            if cd >= FIFTEEN_MINITE_SECOND then -- 大于等于15分钟
                prefabObject._updateToastSequence:AppendInterval(cd - FIFTEEN_MINITE_SECOND)
                intervalTime = SECONDS_PRE_MINUTE
            end

            -- 15分钟
            local minute = math.floor(FIFTEEN_MINITE_SECOND / SECONDS_PRE_MINUTE)
            if cd < FIFTEEN_MINITE_SECOND then
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
            end
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
                self:tryShowToast()
                DataManager.ChatData:getChatSystem():addMaintenanceMsg(minute)
            end)
            prefabObject._updateToastSequence:AppendInterval(intervalTime)
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = nil
            end)
            prefabObject._updateToastSequence:AppendInterval(FOUR_MINITE_SECOND)

            cd = TEN_MINITE_SECOND
        end

        if cd >= TEN_MINITE_SECOND - SECONDS_PRE_MINUTE then  -- 大于等于9分钟
            local intervalTime = cd - TEN_MINITE_SECOND + SECONDS_PRE_MINUTE
            if cd >= TEN_MINITE_SECOND then
                prefabObject._updateToastSequence:AppendInterval(cd - TEN_MINITE_SECOND)
                intervalTime = SECONDS_PRE_MINUTE
            end

            -- 10分钟
            local minute = math.floor(TEN_MINITE_SECOND / SECONDS_PRE_MINUTE)
            if cd < TEN_MINITE_SECOND then
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
            end
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
                self:tryShowToast()
                DataManager.ChatData:getChatSystem():addMaintenanceMsg(minute)
            end)
            prefabObject._updateToastSequence:AppendInterval(intervalTime)
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = nil
            end)
            prefabObject._updateToastSequence:AppendInterval(FOUR_MINITE_SECOND)

            cd = FIVE_MINITE_SECOND
        end

        if cd >= FIVE_MINITE_SECOND - SECONDS_PRE_MINUTE then  -- 大于等于4分钟
            local intervalTime = cd - FIVE_MINITE_SECOND + SECONDS_PRE_MINUTE
            if cd >= FIVE_MINITE_SECOND then
                prefabObject._updateToastSequence:AppendInterval(cd - FIVE_MINITE_SECOND)
                intervalTime = SECONDS_PRE_MINUTE
            end

            -- 5分钟
            local minute = math.floor(FIVE_MINITE_SECOND / SECONDS_PRE_MINUTE)
            if cd < FIVE_MINITE_SECOND then
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
            end
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
                self:tryShowToast()
                DataManager.ChatData:getChatSystem():addMaintenanceMsg(minute)
            end)
            prefabObject._updateToastSequence:AppendInterval(intervalTime)
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = nil
            end)
            prefabObject._updateToastSequence:AppendInterval(THREE_MINITE_SECOND)

            cd = SECONDS_PRE_MINUTE
        end

        if cd >= 0 then -- 最后几分钟
            local intervalTime = cd
            if cd >= SECONDS_PRE_MINUTE then
                prefabObject._updateToastSequence:AppendInterval(cd - SECONDS_PRE_MINUTE)
                intervalTime = SECONDS_PRE_MINUTE
            end

            -- 1分钟
            local minute = math.floor(SECONDS_PRE_MINUTE / SECONDS_PRE_MINUTE)
            if cd < SECONDS_PRE_MINUTE then
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
            end
            prefabObject._updateToastSequence:AppendCallback(function()
                self.updateContent = I18N:getGlobalText(I18N.GlobalConst.UPDATE_TOAST_TXT, minute)
                self:tryShowToast()
                DataManager.ChatData:getChatSystem():addMaintenanceMsg(minute)
            end)
            prefabObject._updateToastSequence:AppendInterval(intervalTime)
            prefabObject._updateToastSequence:OnComplete(function()
                self.updateContent = nil
            end)
        end

        self:tryShowToast()
    end)
end

return RollToastManager