local mod	= DBM:NewMod(2394, "DBM-CastleNathria", nil, 1190)
local L		= mod:GetLocalizedStrings()

mod:SetRevision("20210224082525")
mod:SetCreatureID(164407)
mod:SetEncounterID(2399)
mod:SetUsedIcons(1)
mod:SetHotfixNoticeRev(20210119000000)--2021, 01, 19
mod:SetMinSyncRevision(20201228000000)
mod.respawnTime = 29

mod:RegisterCombat("combat")

mod:RegisterEventsInCombat(
	"SPELL_CAST_START 332318",
	"SPELL_CAST_SUCCESS 332687",
	"SPELL_AURA_APPLIED 331209 331314 342420 335470 340817 341250",
	"SPELL_AURA_REMOVED 331209 331314 342419 342420 340817",
--	"SPELL_PERIODIC_DAMAGE",
--	"SPELL_PERIODIC_MISSED",
	"SPELL_ENERGIZE 346269",
	"UNIT_SPELLCAST_SUCCEEDED boss1"
)

--TODO, this straght up needs an updateAllTimers function like archimonde to be perfect, especially around hateful gaze/impact stun
--The timers COULD be perfected, I'm just not sure it's worth the effort to since the variations are all predictable (based around spell queuing or delayed by impact stun)
--I'll return to perfecting timers if things don't change on live and can analylize dozens more logs to verify patterns
--[[
(ability.id = 332318) and type = "begincast"
 or ability.id = 332687 and type = "cast"
 or (ability.id = 335470 or ability.id = 335470 or ability.id = 331209) and type = "applydebuff"
 or ability.id = 346269 or ability.id = 331314
 or (ability.id = 342420 or ability.id = 340817) and type = "applydebuff"
--]]
local warnHatefulGaze							= mod:NewTargetCountAnnounce(331209, 4, nil, nil, nil, nil, nil, nil, true)
local warnStunnedImpact							= mod:NewTargetNoFilterAnnounce(331314, 1)
--local warnChainLink								= mod:NewTargetAnnounce(342419, 3)--Targetting debuff
local warnChainSlam								= mod:NewTargetCountAnnounce(335470, 3, nil, nil, nil, nil, nil, nil, true)
local warnGruesomeRage							= mod:NewTargetNoFilterAnnounce(341250, 4)

local specWarnHatefulGaze						= mod:NewSpecialWarningMoveTo(331209, nil, nil, nil, 3, 2)
local specWarnHeedlessCharge					= mod:NewSpecialWarningSoon(331212, nil, nil, nil, 2, 2)
local yellHatefulGaze							= mod:NewShortYell(331209)
local yellHatefulGazeFades						= mod:NewShortFadesYell(331209)
local specWarnChainLink							= mod:NewSpecialWarningMoveTo(335300, nil, nil, nil, 1, 2)
local yellChainLink								= mod:NewIconRepeatYell(335300, DBM_CORE_L.AUTO_YELL_ANNOUNCE_TEXT.shortyell, false, 2)
local specWarnChainSlam							= mod:NewSpecialWarningYou(335470, nil, nil, nil, 1, 2)
local specWarnChainSlamPartner					= mod:NewSpecialWarningTarget(335470, nil, nil, nil, 1, 2)
local yellChainSlam								= mod:NewShortYell(335470, nil, nil, nil, "YELL")
local yellChainSlamFades						= mod:NewShortFadesYell(335470, nil, nil, nil, "YELL")
local specWarnDestructiveStomp					= mod:NewSpecialWarningRun(332318, "Melee", 247733, nil, 4, 2)
local specWarnColossalRoar						= mod:NewSpecialWarningSpell(332687, nil, 226056, nil, 2, 2)
local specWarnFallingRubble						= mod:NewSpecialWarningDodge(332572, nil, nil, nil, 2, 2)
local specWarnSiesmicShift						= mod:NewSpecialWarningMoveAway(340817, nil, nil, nil, 2, 2, 4)
--local specWarnGTFO							= mod:NewSpecialWarningGTFO(270290, nil, nil, nil, 1, 8)

