local ADDON_NAME, OneWoW = ...
local L = OneWoW.L

OneWoW.NestedFlyouts = OneWoW.NestedFlyouts or {}
local Nested = OneWoW.NestedFlyouts

local activeNested = {}

function Nested:CreateDungeonsButton(parent, iconSize, yOffset, expansions, showAll)
	local mainButton = CreateFrame("Button", nil, parent)
	mainButton:SetSize(iconSize, iconSize)
	mainButton:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, yOffset)
	mainButton:SetNormalTexture("Interface\\Icons\\Achievement_Boss_Archaedas")

	mainButton.text = mainButton:CreateFontString(nil, "OVERLAY")
	mainButton.text:SetPoint("BOTTOM", mainButton, "BOTTOM", 0, 2)
	mainButton.text:SetFont(STANDARD_TEXT_FONT, 8, "OUTLINE")
	mainButton.text:SetTextColor(1, 1, 1, 1)
	mainButton.text:SetShadowColor(0, 0, 0, 1)
	mainButton.text:SetShadowOffset(1, -1)
	mainButton.text:SetText(L["SETTINGS_PORTALHUB_DUNGEONS"])

	local expFlyout = CreateFrame("Frame", nil, UIParent)
	expFlyout:SetFrameStrata("FULLSCREEN_DIALOG")
	expFlyout:SetFrameLevel(103)
	expFlyout:SetSize(iconSize * #expansions, iconSize)
	expFlyout:SetPoint("TOPLEFT", mainButton, "TOPRIGHT", 2, 0)

	local expButtons = {}
	local validExpansions = {}
	for _, expData in ipairs(expansions) do
		if #expData.portals > 0 or (showAll and expData.id == "mid") then
			table.insert(validExpansions, expData)
		end
	end

	expFlyout:SetSize(iconSize * math.max(#validExpansions, 1), iconSize)

	for i, expData in ipairs(validExpansions) do
		local expButton = CreateFrame("Button", nil, expFlyout)
		expButton:SetSize(iconSize, iconSize)
		expButton:SetPoint("TOPLEFT", expFlyout, "TOPLEFT", (i-1) * iconSize, 0)
		expButton:SetNormalTexture(expData.icon)

		expButton.text = expButton:CreateFontString(nil, "OVERLAY")
		expButton.text:SetPoint("BOTTOM", expButton, "BOTTOM", 0, 2)
		expButton.text:SetFont(STANDARD_TEXT_FONT, 8, "OUTLINE")
		expButton.text:SetTextColor(1, 1, 1, 1)
		expButton.text:SetShadowColor(0, 0, 0, 1)
		expButton.text:SetShadowOffset(1, -1)
		expButton.text:SetText(expData.label)

		if #expData.portals > 0 then
			local portalFlyout = CreateFrame("Frame", nil, UIParent)
			portalFlyout:SetFrameStrata("FULLSCREEN_DIALOG")
			portalFlyout:SetFrameLevel(104)

			local numPortals = math.max(#expData.portals, 1)
			portalFlyout:SetSize(iconSize, iconSize * numPortals)
			portalFlyout:SetPoint("TOP", expButton, "BOTTOM", 0, -2)

			local portalButtons = {}
			for j, portal in ipairs(expData.portals) do
				if OneWoW.PortalHubFlyouts then
					local btn = OneWoW.PortalHubFlyouts:CreateFlyoutButton(portalFlyout, portal, 0, -(j-1) * iconSize, iconSize)
					if btn then
						btn:HookScript("PostClick", function(self, mouseButton)
							if mouseButton == "LeftButton" then
								if OneWoW.NestedFlyouts then OneWoW.NestedFlyouts:RecycleAll() end
								if OneWoW.PortalHubFlyouts then OneWoW.PortalHubFlyouts:RecycleAll() end
								if GameMenuFrame then
									C_Timer.After(0.1, function() HideUIPanel(GameMenuFrame) end)
								end
							end
						end)
						table.insert(portalButtons, btn)
					end
				end
			end

			expButton:SetScript("OnEnter", function(self)
				portalFlyout:Show()
			end)

			expButton:SetScript("OnLeave", function(self)
				C_Timer.After(0.3, function()
					if not portalFlyout:IsMouseOver() and not self:IsMouseOver() then
						portalFlyout:Hide()
					end
				end)
			end)

			portalFlyout:SetScript("OnLeave", function(self)
				C_Timer.After(0.3, function()
					if not self:IsMouseOver() and not expButton:IsMouseOver() then
						self:Hide()
					end
				end)
			end)

			portalFlyout:Hide()
			expButton.portalFlyout = portalFlyout
		end

		table.insert(expButtons, expButton)
	end

	mainButton:SetScript("OnEnter", function(self)
		expFlyout:Show()
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
		GameTooltip:SetText(L["SETTINGS_PORTALHUB_DUNGEONS"], 1, 1, 1)
		GameTooltip:Show()
	end)

	mainButton:SetScript("OnLeave", function(self)
		C_Timer.After(0.5, function()
			if not expFlyout:IsMouseOver() and not self:IsMouseOver() then
				expFlyout:Hide()
				for _, btn in ipairs(expButtons) do
					if btn.portalFlyout then
						btn.portalFlyout:Hide()
					end
				end
			end
		end)
		GameTooltip:Hide()
	end)

	expFlyout:SetScript("OnLeave", function(self)
		C_Timer.After(0.5, function()
			local mouseOver = false
			if self:IsMouseOver() or mainButton:IsMouseOver() then
				mouseOver = true
			else
				for _, btn in ipairs(expButtons) do
					if btn:IsMouseOver() or (btn.portalFlyout and btn.portalFlyout:IsMouseOver()) then
						mouseOver = true
						break
					end
				end
			end
			if not mouseOver then
				self:Hide()
				for _, btn in ipairs(expButtons) do
					if btn.portalFlyout then
						btn.portalFlyout:Hide()
					end
				end
			end
		end)
	end)

	expFlyout:Hide()
	mainButton:Show()

	table.insert(activeNested, {button = mainButton, flyout = expFlyout, subButtons = expButtons})
	return mainButton
end

function Nested:CreateRaidsButton(parent, iconSize, yOffset, expansions, showAll)
	local mainButton = CreateFrame("Button", nil, parent)
	mainButton:SetSize(iconSize, iconSize)
	mainButton:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, yOffset)
	mainButton:SetNormalTexture(4062765)

	mainButton.text = mainButton:CreateFontString(nil, "OVERLAY")
	mainButton.text:SetPoint("BOTTOM", mainButton, "BOTTOM", 0, 2)
	mainButton.text:SetFont(STANDARD_TEXT_FONT, 8, "OUTLINE")
	mainButton.text:SetTextColor(1, 1, 1, 1)
	mainButton.text:SetShadowColor(0, 0, 0, 1)
	mainButton.text:SetShadowOffset(1, -1)
	mainButton.text:SetText(L["SETTINGS_PORTALHUB_RAIDS"])

	local expFlyout = CreateFrame("Frame", nil, UIParent)
	expFlyout:SetFrameStrata("FULLSCREEN_DIALOG")
	expFlyout:SetFrameLevel(103)
	expFlyout:SetSize(iconSize * #expansions, iconSize)
	expFlyout:SetPoint("TOPLEFT", mainButton, "TOPRIGHT", 2, 0)

	local expButtons = {}
	local validExpansions = {}
	for _, expData in ipairs(expansions) do
		if #expData.portals > 0 or (showAll and expData.id == "mid") then
			table.insert(validExpansions, expData)
		end
	end

	expFlyout:SetSize(iconSize * math.max(#validExpansions, 1), iconSize)

	for i, expData in ipairs(validExpansions) do
		local expButton = CreateFrame("Button", nil, expFlyout)
		expButton:SetSize(iconSize, iconSize)
		expButton:SetPoint("TOPLEFT", expFlyout, "TOPLEFT", (i-1) * iconSize, 0)
		expButton:SetNormalTexture(expData.icon)

		expButton.text = expButton:CreateFontString(nil, "OVERLAY")
		expButton.text:SetPoint("BOTTOM", expButton, "BOTTOM", 0, 2)
		expButton.text:SetFont(STANDARD_TEXT_FONT, 8, "OUTLINE")
		expButton.text:SetTextColor(1, 1, 1, 1)
		expButton.text:SetShadowColor(0, 0, 0, 1)
		expButton.text:SetShadowOffset(1, -1)
		expButton.text:SetText(expData.label)

		if #expData.portals > 0 then
			local portalFlyout = CreateFrame("Frame", nil, UIParent)
			portalFlyout:SetFrameStrata("FULLSCREEN_DIALOG")
			portalFlyout:SetFrameLevel(104)

			local numPortals = math.max(#expData.portals, 1)
			portalFlyout:SetSize(iconSize, iconSize * numPortals)
			portalFlyout:SetPoint("TOP", expButton, "BOTTOM", 0, -2)

			local portalButtons = {}
			for j, portal in ipairs(expData.portals) do
				if OneWoW.PortalHubFlyouts then
					local btn = OneWoW.PortalHubFlyouts:CreateFlyoutButton(portalFlyout, portal, 0, -(j-1) * iconSize, iconSize)
					if btn then
						btn:HookScript("PostClick", function(self, mouseButton)
							if mouseButton == "LeftButton" then
								if OneWoW.NestedFlyouts then OneWoW.NestedFlyouts:RecycleAll() end
								if OneWoW.PortalHubFlyouts then OneWoW.PortalHubFlyouts:RecycleAll() end
								if GameMenuFrame then
									C_Timer.After(0.1, function() HideUIPanel(GameMenuFrame) end)
								end
							end
						end)
						table.insert(portalButtons, btn)
					end
				end
			end

			expButton:SetScript("OnEnter", function(self)
				portalFlyout:Show()
			end)

			expButton:SetScript("OnLeave", function(self)
				C_Timer.After(0.3, function()
					if not portalFlyout:IsMouseOver() and not self:IsMouseOver() then
						portalFlyout:Hide()
					end
				end)
			end)

			portalFlyout:SetScript("OnLeave", function(self)
				C_Timer.After(0.3, function()
					if not self:IsMouseOver() and not expButton:IsMouseOver() then
						self:Hide()
					end
				end)
			end)

			portalFlyout:Hide()
			expButton.portalFlyout = portalFlyout
		end

		table.insert(expButtons, expButton)
	end

	mainButton:SetScript("OnEnter", function(self)
		expFlyout:Show()
		GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
		GameTooltip:SetText(L["SETTINGS_PORTALHUB_RAIDS"], 1, 1, 1)
		GameTooltip:Show()
	end)

	mainButton:SetScript("OnLeave", function(self)
		C_Timer.After(0.5, function()
			if not expFlyout:IsMouseOver() and not self:IsMouseOver() then
				expFlyout:Hide()
				for _, btn in ipairs(expButtons) do
					if btn.portalFlyout then
						btn.portalFlyout:Hide()
					end
				end
			end
		end)
		GameTooltip:Hide()
	end)

	expFlyout:SetScript("OnLeave", function(self)
		C_Timer.After(0.5, function()
			local mouseOver = false
			if self:IsMouseOver() or mainButton:IsMouseOver() then
				mouseOver = true
			else
				for _, btn in ipairs(expButtons) do
					if btn:IsMouseOver() or (btn.portalFlyout and btn.portalFlyout:IsMouseOver()) then
						mouseOver = true
						break
					end
				end
			end
			if not mouseOver then
				self:Hide()
				for _, btn in ipairs(expButtons) do
					if btn.portalFlyout then
						btn.portalFlyout:Hide()
					end
				end
			end
		end)
	end)

	expFlyout:Hide()
	mainButton:Show()

	table.insert(activeNested, {button = mainButton, flyout = expFlyout, subButtons = expButtons})
	return mainButton
end

function Nested:RecycleAll()
	for _, data in ipairs(activeNested) do
		if data.button then data.button:Hide() end
		if data.flyout then data.flyout:Hide() end
		if data.subButtons then
			for _, btn in ipairs(data.subButtons) do
				if btn.portalFlyout then btn.portalFlyout:Hide() end
				btn:Hide()
			end
		end
	end
	activeNested = {}
end
