local addOnName = GetAddOnDependencies(...)
local BII3 = _G[addOnName]

BII3.itemList = { ["A**"] = true }

local _G = _G
local type = _G.type
local pairs = _G.pairs
local unpack = _G.unpack
local tonumber = _G.tonumber
local wipe = _G.table.wipe
local sort = _G.table.sort
local tinsert = _G.table.insert
local GetItemIcon = _G.GetItemIcon
local GetSpellInfo = _G.GetSpellInfo
local GetAddOnMetadata = _G.GetAddOnMetadata

local c, dtype, code = {}
local normal, heroic = {}, {}

for index in pairs(BII3.chardb.favorite) do
	BII3.itemList["A"..index.."*"] = true
	BII3:CreateFavorite(index)
end

local function addCategory(id, info)
	if id and type(info) == "string" and ((id > 0 and GetItemIcon(id)) or (id < 0 and GetSpellInfo(-id))) then
		if info:find("^a|") and BII3.isHorde then
			-- 플레이어가 호드일 경우 얼라 아이템 무시
		elseif info:find("^h|") and not BII3.isHorde then
			-- 플레이어가 얼라일 경우 호드 아이템 무시
		else
			c[1], c[2], c[3], c[4], c[5], c[6], c[7], c[8], c[9], c[10], c[11], c[12], c[13], c[14], c[15], c[16], c[17], c[18], c[19], c[20] = ("|"):split(info)
			for _, v in ipairs(c) do
				dtype, code = v:match("([A-Z|a-z])_(.+)")
				code = ("@"):split(code or v)
				code = ("*"):split(code)
				if BII3:GetCategory(code) then
					BII3.itemList[code:sub(1, 1).."**"] = true
					BII3.itemList[code:sub(1, 2).."*"] = true
					if dtype == "d" or dtype == "r" or dtype == "h" then
						heroic[code] = heroic[code] or {}
						tinsert(heroic[code], id)
					else
						normal[code] = normal[code] or {}
						tinsert(normal[code], id)
					end
				end
			end
		end
	end
end

for id, info in pairs(BII3.itemDB) do
	addCategory(id, BII3.itemDB[info] or info)
end

local function itemDBParser(id, ...)
	id = tonumber(id)
	if id then
		local info = BII3.itemDB[id]
		if type(info) == "string" then
			addCategory(id, info)
		elseif type(info) == "number" then
			addCategory(id, BII3.itemDB[info])
		end
	end
	if ... then
		itemDBParser(...)
	end
end

local function unpackItemDB(list)
	if list then
		itemDBParser(("/"):split(list))
		return true
	else
		return nil
	end
end

for pack, use in pairs(BII3.db.dataPacks) do
	if use then
		use = 1
		while unpackItemDB(GetAddOnMetadata(addOnName.."_"..pack, "X-DB-Items-"..use)) do
			use = use + 1
		end
	end
end

for code, items in pairs(normal) do
	for i, id in ipairs(items) do
		if i == 1 then
			BII3.itemList[code] = "!"..id
		else
			BII3.itemList[code] = BII3.itemList[code].."/"..id
		end
	end
end

for code, items in pairs(heroic) do
	for i, id in ipairs(items) do
		if i == 1 then
			if BII3.itemList[code] then
				BII3.itemList[code] = BII3.itemList[code].."_"..id
			else
				BII3.itemList[code] = "!_"..id
			end
		else
			BII3.itemList[code] = BII3.itemList[code].."/"..id
		end
	end
end

normal, heroic, itemDBParser, unpackItemDB = nil
wipe(c)

local function unpackList(add, ...)
	tinsert(c, tonumber(add))
	if ... then
		unpackList(...)
	end
end

local function getName(id)
	if id < 0 then
		if GetSpellInfo(-id) then
			return "9", GetSpellInfo(-id)
		else
			return "-1", id
		end
	elseif GetAddOnMetadata(addOnName.."_UI", "X-DB-ItemName-"..id) then
		return ("|"):split(GetAddOnMetadata(addOnName.."_UI", "X-DB-ItemName-"..id))
	else
		return "-2", id
	end
end

local aname, bname

local function sortItemTable(a, b)
	aname, code = getName(a)
	bname, dtype = getName(b)
	if aname == bname then
		if code == dtype then
			return a > b
		else
			return code < dtype
		end
	else
		return aname > bname
	end
end

function BII3:SortItem(code)
	if self.itemList[code]:find("^!") then
		normal, heroic = ("_"):split(self.itemList[code]:sub(2))
		if normal and normal ~= "" then
			unpackList(("/"):split(normal))
			sort(c, sortItemTable)
			normal = ("/"):join(unpack(c)) or ""
			wipe(c)
		else
			normal = ""
		end
		if heroic and heroic ~= "" then
			unpackList(("/"):split(heroic))
			sort(c, sortItemTable)
			heroic = ("/"):join(unpack(c)) or ""
			wipe(c)
			self.itemList[code] = normal.."_"..heroic
			normal, heroic = nil
		else
			self.itemList[code] = normal..""
			normal, heroic = nil
		end
	end
end