local _G = _G
local type = _G.type
local pairs = _G.pairs
local tinsert = _G.table.insert
local GetItemInfo = _G.GetItemInfo

local core = InvenSimulatorUI
local si = CreateFrame("Frame", "InvenSimulatorSaveItemFrame", UIParent, "UIPanelDialogTemplate")
si:Hide()
si:SetFrameStrata(core:GetFrameStrata())
si:SetToplevel(true)

local itemLoc, num, offset, item, listIndex, cursorItemLink

local function fixLink(link)
	local prefix, id, eid, jid1, jid2, jid3, jid4, sid, _, _, suffix = link:match("^(.+)item:(%d+):(%d+):(%d+):(%d+):(%d+):(%d+):(.+):(.+):(%d+)(.+)$")
	if prefix then
		return ("%sitem:%d:%d:%d:%d:%d:%d:%s:0:%d%s"):format(prefix, id, eid, jid1, jid2, jid3, jid4, sid, InvenSimulatorUI.level, suffix)
	else
		return nil
	end
end

function si:SaveItem(link, update)
	if type(link) == "string" and link:find("item:") then
		link, _, _, _, _, _, _, itemLoc = select(2, GetItemInfo(link))
		if link and itemLoc and itemLoc ~= "" and itemLoc:find("^INVTYPE_") and _G[itemLoc] then
			link = fixLink(link)
			if link then
				itemLoc = _G[itemLoc]
				if InvenSimulatorCharDB.saveItem[itemLoc] and InvenSimulatorCharDB.saveItem[itemLoc][link] then
					return nil
				else
					if update then
						InvenSimulatorCharDB.saveItem[itemLoc] = InvenSimulatorCharDB.saveItem[itemLoc] or {}
						InvenSimulatorCharDB.saveItem[itemLoc][link] = true
						self.filter = itemLoc
						self:Refresh()
					end
					return true
				end
			else
				return nil
			end
		end
	end
end

function si:DeleteItem(link)
	if type(link) == "string" and link:find("item:") then
		for loc in pairs(InvenSimulatorCharDB.saveItem) do
			InvenSimulatorCharDB.saveItem[loc][link] = nil
		end
		if self.selected == link then
			self.selected = nil
		end
		self:Refresh()
	end
end

function si:Refresh()
	if not self.container then return end
	if self.filter == nil then
		self.filter = InvenSimulatorCharDB.saveItemFilter
	end
	if self.list then
		for p in pairs(self.list) do
			self.list[p] = nil
		end
	else
		self.list = {}
	end
	for p in pairs(self.locList) do
		self.locList[p] = nil
	end
	for loc, list in pairs(InvenSimulatorCharDB.saveItem) do
		for item in pairs(list) do
			tinsert(self.locList, loc)
			break
		end
	end
	if #self.locList == 1 then
		self.filter = self.locList[1]
	else
		sort(self.locList)
		tinsert(self.locList, 1, "모두")
		if self.filter == nil then
			self.filter = "모두"
		end
	end
	local chk = true
	for _, v in pairs(self.locList) do
		if self.filter == v then
			chk = nil
			break
		end
	end
	if chk then
		self.filter = self.locList[1]
	end
	if self.filter == "모두" then
		for loc, list in pairs(InvenSimulatorCharDB.saveItem) do
			for item in pairs(list) do
				tinsert(self.list, item)
			end
		end
	elseif InvenSimulatorCharDB.saveItem[self.filter] then
		for item in pairs(InvenSimulatorCharDB.saveItem[self.filter]) do
				tinsert(self.list, item)
		end
	end
	sort(self.list, function(a, b)
		a, b = GetItemInfo(a) or GetItemIcon(a), GetItemInfo(b) or GetItemIcon(b)
		if a and b then
			return a < b
		elseif a then
			return false
		else
			return true
		end
	end)
	UIDropDownMenu_Initialize(self.filterDropdown, self.filterDropdown.Initialize)
	UIDropDownMenu_SetSelectedValue(self.filterDropdown, self.filter)
	self:UpdateScroll()
	InvenSimulatorCharDB.saveItemFilter = self.filter
end