--All timers outside of stun and gaze will use keep arg so timers remain visible if they come off CD during gaze stun
local timerHatefulGazeCD						= mod:NewCDCountTimer(68.9, 331209, nil, nil, nil, 3, nil, DBM_CORE_L.IMPORTANT_ICON, nil, 1, 4)
local timerStunnedImpact						= mod:NewBuffActiveTimer(12, 331314, nil, nil, nil, 5, nil, DBM_CORE_L.DAMAGE_ICON)
local timerChainLinkCD							= mod:NewCDCountTimer(68.9, 335300, nil, nil, nil, 3, nil, nil, true)
local timerChainSlamCD							= mod:NewCDCountTimer(68.9, 335354, nil, nil, nil, 3, nil, DBM_CORE_L.HEROIC_ICON, true)
local timerDestructiveStompCD					= mod:NewCDCountTimer(44.3, 332318, 247733, nil, nil, 3, nil, nil, true)
local timerFallingRubbleCD						= mod:NewCDCountTimer(68.9, 332572, nil, nil, nil, 3, nil, nil, true)
local timerColossalRoarCD						= mod:NewCDCountTimer(31.9, 332687, 226056, nil, nil, 2, nil, nil, true)
local timerSiesmicShiftCD						= mod:NewCDCountTimer(34, 340817, nil, nil, nil, 3, nil, DBM_CORE_L.MYTHIC_ICON, true)--Mythic

--local berserkTimer							= mod:NewBerserkTimer(600)

mod:AddRangeFrameOption(5, 340817)
mod:AddSetIconOption("SetIconGaze", 331209, true, false, {1})

mod.vb.gazeCount = 0
mod.vb.stompCount = 0
mod.vb.roarCount = 0
mod.vb.linkCount = 0
mod.vb.chainSlamCount = 0
mod.vb.rubbleCount = 0
mod.vb.shiftCount = 0
local ChainLinkTargets = {}
local playerName = UnitName("player")
local playerPartner = nil
local SiesmicTimers = {18.1, 25.4, 29.3, 12.3, 25.5, 30.1, 12.6, 25.5, 30.1, 12.3, 25.4, 30.1, 13.5, 25.5, 28.8}
--								   30.1				       13.5        31.3
local function ChainLinkYellRepeater(self, text, runTimes)
	yellChainLink:Yell(text)
	runTimes = runTimes + 1
	if runTimes < 3 then
		self:Schedule(2, ChainLinkYellRepeater, self, text, runTimes)
	end
end

function mod:OnCombatStart(delay)
	self.vb.gazeCount = 0
	self.vb.stompCount = 0
	self.vb.roarCount = 0
	self.vb.linkCount = 0
	self.vb.chainSlamCount = 0
	self.vb.rubbleCount = 0
	playerPartner = nil
	table.wipe(ChainLinkTargets)
	--Roar cast instantly on pull, no timer needed
	if self:IsLFR() then
		timerFallingRubbleCD:Start(12.1-delay, 1)--Unknown, not in combat log
		timerDestructiveStompCD:Start(18.5-delay, 1)
		timerHatefulGazeCD:Start(51.3-delay, 1)
	else
		timerChainLinkCD:Start(4.7-delay, 1)
		timerFallingRubbleCD:Start(12.5-delay, 1)
		timerDestructiveStompCD:Start(18.2-delay, 1)
		timerHatefulGazeCD:Start(50.1-delay, 1)
		if self:IsHard() then
			timerChainSlamCD:Start(28.3-delay, 1)
			if self:IsMythic() then
				self.vb.shiftCount = 0
				timerSiesmicShiftCD:Start(18.1, 1)
			end
		end
	end
--	berserkTimer:Start(-delay)
end

function mod:OnCombatEnd()
	if self.Options.RangeFrame then
		DBM.RangeCheck:Hide()
	end
end

