local IRF2 = InvenRaidFrames2

local _G = _G
local pairs = _G.pairs
local ipairs = _G.ipairs
local select = _G.select
local GetSpellLink = _G.GetSpellLink
local GetSpellInfo = _G.GetSpellInfo
local InCombatLockdown = _G.InCombatLockdown
local GetActiveTalentGroup = _G.GetActiveTalentGroup

local maxButtons = 15
local clickAttributs = { "spell", "macro", "item" }
local modifilters = { "", "ALT-", "CTRL-", "SHIFT-", "ALT-CTRL-", "ALT-SHIFT-", "CTRL-SHIFT-" }
local clickCastingDefalut = { ["BUTTON1"] = "대상 선택", ["BUTTON2"] = "메뉴" }
local soulStoneItem = { 5232, 16892, 16893, 16985, 16896, 22116, 36895 }
local initObjects, soul, key, ccdb = {}

IRF2.numClickCastingButton = maxButtons

for _, key in ipairs(modifilters) do
	for i = 1, maxButtons do
		if clickCastingDefalut["BUTTON"..i] then
			clickCastingDefalut[key.."BUTTON"..i] = clickCastingDefalut["BUTTON"..i]
		end
	end
end

local function getSpellID(spell, rank)
	return tonumber((GetSpellLink(spell or "", rank) or ""):match("spell:(%d+)") or "")
end

local function getSpellMaxRank(spell)
	spell = getSpellID(spell)
	if spell then
		return tonumber((select(2, GetSpellInfo(spell)) or ""):match("(%d+)") or "")
	end
	return nil
end

local function getSpellName(spell)
	return GetSpellInfo(spell) or "*"
end

local spellLocale = {
	wildGrowth = getSpellName(48438),
	createSoulStone = getSpellName(693),
	soulStoneResurrection = getSpellName(20707),
	maxRank = "()",
	rank1 = "("..(select(2, GetSpellInfo(48438)) or "NONE")..")",
}

local handler = CreateFrame("Frame")

local function handlerOnEvent(self)
	if InCombatLockdown() then return end
	if self.talentGroup ~= GetActiveTalentGroup() then
		self.talentGroup = GetActiveTalentGroup() or 1
		if self.talentGroup == 2 then
			self.db = InvenRaidFrames2CharDB.clickCasting2
		else
			self.db = InvenRaidFrames2CharDB.clickCasting
		end
		IRF2:UpdateAllClickCasting()
	end
end

handler:SetScript("OnEvent", handlerOnEvent)
handler:RegisterEvent("PLAYER_TALENT_UPDATE")
handler:RegisterEvent("PLAYER_ENTERING_WORLD")
handler:RegisterEvent("PLAYER_REGEN_ENABLED")
handler:RegisterEvent("PLAYER_LOGIN")

local function setClick(object, modifier, button, ftype, value)
	modifier = modifier:lower()
	if ftype == "macro" then
		object:SetManyAttributes(modifier.."type"..button, ftype, modifier..ftype..button, value)
		object:SetSafeAttribute(modifier.."macrotext"..button, nil)
	elseif ftype == "macrotext" then
		object:SetManyAttributes(modifier.."type"..button, "macro", modifier..ftype..button, value)
		object:SetSafeAttribute(modifier.."macro"..button, nil)
	elseif ftype then
		object:SetManyAttributes(modifier.."type"..button, ftype, modifier..ftype..button, value)
	else
		object:SetManyAttributes(modifier.."type"..button, nil)
	end
end

function IRF2:SetClickCasting(object)
	if not initObjects[object] then
		initObjects[object] = true
		self:SetNewAttribute(object)
	end
	ccdb = GetActiveTalentGroup() == 2 and InvenRaidFrames2CharDB.clickCasting2 or InvenRaidFrames2CharDB.clickCasting
	for i = 1, maxButtons do
		for v, p in ipairs(modifilters) do
			key = p.."BUTTON"..i
			v = ccdb[key] or clickCastingDefalut[key] or "없음"
			if v == "없음" then
				setClick(object, p, i)
			elseif v == "대상 선택" then
				setClick(object, p, i, "target")
			elseif v == "메뉴" then
				setClick(object, p, i, "menu")
			elseif v == "살펴보기" then
				setClick(object, p, i, "macrotext", "/cleartarget\n/target [@mouseover]\n/run InspectUnit('target')")
			elseif v == "거래 요청" then
				setClick(object, p, i, "macrotext", "/run InitiateTrade('mouseover')")
			elseif v == "따라다니기" then
				setClick(object, p, i, "macrotext", "/run FollowUnit('mouseover')")
			elseif v == "대상 지원" then
				setClick(object, p, i, "macrotext", "/assist [@mouseover]")
			elseif v == "주시 대상 설정" then
				setClick(object, p, i, "macrotext", "/주시 [@mouseover]")
			elseif v == "귓속말 하기" then
				setClick(object, p, i, "macrotext", "/run ChatFrame_SendTell(GetUnitName('mouseover'))")
			elseif v == spellLocale.soulStoneResurrection or v == (spellLocale.soulStoneResurrection..spellLocale.maxRank) then
				-- 영혼석 부활
				soul = getSpellMaxRank(spellLocale.createSoulStone)
				if soul and soulStoneItem[soul] then
					setClick(object, p, i, "item", "item:"..soulStoneItem[soul])
				else
					setClick(object, p, i)
				end
			elseif v == spellLocale.wildGrowth or v == (spellLocale.wildGrowth..spellLocale.maxRank) or v == (spellLocale.wildGrowth..spellLocale.rank1) then
				-- 급속 성장
				setClick(object, p, i, "macrotext", "/cleartarget\n/cast [@mouseover] "..v.."\n/targetlasttarget")
			elseif v == "인벤 포커스 지정/해제" then
				setClick(object, p, i, "macrotext", "/run if InvenFocusFrames and InvenFocusFrames.SetTankerUnit then InvenFocusFrames:SetTankerUnit('mouseover', nil) end")
			elseif v:find("%[매크로%] ") then
				setClick(object, p, i, "macro", v:gsub("%[매크로%] ", ""))
			elseif v then
				setClick(object, p, i, "spell", v)
			else
				setClick(object, p, i)
			end
		end
	end
end

function IRF2:UpdateAllClickCasting()
	for object in pairs(initObjects) do
		self:SetClickCasting(object)
	end
end

function IRF2:GetClickCastingValue(talentGroup, key)
	key = key:upper()
	if talentGroup == 2 then
		return InvenRaidFrames2CharDB.clickCasting2[key] or clickCastingDefalut[key] or "없음"
	else
		return InvenRaidFrames2CharDB.clickCasting[key] or clickCastingDefalut[key] or "없음"
	end
end

function IRF2:SetClickCastingValue(talentGroup, key, value)
	key = key:upper()
	if clickCastingDefalut[key] == value then
		value = nil
	end
	if talentGroup == 2 then
		if InvenRaidFrames2CharDB.clickCasting2[key] ~= value then
			InvenRaidFrames2CharDB.clickCasting2[key] = value
			self:UpdateAllClickCasting()
		end
	else
		if InvenRaidFrames2CharDB.clickCasting[key] ~= value then
			InvenRaidFrames2CharDB.clickCasting[key] = value
			self:UpdateAllClickCasting()
		end
	end
end

IRF2:RegisterObjectHandler("ClickCasting", function(object)
	IRF2:SetClickCasting(object)
end)