local _, GF = ...

GF.Hook = GF.Hook or {}

local origOpenBestWindow
local origFindQuestGroup
local refreshTicket = 0

local function getRouter()
	return GF.NativeEntryRouter
end

local function replacementOpenBestWindow(toggle)
	local router = getRouter()
	if router and router.RouteOpenBestWindow then
		return router:RouteOpenBestWindow(origOpenBestWindow, toggle)
	end
	if origOpenBestWindow then
		return origOpenBestWindow(toggle)
	end
end

local function replacementFindQuestGroup(questID, isFromGreenEyeButton)
	local router = getRouter()
	if router and router.RouteFindQuestGroup then
		return router:RouteFindQuestGroup(
			origFindQuestGroup,
			questID,
			isFromGreenEyeButton)
	end
	if origFindQuestGroup then
		return origFindQuestGroup(questID, isFromGreenEyeButton)
	end
end

local function captureOriginalOpenBestWindow()
	local current = _G.LFGListUtil_OpenBestWindow
	if current and current ~= replacementOpenBestWindow
		and not origOpenBestWindow
	then
		origOpenBestWindow = current
	end
	return current
end

local function captureOriginalFindQuestGroup()
	local current = _G.LFGListUtil_FindQuestGroup
	if current and current ~= replacementFindQuestGroup
		and not origFindQuestGroup
	then
		origFindQuestGroup = current
	end
	return current
end

local function shouldPreferOpen()
	local router = getRouter()
	return router and router.ShouldPreferOpen
		and router:ShouldPreferOpen()
end

local function applyPreferOpenReplacement()
	if not shouldPreferOpen() then
		return
	end
	if GF.EnsureBlizzardAddons then
		GF.EnsureBlizzardAddons()
	end
	local currentOpen = captureOriginalOpenBestWindow()
	if currentOpen
		and _G.LFGListUtil_OpenBestWindow ~= replacementOpenBestWindow
	then
		_G.LFGListUtil_OpenBestWindow = replacementOpenBestWindow
	end
	local currentQuest = captureOriginalFindQuestGroup()
	if currentQuest
		and _G.LFGListUtil_FindQuestGroup ~= replacementFindQuestGroup
	then
		_G.LFGListUtil_FindQuestGroup = replacementFindQuestGroup
	end
end

local function schedulePreferOpenReassertion()
	if not (C_Timer and C_Timer.After) then
		return
	end
	local ticket = refreshTicket
	local function reassert()
		if ticket == refreshTicket then
			applyPreferOpenReplacement()
		end
	end
	C_Timer.After(0, reassert)
	C_Timer.After(1, reassert)
	C_Timer.After(3, reassert)
end

function GF.Hook.OnGFUIClosed()
	-- Do not force Blizzard LFG active-panel refresh here; ApplicationViewer
	-- can handle secret listing text only in an untainted chain.
end

function GF.Hook.Refresh()
	refreshTicket = refreshTicket + 1
	if GF.EnsureBlizzardAddons then
		GF.EnsureBlizzardAddons()
	end
	captureOriginalOpenBestWindow()
	captureOriginalFindQuestGroup()
	local preferOpen = shouldPreferOpen()
	if preferOpen then
		applyPreferOpenReplacement()
		schedulePreferOpenReassertion()
	elseif _G.LFGListUtil_OpenBestWindow == replacementOpenBestWindow then
		_G.LFGListUtil_OpenBestWindow = origOpenBestWindow
	end
	if not preferOpen
		and _G.LFGListUtil_FindQuestGroup == replacementFindQuestGroup
	then
		_G.LFGListUtil_FindQuestGroup = origFindQuestGroup
	end
end
