IRF_SpellTimer = LibStub("AceAddon-3.0"):NewAddon("IRF_SpellTimer", "AceEvent-3.0")
local mother = InvenRaidFrames

local UnitAura = _G.UnitAura
local UnitBuff = _G.UnitBuff
local UnitDebuff = _G.UnitDebuff
local GetTime = _G.GetTime
local pairs = _G.pairs

local spelltimersIcon = CreateFrame("Frame", nil, UIParent)
local spelltimersText = CreateFrame("Frame", nil, UIParent)
local spelltimers = {}
local points = { { "BOTTOMLEFT", 2, 2 }, { "BOTTOM", -9, 2}, { "BOTTOMRIGHT", -16, 2 } }
local points2 = { 2, 0, -2 }
local stackcolor = { "|cffffffff", "|cffff8800", "|cffff0000" }
local setevent = nil
local showhide = false
local f, id, d, t, init, name, icon, count, timeLeft, strata, level, s, b, tt, leftTime

function IRF_SpellTimer:OnInitialize()
	self:SetScale()
	self:SetMode()
	self:RegisterEvent("UNIT_AURA")
	self:RegisterMessage("InvenRaidFrames_InitUnits", function() self:UNIT_AURA() end)
	self:RegisterMessage("InvenRaidFrames_UpdateScale", "SetScale")
	self:RegisterMessage("InvenRaidFrames_HideAll", function()
		for unit, frame in pairs(spelltimers) do
			for i = 1, 4 do
				if frame[i] then
					frame[i]:Hide()
				end
			end
		end

	end)
	self:UNIT_AURA()
end

function IRF_SpellTimer:SetMode()
	if mother.vars.class == "드루이드" or mother.vars.class == "사제" then
		if mother.db.char.spelltimer == "아이콘" then
			spelltimersIcon:Show()
			spelltimersText:Hide()
			self:UNIT_AURA()
		elseif mother.db.char.spelltimer == "텍스트" then
			spelltimersIcon:Hide()
			spelltimersText:Show()
			self:UNIT_AURA()
		else
			spelltimersIcon:Hide()
			spelltimersText:Hide()
		end
	elseif mother.db.char.spelltimer2 then
		spelltimersIcon:Show()
		spelltimersText:Hide()
		self:UNIT_AURA()
	else
		spelltimersIcon:Hide()
		spelltimersText:Hide()
	end
end

function IRF_SpellTimer:SetScale()
	spelltimersIcon:SetScale(mother.db.profile.scale)
	spelltimersText:SetScale(mother.db.profile.scale)
end

function IRF_SpellTimer:UNIT_AURA(_, unit, frame)
	if unit then
		f = frame or mother:GetUnit(unit)
		if not f then return end
		d = mother.vars.classDB
		t = InvenRaidFramesDispelDB
		init = { false, false, false }
		for spell, index in pairs(d.spell) do
			name, _, icon, count, _, _, timeLeft = UnitAura(unit, spell, nil, index > 0 and "HELPFUL" or "HELPFUL|PLAYER")
			if name then
				init[self:SetSpellTimer(unit, f, name, index, icon, count, timeLeft)] = true
			end
			if mother.vars.class == "사제" or mother.vars.class == "성기사" then
				name, _, icon, count, _, _, timeLeft = UnitAura(unit, spell, nil, "HARMFUL")
				if name then
					init[self:SetSpellTimer(unit, f, name, index, icon, count, timeLeft)] = true
				end
			end
		end
		if spelltimers[unit] then
			for i = 1, 3 do
				if not init[i] then
					spelltimers[unit][i].hideTime = 0
					if spelltimers[unit][4] then
						spelltimers[unit][4].timer[i] = 0
					end
				end
			end
		end
	else
		for unit, frame in pairs(spelltimers) do
			if not mother.vars.unit[unit] then
				for i = 1, 4 do
					if frame[i] then
						frame[i]:Hide()
					end
				end
			end
		end
		for unit, frame in pairs(mother.vars.unit) do
			self:UNIT_AURA(_, unit, frame)
		end
	end
end

function IRF_SpellTimer:ClearPet()
	for unit, frame in pairs(spelltimers) do
		if strfind(unit, "pet") and not UnitExists(unit) then
			for i = 1, 4 do
				if spelltimers[unit][i] then
					spelltimers[unit][i]:Hide()
				end
			end
		end
	end
end

function IRF_SpellTimer:SetSpellTimer(unit, frame, name, id, icon, count, timeLeft)
	id = abs(id)
	if name == "회복의 기원" and mother.db.char.spelltimer == "아이콘" and not mother.db.char.pmCount then
		self:Init(unit, frame, id, icon, 1, timeLeft)
	else
		self:Init(unit, frame, id, icon, count, timeLeft)
	end
	return id
end