function mod:SPELL_CAST_START(args)
	local spellId = args.spellId
	if spellId == 332318 then
		self.vb.stompCount = self.vb.stompCount + 1
		specWarnDestructiveStomp:Show()
		specWarnDestructiveStomp:Play("justrun")
		--Heroic
		--pull:18.2, 25.9, 44.6, 25.5, 44.9, 25.5, 45.0, 25.3, 44.0", -- [2]
		--Mythic
		--pull:18.6, 25.5, 43.4, 25.5, 43.8, 25.5, 43.7", -- [2]
		if self.vb.stompCount % 2 == 0 then
			timerDestructiveStompCD:Start(43, self.vb.stompCount+1)
		else
			timerDestructiveStompCD:Start(25, self.vb.stompCount+1)--LFR is only about .5 seconds slower, so not worth nitpick
		end
	end
end

function mod:SPELL_CAST_SUCCESS(args)
	local spellId = args.spellId
	if spellId == 332687 then
		self.vb.roarCount = self.vb.roarCount + 1
		specWarnColossalRoar:Show()
		specWarnColossalRoar:Play("aesoon")
		timerColossalRoarCD:Start(self:IsLFR() and 33.2 or 31.9, self.vb.roarCount+1)
	end
end

function mod:SPELL_AURA_APPLIED(args)
	local spellId = args.spellId
	if spellId == 331209 then
		self.vb.gazeCount = self.vb.gazeCount + 1
		timerHatefulGazeCD:Start(self:IsLFR() and 70.3 or 67.3, self.vb.gazeCount+1)
		if self.Options.SetIconGaze then
			self:SetIcon(args.destName, 1)
		end
		if args:IsPlayer() then
			specWarnHatefulGaze:Show(DBM_CORE_L.PILLAR)
			specWarnHatefulGaze:Play("targetyou")
			yellHatefulGaze:Yell()
			yellHatefulGazeFades:Countdown(spellId)
		else
			specWarnHeedlessCharge:Show()
			specWarnHeedlessCharge:Play("farfromline")
			warnHatefulGaze:Show(self.vb.gazeCount, args.destName)
		end
	elseif spellId == 331314 then
		warnStunnedImpact:Show(args.destName)
		timerStunnedImpact:Start()
	elseif spellId == 342420 then--spellId == 342419 or
		--Combat log order is all 342419 first, then all 342420
		--Update, both spell Ids now have source and des names, so can just ignore one spell Id entirely and apply source/dest to check for pairs
		ChainLinkTargets[#ChainLinkTargets + 1] = args.sourceName
--		warnChainLink:CombinedShow(0.3, args.destName)
		local icon = #ChainLinkTargets--Generate icon on the evens, because then we can divide it by 2 to assign raid icon to that pair
		local playerIsInPair = false
		if args.sourceName == playerName then
			specWarnChainLink:Show(args.destName)
			specWarnChainLink:Play("gather")
			playerIsInPair = true
			playerPartner = args.destName
		elseif args.destName == playerName then
			specWarnChainLink:Show(args.sourceName)
			specWarnChainLink:Play("gather")
			playerIsInPair = true
			playerPartner = args.sourceName
		end
		if playerIsInPair then
			--need to account for up to 30 people (15 pairs)
			if icon == 9 then
				icon = "(°,,°)"
			elseif icon == 10 then
				icon = "(•_•)"
			elseif icon == 11 then
				icon = "(ಥ﹏ಥ)"
			elseif icon == 12 then
				icon = "(ツ)"
			elseif icon == 13 then
				icon = "ʕ•ᴥ•ʔ"
			elseif icon == 14 then
				icon = "ಠ_ಠ"
			elseif icon == 15 then
				icon = "(͡°͜°)"
			end
			self:Unschedule(ChainLinkYellRepeater)
			if type(icon) == "number" then icon = DBM_CORE_L.AUTO_YELL_CUSTOM_POSITION:format(icon, "") end
			self:Schedule(2, ChainLinkYellRepeater, self, icon, 0)
			yellChainLink:Yell(icon)
		end
	elseif spellId == 335470 then
		if args:IsPlayer() then
			specWarnChainSlam:Show()
			specWarnChainSlam:Play("targetyou")
			yellChainSlam:Yell()
			yellChainSlamFades:Countdown(4)--Can't auto pull from spellId
		elseif playerPartner and playerPartner == args.destName then
			specWarnChainSlamPartner:Show(args.destName)
			specWarnChainSlamPartner:Play("gathershare")
		else
			warnChainSlam:Show(self.vb.chainSlamCount, args.destName)
		end
		--Chain slam always extends Colossal Roar by a very precise amount
		if timerColossalRoarCD:GetRemaining(self.vb.roarCount+1) < 7.25 then
			local elapsed, total = timerColossalRoarCD:GetTime(self.vb.roarCount+1)
			local extend = 7.25 - (total-elapsed)
			DBM:Debug("timerColossalRoarCD extended by: "..extend, 2)
			timerColossalRoarCD:Stop()
			timerColossalRoarCD:Update(elapsed, total+extend, self.vb.roarCount+1)
		end
	elseif spellId == 341250 then
		warnGruesomeRage:Show(args.destName)
	elseif spellId == 340817 then
		if self:AntiSpam(8, 9) then
			self.vb.shiftCount = self.vb.shiftCount + 1
			local timer = SiesmicTimers[self.vb.shiftCount+1]
			if timer then
				timerSiesmicShiftCD:Start(timer, self.vb.shiftCount+1)
				local timerAfter = SiesmicTimers[self.vb.shiftCount+2]
				if not timerAfter then--Disable timer keeping if we're out of timer data beind THIS timer
					timerSiesmicShiftCD:SetSTKeep(false, self.vb.shiftCount+1)
				end
			end
		end
		if args:IsPlayer() then
			specWarnSiesmicShift:Show()
			specWarnSiesmicShift:Play("range5")
			if self.Options.RangeFrame then
				DBM.RangeCheck:Show(5)
			end
		end
	end
end

function mod:SPELL_AURA_REMOVED(args)
	local spellId = args.spellId
	if spellId == 331209 then
		if args:IsPlayer() then
			yellHatefulGazeFades:Cancel()
		end
		if self.Options.SetIconGaze then
			self:SetIcon(args.destName, 0)
		end
	elseif spellId == 331314 then
		timerStunnedImpact:Stop(args.destName)
	elseif spellId == 342419 or spellId == 342420 then--Both spellIds checked on purpose here for personal removal
		if args:IsPlayer() then
			self:Unschedule(ChainLinkYellRepeater)
			playerPartner = nil
		end
	elseif spellId == 340817 then
		if args:IsPlayer() then
			if self.Options.RangeFrame then
				DBM.RangeCheck:Hide()
			end
		end
	end
end

--[[
function mod:SPELL_PERIODIC_DAMAGE(_, _, _, _, destGUID, _, _, _, spellId, spellName)
	if spellId == 270290 and destGUID == UnitGUID("player") and self:AntiSpam(2, 2) then
		specWarnGTFO:Show(spellName)
		specWarnGTFO:Play("watchfeet")
	end
end
mod.SPELL_PERIODIC_MISSED = mod.SPELL_PERIODIC_DAMAGE
--]]

function mod:SPELL_ENERGIZE(_, _, _, _, _, _, _, _, spellId, _, _, amount)
	if spellId == 346269 then
		timerHatefulGazeCD:Stop()--Boss immediately full energy so terminate timer/countdown immediately
		--TODO, also adjust other timers instead of just using KeepTime?
		--Might be annoying work to do for something that shouldn't happen in a properly executed fight
	end
end

function mod:UNIT_SPELLCAST_SUCCEEDED(uId, _, spellId)
	if spellId == 335300 then--Chain link
		table.wipe(ChainLinkTargets)
		self.vb.linkCount = self.vb.linkCount + 1
		timerChainLinkCD:Start(67.7, self.vb.linkCount+1)--67.7-69.1
	elseif spellId == 341193 then--or spellId == 341103
		self.vb.rubbleCount = self.vb.rubbleCount + 1
		specWarnFallingRubble:Show(self.vb.rubbleCount)
		specWarnFallingRubble:Play("watchstep")
		timerFallingRubbleCD:Start(67.8, self.vb.rubbleCount+1)
	elseif spellId == 335354 then--Chain Slam
		self.vb.chainSlamCount = self.vb.chainSlamCount + 1
		timerChainSlamCD:Start(68.9, self.vb.chainSlamCount+1)
	end
end