function si:UpdateScroll()
	self = si
	GameTooltip:Hide()
	self.delete:Disable()
	num, offset = ceil(#self.list / 4), HybridScrollFrame_GetOffset(self.container)
	if num > 0 then
		for i, group in ipairs(self.container.buttons) do
			if self.list[(offset + i) * 4 - 3] then
				for j = 1, 4 do
				--for j = (offset + i) * 4 - 3, (offset + i) * 4 do
					listIndex = (offset + i - 1) * 4 + j
					item = self.list[listIndex]
					if item then
						group.items[j].icon:SetTexture(GetItemIcon(item))
						group.items[j].item = item
						group.items[j]:SetID(listIndex)
						if self.selected == item then
							self.delete:Enable()
							group.items[j]:SetChecked(true)
						else
							group.items[j]:SetChecked(nil)
						end
						group.items[j]:Show()
						if GetMouseFocus() == group.items[j] then
							group.items[j]:GetScript("OnEnter")(group.items[j])
						end
					else
						group.items[j]:Hide()
					end
				end
				group:Show()
			else
				group:Hide()
			end
		end
	else
		for i, group in ipairs(self.container.buttons) do
			group:Hide()
		end
	end
	HybridScrollFrame_Update(self.container, num * 40, #self.container.buttons * 40)
end

function si:CreateFrame()
	self.levelElements = {}
	self.locList = {}
	self.title:SetText("인벤 시뮬레이터 - 아이템 저장소")
	InvenSimulatorCharDB.saveItemPos = InvenSimulatorCharDB.saveItemPos or { "CENTER", 0, 0 }
	self:SetScript("OnShow", self.Refresh)
	self:EnableMouse(true)
	self:SetClampedToScreen(true)
	self:SetMovable(true)
	self:RegisterForDrag("LeftButton")
	self:SetScript("OnDragStart", self.StartMoving)
	self:SetScript("OnDragStop", function(self)
		self:StopMovingOrSizing()
		InvenSimulatorUI.db.saveItemPos[1], _, _, InvenSimulatorUI.db.saveItemPos[2], InvenSimulatorUI.db.saveItemPos[3] = self:GetPoint()
	end)
	self:SetWidth(210)
	self:SetHeight(231)
	self:SetPoint(unpack(InvenSimulatorCharDB.saveItemPos))
	self.levelElements[InvenSimulatorSaveItemFrameClose] = 1
	self.delete = CreateFrame("Button", nil, self, "UIPanelButtonTemplate")
	self.levelElements[self.delete] = 1
	self.delete:SetPoint("TOPRIGHT", -6, -28)
	self.delete:SetWidth(60)
	self.delete:SetHeight(20)
	self.delete:SetText("삭제")
	self.delete:SetScript("OnClick", function()
		si:DeleteItem(si.selected)
	end)

	local dropdownFunc = function(self)
		si.filter = self.value
		UIDropDownMenu_SetSelectedValue(self.owner, self.value)
		si:Refresh()
	end
	local dropdownInitialize = function(self)
		local info = UIDropDownMenu_CreateInfo()
		for _, text in ipairs(si.locList) do
			info.text = text
			info.value = value
			info.func = self.func
			info.owner = UIDROPDOWNMENU_OPEN_MENU
			info.checked = self.filter == text and 1 or nil
			UIDropDownMenu_AddButton(info)
		end
	end
	self.filterDropdown = CreateFrame("Frame", "InvenSimulatorSaveItemFrameFilter", self, "UIDropDownMenuTemplate")
	self.levelElements[self.filterDropdown] = 1
	self.filterDropdown:SetID(1)
	self.filterDropdown:EnableMouse(true)
	self.filterDropdown:SetPoint("RIGHT", self.delete, "LEFT", 12, -4)
	UIDropDownMenu_SetWidth(self.filterDropdown, 110)
	UIDropDownMenu_JustifyText(self.filterDropdown, "LEFT")
	self.filterDropdown.func = dropdownFunc
	self.filterDropdown.Initialize = dropdownInitialize
	local frameOnMouseDown = function(_, button)
		if button == "LeftButton" then
			cursorItemLink = InvenSimulatorUI:GetCursorItemLink()
			if cursorItemLink and cursorItemLink == core:GetEquipableLink() then
				si:SaveItem(cursorItemLink, true)
			end
		end
		ClearCursor()
	end
	local frameOnReceiveDrag = function()
		frameOnMouseDown(nil, "LeftButton")
	end
	self:SetScript("OnMouseUp", frameOnMouseDown)
	self:SetScript("OnReceiveDrag", frameOnReceiveDrag)
	self.container = CreateFrame("ScrollFrame", "InvenSimulatorSaveItemFrameContainer", self, "HybridScrollFrameTemplate")
	self.levelElements[self.container] = 1
	self.container:SetPoint("TOPLEFT", 10, -56)
	self.container:SetPoint("BOTTOMRIGHT", -28, 13)
	self.container:SetScript("OnMouseUp", frameOnMouseDown)
	self.container:SetScript("OnReceiveDrag", frameOnReceiveDrag)
	self.container.scrollBar = CreateFrame("Slider", "InvenSimulatorSaveItemFrameContainerScrollBar", self.container, "HybridScrollBarTemplate")
	self.levelElements[self.container.scrollBar] = 2
	self.container.scrollBar:SetPoint("TOPLEFT", self.container, "TOPRIGHT", 0, -12)
	self.container.scrollBar:SetPoint("BOTTOMLEFT", self.container, "BOTTOMRIGHT", 0, 11)
	self.container.buttons = {}
	local numButtons = ceil(self.container:GetHeight() / 40) + 1
	local realNum, button = 0
	local itemButtonOnEnter = function(self)
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
		GameTooltip:SetHyperlink(self.item)
		GameTooltip:Show()
	end
	local itemButtonOnClick = function(self, button)
		if button == "LeftButton" then
			if si.selected == self.item then
				si.selected = nil
			else
				si.selected = self.item
			end
			si:UpdateScroll()
		end
	end
	for i = 1, numButtons do
		self.container.buttons[i] = CreateFrame("Frame", "InvenSimulatorSaveItemFrameItemGroup"..i, self.container.scrollChild)
		self.levelElements[self.container.buttons[i]] = 2
		if i == 1 then
			self.container.buttons[i]:SetPoint("TOPLEFT", 5, -2)
		else
			self.container.buttons[i]:SetPoint("TOPLEFT", self.container.buttons[i - 1], "BOTTOMLEFT", 0, 0)
		end
		self.container.buttons[i]:SetWidth(self.container:GetWidth())
		self.container.buttons[i]:SetHeight(40)
		self.container.buttons[i].items = {}
		for j = 1, 4 do
			realNum = realNum + 1
			self.container.buttons[i].items[j] = CreateFrame("CheckButton", "InvenSimulatorSaveItemFrameItemButton"..realNum, self.container.buttons[i], "PopupButtonTemplate")
			self.levelElements[self.container.buttons[i]] = 3
			if j == 1 then
				self.container.buttons[i].items[j]:SetPoint("TOPLEFT")
			else
				self.container.buttons[i].items[j]:SetPoint("LEFT", self.container.buttons[i].items[j - 1], "RIGHT", 5, 0)
			end
			self.container.buttons[i].items[j].icon = _G["InvenSimulatorSaveItemFrameItemButton"..realNum.."Icon"]
			self.container.buttons[i].items[j].icon:SetTexture("")
			self.container.buttons[i].items[j]:SetScript("OnClick", itemButtonOnClick)
			self.container.buttons[i].items[j]:SetScript("OnEnter", itemButtonOnEnter)
			self.container.buttons[i].items[j]:SetScript("OnLeave", GameTooltip_Hide)
			self.container.buttons[i].items[j]:SetScript("OnDragStart", nil)
			self.container.buttons[i].items[j]:SetScript("OnDragStop", nil)
			self.container.buttons[i].items[j]:SetScript("OnMouseUp", frameOnMouseDown)
			self.container.buttons[i].items[j]:SetScript("OnReceiveDrag", frameOnReceiveDrag)
		end
	end
	self.container.update = self.UpdateScroll
	HybridScrollFrame_CreateButtons(self.container)
	self:Refresh()
end

si:SetScript("OnShow", si.CreateFrame)