function IRF_SpellTimer:Init(unit, frame, id, icon, count, timeLeft)
	f = frame or mother:GetUnit(unit)
	if not f then return end
	strata = f:GetFrameStrata()
	level = f.textparent:GetFrameLevel() or 0
	spelltimersIcon:SetFrameStrata(strata)
	spelltimersIcon:SetFrameLevel(level + 3)
	spelltimersText:SetFrameStrata(strata)
	spelltimersText:SetFrameLevel(level + 3)
	s = self:Create(unit)
	b = s[id]
	b.icon:SetTexture(icon)
	b.count:SetText((count and count > 1) and count or "")
	b.hideTime = mother.db.char.showSpellTime[id] and timeLeft or nil
	if mother.db.char.showSpell[id] then
		b:ClearAllPoints()
		b:SetPoint(points[id][1], f, points[id][1], b.hideTime and points[id][2] or points2[id], points[id][3])
		if spelltimersIcon:IsVisible() then
			b:Show()
		end
	else
		b:Hide()
	end
	if s[4] then
		s[4]:ClearAllPoints()
		s[4]:SetPoint("BOTTOM", f, "BOTTOM", 0, 2)
		s[4].count[id] = count
		s[4].timer[id] = (mother.vars.class == "사제" and id == 3) and "X" or (timeLeft or 0)
		if spelltimersText:IsVisible() then
			s[4]:Show()
		end
	end
end

local function spellTimerFrameOnUpdate(self)
	if self.hideTime then
		leftTime = self.hideTime - GetTime()
		if leftTime < 100 then
			self.cooldown:SetText(ceil(leftTime))
		else
			self.cooldown:SetText("")
		end
		if leftTime <= 0 then
			this:Hide()
		end
	else
		self.cooldown:SetText("")
	end
end

local function spellTimerFrameOnHide(self)
	self.count:SetText("")
	self.cooldown:SetText("")
	self.icon:SetTexture("")
	self.hideTime = nil
end

local function spellTimerTextOnUpdate(self)
	tt = nil
	for i = 1, 3 do
		if type(self.timer[i]) == "string" then
			tt = (tt and (tt.."-") or "")..self.timer[i]
		elseif self.timer[i] == 0 or self.timer[i] == nil then
			tt = (tt and (tt.."-") or "").."0"
		else
			leftTime = ceil(self.timer[i] - GetTime())
			if leftTime <= 0 then
				tt = (tt and (tt.."-") or "").."0"
			else
				if i == 1 and mother.vars.class == "드루이드" then
					tt = (tt and (tt.."-") or "")..stackcolor[self.count[i]]..leftTime.."|r"
				elseif i == 2 and mother.vars.class == "사제" then
					tt = (tt and (tt.."-") or "")..self.count[i]
				else
					tt = (tt and (tt.."-") or "")..leftTime
				end
			end
		end
	end
	if tt == "0-0-0" or not spelltimersText:IsVisible() then
		this:Hide()
	else
		self.text:SetText(tt)
	end
end

local function spellTimerTextOnHide(self)
	self.timer = { 0, 0, 0 }
	self.count = { 0, 0, 0 }
	self.text:SetText("")
end

function IRF_SpellTimer:Create(unit)
	if not spelltimers[unit] then
		spelltimers[unit] = {}
		for i = 1, 3 do
			b = CreateFrame("Frame", nil, spelltimersIcon)
			b.icon = b:CreateTexture(nil, "ARTWORK")
			b.icon:SetAllPoints(b)
			b.count = b:CreateFontString(nil, "OVERLAY", "NumberFontNormalSmall")
			b.count:SetPoint("CENTER", b, "CENTER", 2, 0)
			b.count:SetText("")
			b.cooldown = b:CreateFontString(nil, "OVERLAY", "GameFontNormal")
			b.cooldown:SetTextColor(1, 1, 1)
			b.cooldown:SetPoint("LEFT", b, "RIGHT", 0, 1)
			b.cooldown:SetText("")
			b:SetScript("OnUpdate", spellTimerFrameOnUpdate)
			b:SetScript("OnHide", spellTimerFrameOnHide)
			b:SetWidth(13)
			b:SetHeight(13)
			b:Hide()
			spelltimers[unit][i] = b
		end
		if mother.vars.class == "드루이드" or mother.vars.class == "사제" then
			t = CreateFrame("Frame", nil, spelltimersText)
			t.timer = { 0, 0, 0 }
			t.count = { 0, 0, 0 }
			t.text = t:CreateFontString(nil, "OVERLAY", "GameFontNormal")
			t.text:SetTextColor(1, 1, 1)
			t.text:SetPoint("CENTER", t, "CENTER")
			t.text:SetText("")
			t:SetWidth(13)
			t:SetHeight(13)
			t:Hide()
			t:SetScript("OnUpdate", spellTimerTextOnUpdate)
			t:SetScript("OnHide", spellTimerTextOnHide)
			spelltimers[unit][4] = t
		end
	end
	return spelltimers[unit]
end