-- 생존기 표시 모듈
local IRF2 = InvenRaidFrames2

local _G = _G
local pairs = _G.pairs
local GetTime = _G.GetTime
local UnitAura = _G.UnitAura
local GetSpellInfo = _G.GetSpellInfo

local name, survival, endTime

local function getName(id)
	return id and GetSpellInfo(id) or "*"
end

-- 직업별 생존기 정의 (*는 타인에게 걸 수 있는 생존기)
local skills = {
	["WARRIOR"] = { [getName(871)] = "방벽", [getName(12975)] = "최저" },
	["ROGUE"] = { [getName(5277)] = "회피", [getName(31224)] = "그망" },
	["PALADIN"] = { [getName(642)] = "무적", [getName(498)] = "가호" },
	["MAGE"] = { [getName(27619)] = "얼방", [getName(66)] = "투명" },
	["HUNTER"] = { [getName(5384)] = "죽척", [getName(19263)] = "저지" },
	["PRIEST"] = { [getName(27827)] = "구원", [getName(47585)] = "분산" },
	["DRUID"] = { [getName(61336)] = "생본", [getName(22812)] = "껍질" },
	["DEATHKNIGHT"] = { [getName(48792)] = "얼인", [getName(51271)] = "불굴", [getName(49039)] = "리치", [getName(55233)] = "흡혈" },
	["SHAMAN"] = { [getName(30823)] = "주분" },
	["*"] = { [getName(1022)] = "보손", [getName(19752)] = "중재", [getName(47788)] = "수호", [getName(33206)] = "고억", [getName(6940)] = "희손" },
}
local ignoreEndTime = { [getName(19752)] = true, [getName(5834)] = true, [getName(66)] = true }

for p in pairs(skills) do
	if skills[p]["*"] then
		skills[p]["*"] = nil
	end
end

local survivalSkillHandler = CreateFrame("Frame")
survivalSkillHandler:Hide()
survivalSkillHandler:SetScript("OnUpdate", function(self)
	self.timer = GetTime()
	for unit, object in pairs(IRF2.units) do
		if object:IsShown() and object.survivalSkill and object.survivalSkill_endTime and object.survivalSkill_endTime > self.timer then
			object:UpdateText()
		end
	end
end)

local function checkTotalSurvivalSkill()
	for unit, object in pairs(IRF2.units) do
		if object:IsShown() and object.survivalSkill then
			return survivalSkillHandler:Show()
		end
	end
	survivalSkillHandler:Hide()
end

local function checkSkill(unit, class)
	-- 타인에게 걸 수 있는 생존기 체크
	if UnitExists(unit or "") then
		for spell, newText in pairs(skills["*"]) do
			name, _, _, _, _, _, endTime = UnitAura(unit, spell, nil, "HELPFUL")
			if name then
				if ignoreEndTime[spell] then
					return newText, 0
				else
					return newText, endTime or 0
				end
			end
		end
		-- 직업별 자체 생존기 체크
		if class and skills[class] then
			for spell, newText in pairs(skills[class]) do
				name, _, _, _, _, _, endTime = UnitAura(unit, spell, nil, "HELPFUL")
				if name then
					if ignoreEndTime[spell] then
						return newText, 0
					else
						return newText, endTime or 0
					end
				end
			end
		end
	end
	return nil
end

local function survivalSkill(object)
	survival, endTime = checkSkill(object.vehicleUnit or object.unit, object.class)
	if survival and IRF2.db.layout.showSurvivalSkill then
		-- 생존기가 있을 경우
		if object.survivalSkill ~= survival then
			object.survivalSkill = survival
			if endTime > 0 then
				object.survivalSkill_endTime = endTime
			else
				object.survivalSkill_endTime = nil
			end
			object:UpdateText()
			checkTotalSurvivalSkill()
		end
	elseif object.survivalSkill then
		-- 생존기가 없을 경우
		object.survivalSkill = nil
		object.survivalSkill_endTime = nil
		object:UpdateText()
		checkTotalSurvivalSkill()
	end
end

survivalSkillHandler:SetScript("OnEvent", function(self, event, unit)
	self.object = IRF2:GetUnitToObject(unit)
	if self.object then
		survivalSkill(self.object)
		if IRF2.units[unit] and IRF2.units[unit] ~= self.object then
			survivalSkill(IRF2.units[unit])
		end
	end
end)

local function survivalSkillMod(object)
	IRF2.objectModules["SurvivalSkill"] = nil
	survivalSkillHandler:RegisterEvent("UNIT_AURA")
	IRF2:RegisterAuraEvent("SurvivalSkill", survivalSkill)
end

IRF2:RegisterObjectModule("SurvivalSkill", survivalSkillMod)