local IRF2 = InvenRaidFrames2
local Option = IRF2.optionFrame
local LBO = LibStub("LibBlueOption-1.0")
local SM = LibStub("LibSharedMedia-3.0")

local _G = _G
local pairs = _G.pairs
local ipairs = _G.ipairs
local unpack = _G.unpack
local InCombatLockdown = _G.InCombatLockdown
local UnitAffectingCombat = _G.UnitAffectingCombat

function Option:CreateProfileMenu(menu, parent)
	local profiles = {}
	local function disable()
		return StaticPopup_Visible("INVENRAIDFRAMES2_NEW_PROFILE") or StaticPopup_Visible("INVENRAIDFRAMES2_DELETE_PROFILE") or StaticPopup_Visible("INVENRAIDFRAMES2_APPLY_PROFILE")
	end
	local function getTargetProfile()
		if menu.list:GetValue() then
			menu.targetProfile = profiles[menu.list:GetValue()]
		else
			menu.targetProfile = nil
		end
		return menu.targetProfile
	end
	menu.current = parent:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
	menu.current:SetPoint("TOPLEFT", 5, -5)
	menu.current:SetText("현재 프로필: |cffffffff"..(IRF2.baseDB.profileKeys[IRF2.playerProfile] or "기본값"))
	menu.list = LBO:CreateWidget("List", parent, "프로필 목록", nil, nil, disable, nil,
		function()
			return Option:ConvertTable(IRF2.baseDB.profiles, profiles), true
		end,
		function(v)
			getTargetProfile()
			menu.apply:Update()
			menu.delete:Update()
		end
	)
	menu.list:SetPoint("TOPLEFT", menu.current, "BOTTOMLEFT", 0, -10)
	menu.list:HookScript("OnHide", function()
		StaticPopup_Hide("INVENRAIDFRAMES2_NEW_PROFILE")
		StaticPopup_Hide("INVENRAIDFRAMES2_DELETE_PROFILE")
		StaticPopup_Hide("INVENRAIDFRAMES2_APPLY_PROFILE")
	end)
	menu.apply = LBO:CreateWidget("Button", parent, "현재 캐릭터에 프로필 적용", "현재 캐릭터에 선택된 프로필을 적용합니다.", nil,
		function()
			if disable() then
				return true
			elseif getTargetProfile() then
				if menu.targetProfile == IRF2.dbName then
					return true
				else
					return nil
				end
			else
				return true
			end
		end, true,
		function()
			StaticPopup_Show("INVENRAIDFRAMES2_APPLY_PROFILE", getTargetProfile())
		end
	)
	menu.apply:SetPoint("TOPLEFT", menu.list, "BOTTOMLEFT", 0, 12)
	menu.apply:SetPoint("TOPRIGHT", menu.list, "BOTTOMRIGHT", 0, 12)
	menu.create = LBO:CreateWidget("Button", parent, "새 프로필 만들기", "현재 선택된 프로필을 기초로 하여 새로운 프로필을 생성하고 현재 캐릭터에 적용합니다. 프로필을 선택하지 않았다면 초기값 상태로 새로운 프로필을 생성합니다.", nil, disable, true,
		function()
			getTargetProfile()
			StaticPopup_Show("INVENRAIDFRAMES2_NEW_PROFILE")
		end
	)
	menu.create:SetPoint("TOPLEFT", menu.apply, "BOTTOMLEFT", 0, 20)
	menu.create:SetPoint("TOPRIGHT", menu.apply, "BOTTOMRIGHT", 0, 20)

	menu.delete = LBO:CreateWidget("Button", parent, "프로필 삭제", "현재 선택된 프로필을 삭제합니다.", nil,
		function()
			if disable() then
				return true
			elseif getTargetProfile() then
				if menu.targetProfile == "기본값" or menu.targetProfile == IRF2.dbName then
					return true
				else
					return nil
				end
			else
				return true
			end
		end, true,
		function()
			StaticPopup_Show("INVENRAIDFRAMES2_DELETE_PROFILE", getTargetProfile())
		end
	)
	menu.delete:SetPoint("TOPLEFT", menu.create, "BOTTOMLEFT", 0, 20)
	menu.delete:SetPoint("TOPRIGHT", menu.create, "BOTTOMRIGHT", 0, 20)
	local function togglePopup()
		menu.list:Update()
		menu.apply:Update()
		menu.delete:Update()
		LBO:Refresh(parent)
	end
	local function checkCombat(self)
		if UnitAffectingCombat("player") or InCombatLockdown() then
			self:Hide()
		end
	end
	StaticPopupDialogs["INVENRAIDFRAMES2_NEW_PROFILE"] = {
		text = "새로운 프로필을 작성합니다.\n새 프로필 이름을 입력해주세요",
		button1 = OKAY, button2 = CANCEL, hideOnEscape = 1, timeout = 0, exclusive = 1, whileDead = 1, hasEditBox = 1, maxLetters = 32, showAlert = 1,
		OnUpdate = checkCombat, OnHide = togglePopup,
		OnAccept = function(self)
			local name = (self.editBox:GetText() or ""):trim()
			if name ~= "" then
				if IRF2.baseDB.profiles[name] then
					IRF2:Message(("[|cff8080ff%s|r] 이미 존재하는 프로필입니다."):format(name))
				elseif Option:NewProfile(name, menu.targetProfile) then
					if IRF2.baseDB.profiles[name] then
						menu.current:SetText("현재 프로필: |cffffffff"..name)
						IRF2:Message(("[|cff8080ff%s|r] 새로운 프로필이 생성되고 적용되었습니다."):format(name))
					else
						IRF2:Message("새로운 프로필 생성에 실패했습니다.")
					end
				else
					IRF2:Message("새로운 프로필 생성에 실패했습니다.")
				end
			end
		end,
		OnShow = function(self)
			self.button1:Disable()
			self.button2:Enable()
			self.editBox:SetText("")
			self.editBox:SetFocus()
			togglePopup()
		end,
		EditBoxOnTextChanged = function(self)
			if (self:GetParent().editBox:GetText() or ""):trim() ~= "" then
				self:GetParent().button1:Enable()
			else
				self:GetParent().button1:Disable()
			end
		end,
		EditBoxOnEscapePressed = function(self)
			self:GetParent():Hide()
		end,
		EditBoxOnEnterPressed = function(self)
			if (self:GetParent().editBox:GetText() or ""):trim() ~= "" then
				self:GetParent().button1:Click()
			end
		end,
	}
	StaticPopupDialogs["INVENRAIDFRAMES2_DELETE_PROFILE"] = {
		text = "'%s' 프로필을 삭제합니다.\n정말 삭제하시겠습니까?",
		button1 = YES, button2 = NO, hideOnEscape = 1, timeout = 0, exclusive = 1, whileDead = 1, showAlert = 1,
		OnUpdate = checkCombat, OnShow = togglePopup, OnHide = togglePopup,
		OnAccept = function(self)
			IRF2.baseDB.profiles[menu.targetProfile] = nil
			for p, v in pairs(IRF2.baseDB.profileKeys) do
				if v == menu.targetProfile then
					IRF2.baseDB.profileKeys[p] = nil
				end
			end
			IRF2:Message(("[|cff8080ff%s|r] 프로필이 삭제되었습니다."):format(menu.targetProfile))
		end,
	}
	StaticPopupDialogs["INVENRAIDFRAMES2_APPLY_PROFILE"] = {
		text = "현재 캐릭터에 '%s' 프로필을 적용하시겠습니까?",
		button1 = YES, button2 = NO, hideOnEscape = 1, timeout = 0, exclusive = 1, whileDead = 1, showAlert = 1,
		OnUpdate = checkCombat, OnShow = togglePopup, OnHide = togglePopup,
		OnAccept = function(self)
			menu.current:SetText("현재 프로필: |cffffffff"..(menu.targetProfile or "기본값"))
			IRF2:SetProfile(menu.targetProfile)
			Option:UpdateAllOptions()
			IRF2:Message(("[|cff8080ff%s|r] 프로필이 현재 캐릭터에 적용되었습니다."):format(menu.targetProfile))
		end,
	}
