-- --------- --
-- Profiteer --
-- --------- --

Profiteer = {
	settingsVersion = 0.1,
	icons = {
		gold = "EsoUI/Art/currency/currency_gold.dds"
	},
	colors = {
		default = "|c" .. ZO_TOOLTIP_DEFAULT_COLOR:ToHex(),
		instructional = "|c" .. ZO_TOOLTIP_INSTRUCTIONAL_COLOR:ToHex(),
		title = "|c00B5FF",
	},
	controller = ProfiteerController,
	list = ProfiteerControllerResultsList,
	slider = ProfiteerControllerResultsSlider,
	runes = {},
}
local Profiteer = Profiteer
local PriceTracker = PriceTracker

-- Addon initialization
function Profiteer:OnLoad(eventCode, addOnName)
	if(addOnName ~= "Profiteer") then return end

	EVENT_MANAGER:RegisterForEvent("OnCraftingStationInteractStart", EVENT_CRAFTING_STATION_INTERACT, function(...) self:OnCraftingStationInteractStart(...) end)
	EVENT_MANAGER:RegisterForEvent("OnCraftingStationInteractEnd", EVENT_END_CRAFTING_STATION_INTERACT, function(...) self:OnCraftingStationInteractEnd(...) end)

	SLASH_COMMANDS["/profiteer"] = function(...) self:CommandHandler(...) end

	local defaults = {
		location = {
			top = 70,
			left = 15
		},
		hideNoPrice = false,
		reverseMouseWheel = false,
	}

	-- Load saved settings
	self.settings = ZO_SavedVars:NewAccountWide("ProfiteerSettings", self.settingsVersion, nil, defaults)

	self:RestorePosition()

	-- Do some housekeeping and remove inparsable items
	self:Housekeeping()

	self.menu:InitAddonMenu(addOnName)
end

-- Handle slash commands
function Profiteer:CommandHandler(text)
	if not text or text == "" or text == "help" then
		self:ShowHelp()
		return
	end

	-- Hidden option
	if text == "housekeeping" then
		self:Housekeeping()
		return
	end

end

function Profiteer:ShowHelp()
	d("This isn't very helpful")
end

-- This method makes sure the item list is intact and parsable, in order to avoid exceptions later on
function Profiteer:Housekeeping()
end

function Profiteer:OnSliderChanged(value)
	self.list:SetVerticalScroll(value)
	self.slider:SetValue(value)
end

function Profiteer:OnMouseWheel(delta)
	if self.list:GetNumChildren() == 0 then return end
	if self.settings.reverseMouseWheel then
		delta = -delta
	end
	local newSliderValue = self.slider:GetValue() + delta * self.list:GetChild(1):GetHeight()
	local min, max = self.slider:GetMinMax()
	if newSliderValue > max or newSliderValue < min then return end
	self:OnSliderChanged(newSliderValue)
	-- if self.slider:GetValue() == 1 and delta < 0 then return end
	-- if self.slider:GetValue() == max and delta > 0 then return end
	-- self:OnSliderChanged(self.slider:GetValue() + delta -- * self.list:GetChild(1):GetHeight())
end

function Profiteer:OnMoveStop()
	Profiteer.settings.location.top = Profiteer.controller:GetTop()
	Profiteer.settings.location.left = Profiteer.controller:GetLeft()
end

function Profiteer:RestorePosition()
	self.controller:ClearAnchors()
	self.controller:SetAnchor(TOPLEFT, GuiRoot, TOPLEFT, self.settings.location.left, self.settings.location.top)
end

