-- 기본 변수 선언
BlueCraftInfoUI = AceLibrary("AceAddon-2.0"):new("AceEvent-2.0")
local mother = BlueCraftInfo
local self = BlueCraftInfoUI
local recipe = BlueCraftInfoRecipe
local Tablet = AceLibrary("Tablet-2.0")
local Dewdrop = AceLibrary("Dewdrop-2.0")
local tooltip = BlueCraftInfoTooltip
local selectid = 2
local table = {}
local thisTable
local cacheItem = {}

-- 로컬 함수 선언
local type, abs, strsub, gsub, strsplit = type, abs, strsub, gsub, strsplit

local function GetItemID(name)
	local loc = sfind(self.Reagents, name)
	return loc and Uncomp36(strsub(self.Reagents, loc - 3, loc - 1)) or nil
end

local function GetLinkInfo(id, cid)
	if not id then return end
	local reagent, text, rnt, desc = {}, {}
	BlueCraftInfoTooltip:SetOwner(UIParent, "ANCHOR_NONE")
	BlueCraftInfoTooltip:ClearLines()
	BlueCraftInfoTooltipTextLeft1:SetText("")
	BlueCraftInfoTooltipTextLeft2:SetText("")
	BlueCraftInfoTooltipTextLeft3:SetText("")
	BlueCraftInfoTooltip:SetHyperlink("enchant:"..id)
	BlueCraftInfoTooltip:Show()
	local reagent, text, rnt, desc = {}, {}
	for i = 1, 3 do
		text[i] = getglobal("BlueCraftInfoTooltipTextLeft"..i):GetText()
	end
	if sfind(text[1], "^재료: ") then
		rnt, desc = text[1], text[2]
	elseif sfind(text[2], "^재료: ") then
		rnt, desc = text[2], text[3]
	end
	BlueCraftInfoTooltip:Hide()
	if rnt == nil then
		return
	end
	if sfind(desc, "^\n") then
		desc = nil
	end
	rnt = gsubs(rnt, { "재료: ", strchar(124).."cffffffff", strchar(124).."cffff2020", strchar(124).."r", strchar(124).."n" }, "")
	local itemID = mother:GetItem2Recipe(id)
	if itemID and mother.cache[itemID] and type(mother.cache[itemID]) == "table" then
		mother.cache[itemID][2] = rnt
	end
	rnt = { strsplit(",", gsub(rnt, " ", "")) }
	for i = 1, #(rnt) do
		local _, _, n, c = sfind(rnt[i], "(.+)%((%d+)%)")
		if n then
			reagent[#(reagent) + 1] = { n, c }
		else
			reagent[#(reagent) + 1] = { rnt[i], 1 }
		end
	end
	return reagent, desc
end

local function GetItem(itemID)
	if itemID then
		local name, link, rarity, _, _, _, _, _, _, texture = GetItemInfo(itemID)
		return name, link, rarity, texture
	end
end

local function GetLink(tid, id)
	local header = mother.skillNameKR[tid]
	local name = ((header == "마법부여") and "" or (header..": "))..table[tid][id][1]
	return "|cffffd000|Henchant:"..table[tid][id][4].."|h["..name.."]|h|r"
end

local function SetLink(itemID)
	if itemID and cacheItem[itemID] == nil then
		BlueCraftInfoTooltip:SetOwner(UIParent, "ANCHOR_NONE")
		if itemID < 0 then
			BlueCraftInfoTooltip:SetHyperlink("enchant:"..abs(itemID))
		else
			BlueCraftInfoTooltip:SetHyperlink("item:"..itemID..":0:0:0:0:0:0:0")
		end
		BlueCraftInfoTooltip:Hide()
		cacheItem[itemID] = 0
	end
end

local function SetDefaultSkillSelection()
	for i = 1, #(thisTable) do
		if type(thisTable[i]) == "number" then
			return i
		end
	end
	return 2
end

local function AddSkin(obj)
	obj:SetBackdrop({
		bgFile = "Interface\\ChatFrame\\ChatFrameBackground", tile = true, tileSize = 16,
		edgeFile = "Interface\\AddOns\\BlueCraftInfoUI\\krsnik", edgeSize = 16,
		insets = {left = 4, right = 4, top = 4, bottom = 4},
	})
	obj:SetBackdropBorderColor(0.2, 0.2, 0.2, 1)
	obj:SetBackdropColor(0.1, 0.1, 0.1, 1)
end

local function ChangeScrollBarSkin(frame)
	for k, v in pairs({ frame:GetRegions() }) do
		if regions then
			for _, r in pairs(regions) do
				if k == r then
					v:SetAlpha(0)
					break
				end
			end
		else
			v:SetAlpha(0)
		end
	end
	AddSkin(getglobal(frame:GetName().."ScrollBar"))
end

local function ChangeEditBoxSkin(frame)
	for k, v in pairs({ frame:GetRegions() }) do
		local keep = false
		for i = 1, 5 do
			if k == i then
				keep = true
				break
			end
		end
		if not keep then
			v:SetAlpha(0)
		end
	end
	local l, r, t, b = frame:GetTextInsets()
	frame:SetTextInsets(l + 5, r + 5, t, b)
	if not frame:IsMultiLine() then
		frame:SetHeight(26)
	end
	frame:SetWidth(frame:GetWidth() + 5)
	AddSkin(frame)
end

function BlueCraftInfoUI:OnInitialize()
	if mother.db.profile.position.isSet then
		BlueCraftInfoFrame:ClearAllPoints()
		BlueCraftInfoFrame:SetPoint("CENTER", UIParent, "CENTER", mother.db.profile.position.x, mother.db.profile.position.y)
	end
	self:SetBackdropColor()
	ChangeScrollBarSkin(BlueCraftInfoListScrollFrame)
	ChangeScrollBarSkin(BlueCraftInfoDetailScrollFrame)
	ChangeEditBoxSkin(BlueCraftInfoFrameEditBox)
	if Skinner then
		Skinner:applySkin(BlueCraftInfoFrame)
		Skinner:applySkin(BlueCraftInfoListFrame)
		Skinner:applySkin(BlueCraftInfoDetailFrame)
	end
	if VisualThemes then
		VisualThemes:RegisterAddOn("BlueCraftInfo", "BlueCraftInfo", 0, "BlueCraftInfoFrame", "BlueCraftInfoListFrame", "BlueCraftInfoDetailFrame")
	end
	BlueCraftInfoDetailRequirementLabel:SetText("필요 숙련:")
	self:ConvTradeSkillData()
	self:InitDropDown()
end

function BlueCraftInfoUI:FrameToggle()
	if BlueCraftInfoFrame:IsVisible() then
		self:ToggleDropDown(0)
		self:CancelAllScheduledEvents()
		HideUIPanel(BlueCraftInfoFrame)
	else
		ShowUIPanel(BlueCraftInfoFrame)
	end
end

function BlueCraftInfoUI:InitDropDown()
	self.menu = { type = "group", args = {} }
	for i = 1, #(mother.skillNameKR) do
		self.menu.args["ts"..i] = {
			name = mother.skillNameKR[i],
			desc = mother.skillNameKR[i].."의 목록",
			type = "execute",
			order = i,
			func = function()self:SetTradeSkill(i) AceLibrary("Dewdrop-2.0"):Close() end,
		}
	end
	Dewdrop:Register(BlueCraftInfoFrameDropdown, "children", self.menu, "dontHook", true, "point", "TOPLEFT", "relativePoint", "BOTTOMLEFT")
	self:SetTradeSkill(mother.db.profile.list or 1)
end

function BlueCraftInfoUI:SetTradeSkill(id, search)
	self:ToggleDropDown(0)
	BlueCraftInfoFrameEditBox:SetText(SEARCH)
	if id < 1 then
		id = #(mother.skillNameKR)
	elseif id > #(mother.skillNameKR) then
		id = 1
	end
	BlueCraftInfoListFrame:Show()
	mother.db.profile.list = id
	BlueCraftInfoFrameDropdownText:SetText(mother.skillNameKR[id])
	self:ResetScrollBar(BlueCraftInfoListScrollFrame)
	self:ResetScrollBar(BlueCraftInfoDetailScrollFrame)
	self:SetListTable()
	BlueCraftInfoFrameCollapseAllButton.value = false
	self:CollapseAll()
	selectid = SetDefaultSkillSelection()
	self:ListFrameUpdate()
	self:ShowDetail()
end

function BlueCraftInfoUI:ResetScrollBar(frame)
	getglobal(frame:GetName().."ScrollBarScrollDownButton"):Disable()
	getglobal(frame:GetName().."ScrollBarScrollUpButton"):Disable()
	getglobal(frame:GetName().."ScrollBar"):SetMinMaxValues(0, 0)
	getglobal(frame:GetName().."ScrollBar"):SetValue(0)
	FauxScrollFrame_SetOffset(frame, 0)
end

function BlueCraftInfoUI:DropDownScroll(sc)
	local id = mother.db.profile.list
	if sc > 0 then
		BlueCraftInfoUI:SetTradeSkill(id - 1)
	else
		BlueCraftInfoUI:SetTradeSkill(id + 1)
	end
end

function BlueCraftInfoUI:ToggleDropDown(check)
	if check == 0 then
		Dewdrop:Close()
	elseif check == 1 then
		Dewdrop:Open(BlueCraftInfoFrameDropdown)
	elseif Dewdrop:IsOpen(BlueCraftInfoFrameDropdown) then
		PlaySound("igMainMenuOptionCheckBoxOff")
		Dewdrop:Close()
	else
		PlaySound("igMainMenuOptionCheckBoxOn")
		Dewdrop:Open(BlueCraftInfoFrameDropdown)
	end
end

function BlueCraftInfoUI:CreateSkillButtons()
	local sb, prev_sb
	for i = 1, 18 do
		sb = CreateFrame("Button", "BlueCraftInfoSkill"..i, BlueCraftInfoListFrame, "BlueCraftInfoSkillButtonTemplate")
		if prev_sb then
			sb:SetPoint("TOPLEFT", prev_sb, "BOTTOMLEFT", 0, 0)
		else
			sb:SetPoint("TOPLEFT", BlueCraftInfoListFrame, "TOPLEFT", 5, -5)
		end
		prev_sb = sb
	end
end

function BlueCraftInfoUI:SetCollapseIcon(value)
	local cb = BlueCraftInfoFrameCollapseAllButton
	if value then
		cb.value = true
		cb:SetNormalTexture("Interface\\Buttons\\UI-MinusButton-Up")
	else
		cb.value = false
		cb:SetNormalTexture("Interface\\Buttons\\UI-PlusButton-Up")
	end
end

function BlueCraftInfoUI:CollapseAll()
	local cbvalue = not BlueCraftInfoFrameCollapseAllButton.value
	self:SetCollapseIcon(cbvalue)
	self:SetCollapse(cbvalue)
end

function BlueCraftInfoUI:SetCollapse(value)
	local tid = mother.db.profile.list
	local numAllEntries = #(table[tid])
	if value then
		for i = 1, numAllEntries do
			if table[tid][i][2] == -1 then
				table[tid][i][2] = 0
			end
		end
	else
		for i = 1, numAllEntries do
			if table[tid][i][2] == 0 then
				table[tid][i][2] = -1
			end
		end
	end
	self:Search()
end

function BlueCraftInfoUI:ListFrameUpdate()
	local tid = mother.db.profile.list
	local numEntries = #(thisTable)
	local offset = FauxScrollFrame_GetOffset(BlueCraftInfoListScrollFrame) or 0
	local id, sb, sbh, ts
	FauxScrollFrame_Update(BlueCraftInfoListScrollFrame, numEntries, 18, 16, nil, nil, nil, BlueCraftInfoHighlightFrame, 293, 316)
	BlueCraftInfoHighlightFrame:Hide()
	for i = 1, 18 do
		id = i + offset
		sb = getglobal("BlueCraftInfoSkill"..i)
		sbh = getglobal("BlueCraftInfoSkill"..i.."Highlight")
		if ( id <= numEntries ) and table[tid] then
			if type(thisTable[id]) == "table" then
				sb:SetID(thisTable[id][1])
				ts = table[tid][thisTable[id][1] ]
				sb:SetText(ts[1])
				sb:SetNormalTexture("Interface\\Buttons\\UI-"..(thisTable[id][2] and "Minus" or "Plus").."Button-Up")
				sbh:SetTexture("Interface\\Buttons\\UI-PlusButton-Hilight")
				sb:UnlockHighlight()
			elseif thisTable[id] then
				sb:SetID(thisTable[id])
				ts = table[tid][thisTable[id] ]
				sb:SetText((select(4, GetItemQualityColor(ts and ts[6] or 1))).." "..ts[1].."|r")
				sb:SetNormalTexture("")
				sbh:SetTexture("")
				if selectid == thisTable[id] then
					BlueCraftInfoHighlight:SetVertexColor(GetItemQualityColor(ts and ts[6] or 1))
					BlueCraftInfoHighlightFrame:SetPoint("TOPLEFT", sb, "TOPLEFT", 15, 0)
					BlueCraftInfoHighlightFrame:Show()
					sb:LockHighlight()
				else
					sb:UnlockHighlight()
				end
			end
			sb:Show()
		else
			sb:Hide()
		end
	end
end

function BlueCraftInfoUI:SetListTable(search)
	local tid = mother.db.profile.list
	thisTable = {}
	local chk, cnt = true, 0
	for i = 1, #(table[tid]) do
		if table[tid][i][2] == 0 then
			chk = true
			cnt = cnt + 1
			thisTable[cnt] = { i, chk }
		elseif table[tid][i][2] == -1 then
			chk = false
			cnt = cnt + 1
			thisTable[cnt] = { i, chk }
		elseif chk then
			if search then
				if sfind(table[tid][i][1], search) then
					cnt = cnt + 1
					thisTable[cnt] = i
				end
			else
				cnt = cnt + 1
				thisTable[cnt] = i
			end
		end
	end
end

function BlueCraftInfoUI:Search()
	local search = BlueCraftInfoFrameEditBox:GetText()
	if search == SEARCH or search == "" then
		search = nil
	end
	self:SetListTable(search)
	selectid = SetDefaultSkillSelection()
	self:ListFrameUpdate()
end

function BlueCraftInfoUI:SkillButton_OnClick(frame, button)
	local tid = mother.db.profile.list
	local id = tonumber(frame:GetID())
	if table[tid][id][2] > 0 then
		if IsShiftKeyDown() and table[tid][id][4] then
			ChatFrameEditBox:Show()
			ChatFrameEditBox:Insert(GetLink(tid, id))
		end
		selectid = id
		self:ShowDetail()
	else
		table[tid][id][2] = abs(table[tid][id][2]) - 1
		self:Search()
	end
	BlueCraftInfoFrameEditBox:ClearFocus()
	self:ListFrameUpdate()
end

function BlueCraftInfoUI:ShowDetail()
	local tid = mother.db.profile.list
	local id = selectid
	if table[tid][id] then
		local itemID, count, itemName, itemLink, itemRarity, itemTexture, rFrame, rName, reload, itemID36, rarity, getrecipe, loc1, loc2, loc3, loc4, tmp, ids
		local reagent, desc = GetLinkInfo(table[tid][id][4])
		if table[tid][id][5] == "0" then
			BlueCraftInfoDetailSkillName:SetText(table[tid][id][1])
			BlueCraftInfoDetailSkillIcon:SetNormalTexture("Interface\\Icons\\Spell_Holy_GreaterHeal")
			BlueCraftInfoDetailSkillIcon.link = GetLink(tid, id)
			BlueCraftInfoDetailSkillIcon.id = nil
		else
			itemID36, count = strsplit("_", table[tid][id][5])
			itemID = Uncomp36(itemID36)
			count = Uncomp36(count)
			itemName, itemLink, itemRarity, itemTexture = GetItem(itemID)
			if itemName then
				local _, _, _, color = GetItemQualityColor(table[tid][id][6] or 1)
				BlueCraftInfoDetailSkillName:SetText(color..itemName.."|r")
				BlueCraftInfoDetailSkillIcon:SetNormalTexture(itemTexture)
				BlueCraftInfoDetailSkillIcon.link = itemLink
				BlueCraftInfoDetailSkillIcon.id = itemID
			else
				BlueCraftInfoDetailSkillName:SetText(table[tid][id][1])
				BlueCraftInfoDetailSkillIcon:SetNormalTexture("Interface\\Icons\\INV_Misc_QuestionMark")
				BlueCraftInfoDetailSkillIcon.link = nil
				BlueCraftInfoDetailSkillIcon.id = itemID
				SetLink(itemID)
				reload = true
			end
		end
		if reload or reagent == nil then
			self:ReloadDetailFrame(table[tid][id][4])
			return
		end
		BlueCraftInfoDetailScrollFrame:Show()
		BlueCraftInfoDetailFrameWait:Hide()
		BlueCraftInfoDetailSkillIconCount:SetText(count)
		BlueCraftInfoDetailRequirementText:SetText(BlueCraftInfoFrameDropdownText:GetText().."("..((table[tid][id][3] and table[tid][id][3] ~= 999) and table[tid][id][3] or "??")..")")
		for i = 1, #(reagent) do
			local iid = GetItemID(reagent[i][1])
			itemName, itemLink, itemRarity, itemTexture = GetItem(iid)
			rFrame = getglobal("BlueCraftInfoDetailReagent"..i)
			rName = getglobal("BlueCraftInfoDetailReagent"..i.."Name")
			if itemName then
				local _, _, _, color = GetItemQualityColor(itemRarity or 1)
				rName:SetText(color..itemName.."|r")
				SetItemButtonTexture(rFrame, itemTexture)
				rFrame.link = itemLink
				rFrame.id = iid
			else
				rName:SetText(reagent[i][1])
				SetItemButtonTexture(rFrame, "Interface\\Icons\\INV_Misc_QuestionMark")
				rFrame.link = nil
				rFrame.id = iid
			end
			getglobal("BlueCraftInfoDetailReagent"..i.."Count"):SetText(reagent[i][2])
			rFrame:Show()
		end
		self:CancelAllScheduledEvents()
		BlueCraftInfoDetailDescription:SetText(desc)
		getrecipe = nil
		if table[tid][id][7] then
			getrecipe = mother:GetRecipeDrop(table[tid][id][7])
		end
		if getrecipe then
			BlueCraftInfoDetailRecipe:SetText("획득처:\n|cffffffff "..getrecipe.."|r")
		else
			BlueCraftInfoDetailRecipe:SetText()
		end
		for i = #(reagent or {}) + 1, 8 do
			getglobal("BlueCraftInfoDetailReagent"..i):Hide()
		end
		cacheItem[table[tid][id][4]] = nil
		BlueCraftInfoDetailFrame:Show()
	else
		BlueCraftInfoDetailFrame:Hide()
	end
end

function BlueCraftInfoUI:ReloadDetailFrame(id, link)
	BlueCraftInfoDetailFrame:Show()
	if id then
		cacheItem[id] = cacheItem[id] and (cacheItem[id] + 1) or 1
		if cacheItem[id] > 2 then
			BlueCraftInfoDetailScrollFrame:Hide()
			BlueCraftInfoDetailFrameWait:SetText("아이템 캐쉬 확인에 실패했습니다.")
			BlueCraftInfoDetailFrameWait:Show()
			self:CancelAllScheduledEvents()
			return
		end
	end
	BlueCraftInfoDetailScrollFrame:Hide()
	BlueCraftInfoDetailFrameWait:SetText("아이템 캐쉬를 생성하고 있습니다.\n잠시 기다려주세요.")
	BlueCraftInfoDetailFrameWait:Show()
	self:ScheduleEvent(function() self:ShowDetail() end, 1, self)
end

function BlueCraftInfoUI:ShowItemTooltip(frame)
	if not frame then
		return
	end
	if this.link then
		GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
		GameTooltip:SetHyperlink(frame.link)
	elseif this.id then
		GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
		GameTooltip:SetText("|cffffffff해당 아이템이 아이템 캐쉬에 존재하지 않습니다.|r")
		GameTooltip:AddLine("클릭하면 해당 아이템의 정보를 서버로부터 가져옵니다.")
	end
	GameTooltip:Show()
	CursorUpdate()
end

function BlueCraftInfoUI:ClickItem(frame)
	if not frame then
		return
	end
	if frame.link then
		if sfind(frame.link, "item:") then
			if IsShiftKeyDown() then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(frame.link)
			elseif IsControlKeyDown() then
				DressUpItemLink(frame.link)
			else
				ChatFrame_OnHyperlinkShow("item:"..frame.id..":0:0:0:0:0:0:0", frame.itemLink)
			end
		else
			if IsShiftKeyDown() then
				ChatFrameEditBox:Show()
				ChatFrameEditBox:Insert(frame.link)
			else
				ChatFrame_OnHyperlinkShow(frame.link, frame.link)
			end
		end
	elseif frame.id then
		BlueCraftInfoTooltip:SetOwner(frame, "ANCHOR_NONE")
		BlueCraftInfoTooltip:SetHyperlink("item:"..frame.id..":0:0:0:0:0:0:0")
		BlueCraftInfoTooltip:Hide()
		self:ScheduleEvent(function() self:ShowDetail() end, 1, self)
	end
	BlueCraftInfoFrameEditBox:ClearFocus()
end

function BlueCraftInfoUI:SetBackdropColor()
	local c = mother.db.profile.backdrop
	BlueCraftInfoFrame:SetBackdropColor(c.r, c.g, c.b, c.a)
	BlueCraftInfoListFrame:SetBackdropColor(c.r, c.g, c.b, c.a)
	BlueCraftInfoDetailFrame:SetBackdropColor(c.r, c.g, c.b, c.a)
end

function BlueCraftInfoUI:SavePosition()
	local cx, cy = UIParent:GetCenter()
	local x, y = BlueCraftInfoFrame:GetCenter()
	mother.db.profile.position.x = x - cx
	mother.db.profile.position.y = y - cy
	mother.db.profile.position.isSet = true
	BlueCraftInfoFrame:ClearAllPoints()
	BlueCraftInfoFrame:SetPoint("CENTER", UIParent, "CENTER", mother.db.profile.position.x, mother.db.profile.position.y)
end

function BlueCraftInfoUI:ConvTradeSkillData()
	local copyname = { ["무기"] = 1, ["양손 무기"] = 1, ["방패"] = 1, ["가슴보호구"] = 1, ["장갑"] = 1, ["장화"] = 1, ["손목보호구"] = 1, ["망토"] = 1, ["반지"] = 1 }
	for i = 1, #(mother.skillNameEN) do
		table[i] = {}
		if mother.Data[mother.skillNameEN[i]] then
			local cnt, ccnt, db, ts, name, header, rar = 0
			for j = 1, #(mother.Data[mother.skillNameEN[i]]) do
				cnt = cnt + 1
				table[i][cnt] = { mother.Data[mother.skillNameEN[i]][j][1], 0 }
				if mother.Data[mother.skillNameEN[i]][j][2] ~= "" then
					ccnt = cnt
					if mother.skillNameEN[i] == "Enchanting" and copyname[mother.Data[mother.skillNameEN[i]][j][1]] then
						header = mother.Data[mother.skillNameEN[i]][j][1].." 마법부여 - "
					elseif mother.skillNameEN[i] == "Alchemy" and mother.Data[mother.skillNameEN[i]][j][1] == "변환" then
						header = "변환식: "
					elseif mother.skillNameEN[i] == "Jewelcrafting" and mother.Data[mother.skillNameEN[i]][j][1] == "조각상" then
						header = "조각상 - "
					else
						header = ""
					end
					db = { strsplit("/", mother.Data[mother.skillNameEN[i]][j][2]) }
					for k = 1, #(db) do
						ts = { strsplit("|", db[k]) }
						name, rar = strsplit("_", ts[1])
						cnt = cnt + 1
						table[i][cnt] = { header..name, ccnt, Uncomp36(ts[3]), Uncomp36(ts[2]), ts[4], rar or 1, ts[5] }
					end
				end
			end
		end
	end
	collectgarbage()
end