end

local statusBars = { "health", "mana", "heal", "resCastingBar", "castingBar" }
local centerPos = { CENTER = "RIGHT", TOP = "TOPRIGHT", BOTTOM = "BOTTOMRIGHT" }
local pos, prev_r, prev_g, prev_b

function Option:NewProfile(profile1, profile2)
	if type(profile1) == "string" and not InvenRaidFrames2DB.profiles[profile1] then
		if type(profile2) == "string" and InvenRaidFrames2DB.profiles[profile2] then
			InvenRaidFrames2DB.profiles[profile1] = CopyTable(InvenRaidFrames2DB.profiles[profile2])
		end
		IRF2:SetProfile(profile1)
		Option:UpdateAllOptions()
		return true
	end
	return nil

end

function Option:UpdateAllOptions()
	if IRF2.db.use == "사용 안함" then
		IRF2.db.run = false
	else
		IRF2.db.run = true
		IRF2.db.shown = IRF2.db.use
	end
	IRF2.anchor:ClearAllPoints()
	IRF2.anchor:SetPoint(IRF2.db.pos[1], UIParent, IRF2.db.pos[1], IRF2.db.pos[2], IRF2.db.pos[3])
	IRF2.anchor:SetScale(IRF2.db.layout.scale)
	if IRF2.borderFrame then
		IRF2.borderFrame:SetScale(IRF2.db.layout.scale)
	end
	if IRF2.group.pet then
		IRF2.petAnchor:ClearAllPoints()
		IRF2.petAnchor:SetPoint(IRF2.db.pet.pos[1], UIParent, IRF2.db.pet.pos[1], IRF2.db.pet.pos[2], IRF2.db.pet.pos[3])
		IRF2.petAnchor:SetScale(IRF2.db.pet.scale)
		IRF2.group.pet:SetScale(IRF2.db.pet.scale)
	end
	if IRF2.borderFramePet then
		IRF2.borderFramePet:SetScale(IRF2.db.pet.scale)
	end
	for i = 0, 8 do
		IRF2.group[i].partyTag:ClearAllPoints()
		IRF2.group[i].partyTag1:ClearAllPoints()
		if IRF2.db.anchor == "좌측 상단" then
			IRF2.group[i].partyTag:SetPoint("BOTTOM", IRF2.group[i], "TOP", 0, 0)
			IRF2.group[i].partyTag1:SetPoint("RIGHT", IRF2.group[i], "LEFT", 0, 0)
		elseif IRF2.db.anchor == "우측 상단" then
			IRF2.group[i].partyTag:SetPoint("BOTTOM", IRF2.group[i], "TOP", 0, 0)
			IRF2.group[i].partyTag1:SetPoint("LEFT", IRF2.group[i], "RIGHT", 0, 0)
		elseif IRF2.db.anchor == "좌측 하단" then
			IRF2.group[i].partyTag:SetPoint("TOP", IRF2.group[i], "BOTTOM", 0, 0)
			IRF2.group[i].partyTag1:SetPoint("RIGHT", IRF2.group[i], "LEFT", 0, 0)
		elseif IRF2.db.anchor == "우측 하단" then
			IRF2.group[i].partyTag:SetPoint("TOP", IRF2.group[i], "BOTTOM", 0, 0)
			IRF2.group[i].partyTag1:SetPoint("LEFT", IRF2.group[i], "RIGHT", 0, 0)
		end
		IRF2.group[i]:SetScale(IRF2.db.layout.scale)
		IRF2.group[i].partyTag:SetWidth(IRF2.db.layout.width)
		IRF2.group[i].partyTag1:SetHeight(IRF2.db.layout.height)
		IRF2.group[i].partyTag:SetBackdropColor(unpack(IRF2.db.partyTagColor[i]))
		IRF2.group[i].partyTag1:SetBackdropColor(unpack(IRF2.db.partyTagColor[i]))
	end
	IRF2:SetFont(IRF2.tempText)
	for _, object in pairs(IRF2.objects) do
		object:SetManyAttributes("initial-width", IRF2.db.layout.width, "initial-height", IRF2.db.layout.height)
		object:SetWidth(IRF2.db.layout.width)
		object:SetHeight(IRF2.db.layout.height)
		for i = 1, #statusBars do
			if object[statusBars[i]] then
				prev_r, prev_g, prev_b = object[statusBars[i]]:GetStatusBarColor()
				object[statusBars[i]]:SetStatusBarTexture(SM:Fetch("statusbar", IRF2.db.layout.texture))
				object[statusBars[i]]:SetStatusBarColor(prev_r, prev_g, prev_b)
			end
		end
		if object.health then
			object.health:ClearAllPoints()
			object.mana:ClearAllPoints()
			if IRF2.db.layout.manaBar == 0 then
				object.health:SetAllPoints(object)
				object.mana:SetPoint("TOPLEFT", object, "BOTTOMLEFT")
				object.mana:SetPoint("BOTTOMRIGHT", object, "BOTTOMRIGHT")
			elseif IRF2.db.layout.manaBar == 1 then
				object.health:SetPoint("TOPLEFT", object, "TOPLEFT")
				object.health:SetPoint("BOTTOMRIGHT", object, "TOPRIGHT")
				object.mana:SetAllPoints(object)
			else
				object.health:SetPoint("TOPLEFT", object, "TOPLEFT")
				object.health:SetPoint("BOTTOMRIGHT", object, "BOTTOMRIGHT", 0, IRF2.db.layout.height * IRF2.db.layout.manaBar)
				object.mana:SetPoint("TOPLEFT", object, "TOPLEFT", 0, -(IRF2.db.layout.height * (1 - IRF2.db.layout.manaBar) + 1))
				object.mana:SetPoint("BOTTOMRIGHT", object, "BOTTOMRIGHT")
			end
			object.health:SetOrientation(IRF2.db.layout.healthOrientation == "세로" and "VERTICAL" or "HORIZONTAL")
		end
		if object.mana then
			if IRF2.db.layout.outRangeAlphaMana then
				object.mana:SetAlpha(object.inRange and 1 or IRF2.db.layout.outRangeAlpha)
			else
				object.mana:SetAlpha(1)
			end
		end
		if object.heal then
			object.heal:SetOrientation(IRF2.db.layout.healthOrientation == "세로" and "VERTICAL" or "HORIZONTAL")
			object.heal:SetAlpha(IRF2.db.heal.barAlpha)
			if object.heal.icon then
				object.heal.iconFrame:SetFrameLevel(IRF2.db.frameLevel.healIcon)
				pos = IRF2:GetFramePoint(IRF2.db.heal.pos)
				object.heal.icon:ClearAllPoints()
				object.heal.icon:SetPoint(pos[1], object, pos[1], pos[2], pos[3])
			end
		end
		if object.text then
			IRF2:SetFont(object.text)
		end
		if object.textFrame then
			object.textFrame:SetFrameLevel(IRF2.db.frameLevel.name)
			if IRF2.db.layout.outRangeAlphaName then
				object.textFrame:SetAlpha(object.inRange and 1 or IRF2.db.layout.outRangeAlpha)
			else
				object.textFrame:SetAlpha(1)
			end
		end
		if object.initUnit then
			object:SetBackdropColor(unpack(IRF2.db.layout.backdropColor))
			if object.UpdateOutline then
				object:UpdateOutline()
			end
		end
		if not object.inRange then
			if object.health then
				object.health:SetAlpha(IRF2.db.layout.outRangeAlpha)
			end
			if object.mana then
				if IRF2.db.layout.outRangeAlphaMana then
					object.mana:SetAlpha(IRF2.db.layout.outRangeAlpha)
				end
			end
			if object.text then
				if IRF2.db.layout.outRangeAlphaName then
					object.text:SetAlpha(IRF2.db.layout.outRangeAlpha)
				end
			end
		end
		if object.buffFrame then
			object.buffFrame:SetFrameLevel(IRF2.db.frameLevel.buffCheck)
			pos = IRF2:GetFramePoint(IRF2.db.buffCheck.pos)[1]
			object.buffFrame:ClearAllPoints()
			object.buffFrame:SetPoint(pos, object, pos)
			object.buffFrame:SetHeight(IRF2.db.buffCheck.size)
			if object.buffFrame[1] then
				for j = 1, #object.buffFrame do
					object.buffFrame[j]:SetHeight(IRF2.db.buffCheck.size)
				end
			end
		end
		if object.debuffFrame then
			object.debuffFrame:SetFrameLevel(IRF2.db.frameLevel.debuff)
			pos = IRF2:GetFramePoint(IRF2.db.debuff.pos)[1]
			object.debuffFrame:ClearAllPoints()
			object.debuffFrame:SetPoint(pos, object, pos)
			if object.debuffFrame[1] then
				for i = 1, #object.debuffFrame do
					object.debuffFrame[i].color:ClearAllPoints()
					object.debuffFrame[i].icon:ClearAllPoints()
					if IRF2.db.debuff.iconType == "아이콘" then
						object.debuffFrame[i].color:SetAllPoints(object.debuffFrame[i])
						object.debuffFrame[i].color:Hide()
						object.debuffFrame[i].icon:SetAllPoints(object.debuffFrame[i])
						object.debuffFrame[i].icon:Show()
					elseif IRF2.db.debuff.iconType == "색상" then
						object.debuffFrame[i].color:SetPoint("TOPLEFT", object.debuffFrame[i], "TOPLEFT", 1, -1)
						object.debuffFrame[i].color:SetPoint("BOTTOMRIGHT", object.debuffFrame[i], "BOTTOMRIGHT", -1, 1)
						object.debuffFrame[i].color:Show()
						object.debuffFrame[i].icon:SetAllPoints(object.debuffFrame[i])
						object.debuffFrame[i].icon:Hide()
					else
						object.debuffFrame[i].color:SetAllPoints(object.debuffFrame[i])
						object.debuffFrame[i].color:Show()
						object.debuffFrame[i].icon:SetPoint("TOPLEFT", object.debuffFrame[i], "TOPLEFT", 1, -1)
						object.debuffFrame[i].icon:SetPoint("BOTTOMRIGHT", object.debuffFrame[i], "BOTTOMRIGHT", -1, 1)
						object.debuffFrame[i].icon:Show()
					end
					object.debuffFrame[i]:SetWidth(IRF2.db.debuff.size)
					object.debuffFrame[i]:SetHeight(IRF2.db.debuff.size)
				end
			end
		end
		if object.userDebuff then
			object.userDebuff:SetFrameLevel(IRF2.db.frameLevel.userDebuff)
			object.userDebuff:SetWidth(IRF2.db.userDebuff.size)
			object.userDebuff:SetHeight(IRF2.db.userDebuff.size)
			object.userDebuff:SetAlpha(IRF2.db.userDebuff.alpha)
			if IRF2.db.userDebuff.pos ~= "표시 안함" then
				pos = IRF2:GetFramePoint(IRF2.db.userDebuff.pos)
				object.userDebuff:ClearAllPoints()
				object.userDebuff:SetPoint(pos[1], object, pos[1], pos[2], pos[3])
				if (IRF2.db.userDebuff.pos or ""):find("우측") then
					object.userDebuff.text:SetPoint("RIGHT", object.userDebuff, "LEFT", 3, 0)
				else
					object.userDebuff.text:SetPoint("LEFT", object.userDebuff, "RIGHT", -3, 0)
				end
			end
		end
		if object.bossModFrame then
			object.bossModFrame:SetFrameLevel(IRF2.db.frameLevel.userDebuff + 1)
		end
		if object.castingBar then
			object.castingBar:SetFrameLevel(IRF2.db.frameLevel.castingBar)
			object.castingBar:SetStatusBarColor(unpack(IRF2.db.castingBar.color))
			object.castingBar:ClearAllPoints()
			if IRF2.db.castingBar.pos == "상단" then
				object.castingBar:SetPoint("TOPLEFT", object, "TOPLEFT", 0, 0)
				object.castingBar:SetPoint("BOTTOMRIGHT", object, "TOPRIGHT", 0, -IRF2.db.castingBar.height)
				object.castingBar:SetOrientation("HORIZONTAL")
			elseif IRF2.db.castingBar.pos == "하단" then
				object.castingBar:SetPoint("TOPLEFT", object, "BOTTOMLEFT", 0, IRF2.db.castingBar.height)
				object.castingBar:SetPoint("BOTTOMRIGHT", object, "BOTTOMRIGHT", 0, 0)
				object.castingBar:SetOrientation("HORIZONTAL")
			elseif IRF2.db.castingBar.pos == "좌측" then
				object.castingBar:SetPoint("TOPLEFT", object, "TOPLEFT", 0, 0)
				object.castingBar:SetPoint("BOTTOMRIGHT", object, "BOTTOMLEFT", IRF2.db.castingBar.height, 0)
				object.castingBar:SetOrientation("VERTICAL")
			elseif IRF2.db.castingBar.pos == "우측" then
				object.castingBar:SetPoint("TOPLEFT", object, "TOPRIGHT", -IRF2.db.castingBar.height, 0)
				object.castingBar:SetPoint("BOTTOMRIGHT", object, "BOTTOMRIGHT", 0, 0)
				object.castingBar:SetOrientation("VERTICAL")
			end
		end
		if object.resCastingBar then
			object.resCastingBar:SetFrameLevel(IRF2.db.frameLevel.resCastingBar)
		end
		if object.spellTimer then
			for j = 1, 4 do
				if object.spellTimer[j] then
					object.spellTimer[j]:SetFrameLevel(IRF2.db.frameLevel.spellTimer)
				end
			end
		end
		if object.userSpellTimer then
			for j = 1, #IRF2.charDB.userSpellTimer.auraTypes do
				if object.userSpellTimer[j] then
					object.userSpellTimer[j]:SetFrameLevel(IRF2.db.frameLevel.spellTimer)
				end
			end
		end
		if object.raidIcon then
			object.raidIconFrame:SetFrameLevel(IRF2.db.frameLevel.raidIcon)
			pos = IRF2:GetFramePoint(IRF2.db.raidIcon.pos)[1]
			object.raidIcon:ClearAllPoints()
			object.raidIcon2:ClearAllPoints()
			if IRF2.db.raidIcon.showTarget then
				if centerPos[pos] then
					object.raidIcon:SetPoint(centerPos[pos], object, pos)
					object.raidIcon2:SetPoint(reversePos[centerPos[pos]], object, pos)
				else
					object.raidIcon:SetPoint(pos, object, pos)
					object.raidIcon2:SetPoint(pos, object.raidIcon, reversePos[pos])
				end
			else
				object.raidIcon:SetPoint(pos, object, pos)
				object.raidIcon2:Hide()
			end
			object.raidIcon:SetWidth(IRF2.db.raidIcon.size)
			object.raidIcon:SetHeight(IRF2.db.raidIcon.size)
			object.raidIcon2:SetWidth(IRF2.db.raidIcon.size)
			object.raidIcon2:SetHeight(IRF2.db.raidIcon.size)
		end
		if object.readyCheck then
			object.readyCheck:SetFrameLevel(IRF2.db.frameLevel.readyCheck)
		end
	end

	IRF2.highlightFrame:SetAlpha(IRF2.db.highlightFrameAlpha)
	if IRF2.db.outline == "대상" then
		IRF2:RegisterEvent("PLAYER_TARGET_CHANGED")
	else
		IRF2:UnregisterEvent("PLAYER_TARGET_CHANGED")
	end

	IRF2:UpdateClampRectInsets()
	if IRF2.group.pet then
		IRF2:UpdatePetClampRectInsets()
		IRF2:SetPetGroupOrder()
	end
	if IRF2.borderFrame then
		IRF2.borderFrame:SetBackdropColor(unpack(IRF2.db.border.backdrop))
		IRF2.borderFrame:SetBackdropBorderColor(unpack(IRF2.db.border.border))
	end
	if IRF2.borderFramePet then
		IRF2.borderFramePet:SetBackdropColor(unpack(IRF2.db.border.backdrop))
		IRF2.borderFramePet:SetBackdropBorderColor(unpack(IRF2.db.border.border))
	end
	IRF2:SetGroupPosition()
	IRF2:UpdatePartyTag()
	IRF2:Toggle()
	IRF2:UpdateAllUnits()
	IRF2:UseUnitTargetIcon()
	if IRF2.IncomingHeals then
		IRF2:IncomingHeals()
	end
	IRF2:CallbackTimer("Border", 0.1, IRF2, "UpdateBorder")
	IRF2:CallbackTimer("PetBorder", 0.1, IRF2, "BorderPet")
	collectgarbage()
end