function Profiteer:OnCraftingStationInteractStart(eventCode, craftSkill, sameStation)
	if craftSkill ~= CRAFTING_TYPE_ENCHANTING then return end
	self:InitializeRunes()
	self:ListGlyphs()
	if #self.glyphs == 0 then return end

	local i
	for i = 1, #self.glyphs do
		local glyphControl = WINDOW_MANAGER:GetControlByName("GlyphControl" .. i)
		if not glyphControl then
			glyphControl = WINDOW_MANAGER:CreateControlFromVirtual("GlyphControl" .. i, self.list, "ProfiteerLine")
		end
		local glyph = self.glyphs[i]
		local color = self:GetColor(GetItemLinkQuality(glyph.link))
		glyphControl.name = self:GetItemLinkName(glyph.link)
		glyphControl.glyph:SetText(color .. self:GetItemLinkName(glyph.link))
		glyphControl.aspect:SetText(self:GetColor(glyph.aspectRune.quality) .. self:GetBagItemName(glyph.aspectRune.bagId, glyph.aspectRune.slotIndex))
		glyphControl.potency:SetText(self:GetColor(glyph.potencyRune.quality) .. self:GetBagItemName(glyph.potencyRune.bagId, glyph.potencyRune.slotIndex))
		glyphControl.essence:SetText(self:GetColor(glyph.essenceRune.quality) .. self:GetBagItemName(glyph.essenceRune.bagId, glyph.essenceRune.slotIndex))
		glyphControl.price:SetText(self.glyphs[i].purchasePrice .. " " .. zo_iconFormat(self.icons.gold, 16, 16))
		if i == 1 then
			glyphControl:SetAnchor(TOPLEFT, self.list, TOPLEFT, 0, 0)
		else
			glyphControl:SetAnchor(TOPLEFT, WINDOW_MANAGER:GetControlByName("GlyphControl" .. (i - 1)), BOTTOMLEFT)
		end
	end

	-- Calculate how many lines can be shown
	local lineHeight = self.list:GetChild(1):GetHeight()
	local lines = self.list:GetHeight() / lineHeight
	self.slider:SetMinMax(1, (#self.glyphs - lines) * lineHeight)
	self.list:SetScrollBounding(#self.glyphs)

	self.controller:SetHidden(false)
end

function Profiteer:OnCraftingStationInteractEnd(eventCode)
	self.controller:SetHidden(true)
end

function Profiteer:InitializeRunes()
	self.runes = {}
	self.runes[1] = {}
	self.runes[2] = {}
	self.runes[3] = {}
	local bag
	for bag = BAG_BACKPACK, BAG_BANK do
		local list = ZO_EnchantingTopLevelInventoryBackpack.data
		local i
		for i = 1, #list do
			local itemLink = GetItemLink(list[i].data.bagId, list[i].data.slotIndex)
			local classification = GetItemLinkEnchantingRuneClassification(itemLink)
			local name = list[i].data.name
			if not self.runes[classification][name] then
				self.runes[classification][name] = {
					bagId = list[i].data.bagId,
					slotIndex = list[i].data.slotIndex,
					quality = list[i].data.quality,
					-- stackCount = 0
				}
			end
			-- self.runes[classification][name].stackCount = self.runes[classification][name].stackCount + list[i].data.stackCount
		end
	end
end

function Profiteer:ListGlyphs()
	self.glyphs = {}
	local _, aspectRune, essenceRune, potencyRune, glyphLink, glyph
	for _, aspectRune in pairs(self.runes[1]) do
		for _, essenceRune in pairs(self.runes[2]) do
			for _, potencyRune in pairs(self.runes[3]) do
				glyphLink = GetEnchantingResultingItemLink(potencyRune.bagId, potencyRune.slotIndex,
					essenceRune.bagId, essenceRune.slotIndex,
					aspectRune.bagId, aspectRune.slotIndex)
				local price = self:SuggestPrice(glyphLink)
				if GetItemLinkName(glyphLink) ~= "" and (not self.settings.hideNoPrice or price) then
					glyph = {
						link = glyphLink,
						aspectRune = aspectRune,
						essenceRune = essenceRune,
						potencyRune = potencyRune,
						purchasePrice = price
					}
					table.insert(self.glyphs, glyph)
				end
			end
		end
	end
	table.sort(self.glyphs, Profiteer.Compare)
end

function Profiteer:SuggestPrice(itemLink)
	local _, _, _, itemId = ZO_LinkHandler_ParseLink(itemLink)
	local level = PriceTracker:GetItemLevel(itemLink)
	local matches = PriceTracker:GetMatches(itemId, level)
	if not matches then return nil end
	return PriceTracker:SuggestPrice(matches).purchasePrice
end

function Profiteer:GetItemLinkName(itemLink)
	return zo_strformat(SI_TOOLTIP_ITEM_NAME, GetItemLinkName(itemLink))
end

function Profiteer:GetBagItemName(bagId, slotIndex)
	return zo_strformat(SI_TOOLTIP_ITEM_NAME, GetItemLinkName(GetItemLink(bagId, slotIndex)))
end

function Profiteer:GetColor(fieldValue)
	return "|c" .. ZO_ColorDef:New(GetInterfaceColor(INTERFACE_COLOR_TYPE_ITEM_QUALITY_COLORS, fieldValue)):ToHex()
end

function Profiteer.Compare(item1, item2)
	if not item1.purchasePrice then return false end
	if not item2.purchasePrice then return true end
	return item1.purchasePrice > item2.purchasePrice
end

EVENT_MANAGER:RegisterForEvent("ProfiteerLoaded", EVENT_ADD_ON_LOADED, function(...) Profiteer:OnLoad(...) end)