local _G = _G
local type = _G.type
local pairs = _G.pairs
local ipairs = _G.ipairs
local tinsert = _G.table.insert
local saveValues = { "items", "itemsQuality", "ammo", "tradeSkill", "talents", "glyphs", "buffs", "stance" }

local LDM = LibStub("LibDropMenu-2.0")

local menu = { type = "group", args = {} }
LDM:RegisterMenu("InvenSimulatorProfileMenu", menu)

local function updateList()
	if InvenSimulatorUI:HasProfiles() then
		for p in pairs(menu.args.load.validate) do
			menu.args.load.validate[p] = nil
		end
		for name in pairs(InvenSimulatorCharDB.profiles) do
			tinsert(menu.args.load.validate, name)
		end
		sort(menu.args.load.validate)
		return nil
	end
	return true
end

local function showPopup(confirmType, profileName)
	if confirmType == "SAVE" then
		StaticPopupDialogs["INVEN_SIMULATOR_CONFIRM_PROFILE"].text = "정말 %s에 저장하시겠습니까?"
	elseif confirmType == "SAVEAS" then
		StaticPopupDialogs["INVEN_SIMULATOR_CONFIRM_PROFILE"].text = "%s|1은;는; 이미 존재하는 프로필입니다. 덮어쓰시겠습니까?"
	elseif confirmType == "LOAD" then
		StaticPopupDialogs["INVEN_SIMULATOR_CONFIRM_PROFILE"].text = "정말 %s|1을;를; 불러오시겠습니까?"
	elseif confirmType == "DELETE" then
		StaticPopupDialogs["INVEN_SIMULATOR_CONFIRM_PROFILE"].text = "정말 %s|1을;를; 삭제하시겠습니까?"
	else
		return
	end
	local dialog = StaticPopup_Show("INVEN_SIMULATOR_CONFIRM_PROFILE", profileName)
	if dialog then
		dialog.confirmType, dialog.profileName = confirmType, profileName
	end
end

menu.args.save = {
	type = "execute", name = "프로필 저장하기", desc = "현재 아이템 세팅을 저장합니다.", order = 10,
	func = function()
		showPopup("SAVE", InvenSimulatorCharDB.profile)
		LDM:CloseMenu(1)
	end,
	hidden = function() return not InvenSimulatorCharDB.profile end,
}

menu.args.saveas = {
	type = "text", name = "다른 이름으로 프로필 저장하기", order = 20,
	desc = "현재 아이템 세팅을 다른 이름의 프로필로 저장합니다. 이름 입력후 꼭 앤터키를 누르세요.",
	get = function() return "" end,
	set = function(new)
		new = new and new:trim()
		if new and new ~= "" then
			if InvenSimulatorCharDB.profiles[new] then
				showPopup("SAVEAS", new)
			else
				showPopup("SAVE", new)
			end
		end
		LDM:CloseMenu(1)
	end,
}

menu.args.load = {
	type = "text", name = "프로필 불러오기", desc = "저장된 프로필을 불러옵니다.", order = 30, validate = {}, hidden = updateList,
	set = function(name)
		showPopup("LOAD", name)
		LDM:CloseMenu(1)
	end,
}

menu.args.delete = {
	type = "text", name = "프로필 지우기", desc = "선택한 프로필을 지웁니다.", order = 40, validate = menu.args.load.validate,
	hidden = function() return not InvenSimulatorUI:HasProfiles() end,
	set = function(name)
		showPopup("DELETE", name)
		LDM:CloseMenu(1)
	end,
}

function InvenSimulatorUI:OpenProfileMenu(button)
	if LDM:IsOpen("InvenSimulatorProfileMenu") then
		LDM:CloseMenu(1)
	else
		LDM:OpenMenu("InvenSimulatorProfileMenu", "TOPLEFT", button, "BOTTOMLEFT", 0, 0)
	end
end

StaticPopupDialogs["INVEN_SIMULATOR_CONFIRM_PROFILE"] = {
	text = "", button1 = YES, button2 = NO, hideOnEscape = 1, timeout = 0, exclusive = 1, whileDead = 1,
	OnAccept = function(self)
		if self.confirmType == "SAVE" or self.confirmType == "SAVEAS" then
			InvenSimulatorUI:SaveProfile(self.profileName)
		elseif self.confirmType == "LOAD" then
			InvenSimulatorUI:LoadProfile(self.profileName)
		elseif self.confirmType == "DELETE" then
			InvenSimulatorUI:DeleteProfile(self.profileName)
		end
		InvenSimulatorUI:UpdateProfileName()
	end,
	OnCancel = function () end,
	OnHide = function(self)
		self.confirmType, self.profileName = nil, nil
	end,
}

function InvenSimulatorUI:UpdateProfileName()
	if self.db.profile then
		self.profileName:SetFormattedText("현재 프로필: %s", self.db.profile)
	else
		self.profileName:SetText("선택된 프로필 없음")
	end
end

function InvenSimulatorUI:HasProfiles()
	for p in pairs(self.db.profiles) do
		return true
	end
	return false
end

function InvenSimulatorUI:LoadProfile(name)
	if name and self.db.profiles[name] then
		for buff in pairs(InvenSimulatorUI.db.buffs) do
			self:SetEnableBuff(buff, nil)
		end
		for _, data in ipairs(saveValues) do
			if type(self.db.profiles[name][data]) == "table" then
				if type(self.db[data]) == "table" then
					for p in pairs(self.db[data]) do
						self.db[data][p] = nil
					end
				else
					self.db[data] = {}
				end
				for p, v in pairs(self.db.profiles[name][data]) do
					self.db[data][p] = v
				end
			else
				self.db[data] = self.db.profiles[name][data]
			end
		end
		self.db.profile = name
		for i = 1, 19 do
			self:SetItem(i, self.db.items[i], nil, nil)
		end
		self:ModelUpdate()
		self:ScanItem()
		for buff, value in pairs(InvenSimulatorUI.db.buffs) do
			self:SetEnableBuff(buff, value)
		end
	end
end

function InvenSimulatorUI:SaveProfile(name)
	if name then
		self.db.profiles[name] = self.db.profiles[name] or {}
		for _, data in ipairs(saveValues) do
			if type(self.db[data]) == "table" then
				if type(self.db.profiles[name][data]) == "table" then
					for p in pairs(self.db.profiles[name][data]) do
						self.db.profiles[name][data][p] = nil
					end
				else
					self.db.profiles[name][data] = {}
				end
				for p, v in pairs(self.db[data]) do
					self.db.profiles[name][data][p] = v
				end
			else
				self.db.profiles[name][data] = self.db[data]
			end
		end
		self.db.profile = name
	end
end

function InvenSimulatorUI:DeleteProfile(name)
	if name and self.db.profiles[name] then
		self.db.profiles[name] = nil
		if self.db.profile == name then
			self.db.profile = nil
		end
	end
end