local _, GF = ...

-- NativeEntryRouter owns routing decisions only. Hook.lua remains the adapter
-- that captures, replaces, reasserts, and restores Blizzard's global entries.
GF.NativeEntryRouter = GF.NativeEntryRouter or {}
local Router = GF.NativeEntryRouter

local function dismissPanel(panel)
	local visible = panel and type(panel.IsShown) == "function"
		and panel:IsShown()
	if visible and type(HideUIPanel) == "function" then
		HideUIPanel(panel)
	end
end

function Router:DismissNativePremadeFrames()
	dismissPanel(PVEFrame)
	dismissPanel(PVPUIFrame)
end

function Router:ShouldPreferOpen()
	local db = GF.GetDB and GF.GetDB()
	return db and db.preferOpen
end

function Router:HasActiveOutgoingApplication()
	local applications = GF.Apply
	local query = applications and applications.HasActiveApplication
	return type(query) == "function" and query(applications) == true
end

local function selectGFTab(tabID)
	if not GF.TabBar then
		return
	end
	if GF.TabBar.Select then
		GF.TabBar:Select(tabID)
	elseif GF.TabBar.SelectTab then
		GF.TabBar:SelectTab(tabID)
	end
end

function Router:OpenGroupFinderFromPremadeEntry(toggle)
	if not GF.MainFrame then
		return
	end
	local targetTab = self:HasActiveOutgoingApplication()
		and GF.TAB_BROWSE or GF.TAB_CREATE
	local frame = GF.MainFrame.frame
	local currentTab = GF.TabBar and GF.TabBar.GetCurrent
		and GF.TabBar:GetCurrent()
	local userVisible = GF.MainFrame.IsUserVisible
		and GF.MainFrame:IsUserVisible()
		or (not GF.MainFrame.IsUserVisible
			and frame and frame:IsShown())
	if toggle and userVisible and currentTab == targetTab then
		GF.MainFrame:HideFrame()
	else
		if GF.MainFrame.OpenRoute then
			GF.MainFrame:OpenRoute({ tabID = targetTab })
		elseif targetTab == GF.TAB_BROWSE and GF.MainFrame.OpenBrowseTab then
			GF.MainFrame:OpenBrowseTab()
		elseif GF.MainFrame.OpenCreateTab then
			GF.MainFrame:OpenCreateTab()
		else
			GF.MainFrame:OpenFrame()
		end
		if C_Timer and C_Timer.After then
			C_Timer.After(0, function()
				if GF.MainFrame
					and ((GF.MainFrame.IsUserVisible
						and GF.MainFrame:IsUserVisible())
						or (not GF.MainFrame.IsUserVisible
							and GF.MainFrame.frame
							and GF.MainFrame.frame:IsShown()))
					and GF.TabBar
				then
					selectGFTab(targetTab)
				end
			end)
		end
	end
	self:DismissNativePremadeFrames()
end

function Router:ShouldUseNativeOpenBestWindow()
	-- The unresolved 12.1 censored edit handoff must stay in Blizzard's
	-- creation container. The replacement popup normally intercepts it first.
	local listing = GF.RecruitmentSession
	if listing and listing.GetActiveCensoredState then
		local state = listing:GetActiveCensoredState()
		return state
			and state.state == listing.ACTIVE_CENSOR_STATE_UNRESOLVED
	end
	return false
end

function Router:RouteOpenBestWindow(original, toggle)
	if type(original) == "function" and self:ShouldUseNativeOpenBestWindow() then
		return original(toggle)
	end
	return self:OpenGroupFinderFromPremadeEntry(toggle)
end

function Router:IsGreenEyeSource(value)
	if type(canaccessvalue) == "function" then
		local ok, accessible = pcall(canaccessvalue, value)
		if not ok or accessible ~= true then
			return false
		end
	end
	if type(issecretvalue) == "function" then
		local ok, secret = pcall(issecretvalue, value)
		if not ok or secret == true then
			return false
		end
	end
	return value == true
end

function Router:RouteFindQuestGroup(
	original, questID, isFromGreenEyeButton)
	if self:IsGreenEyeSource(isFromGreenEyeButton)
		and self:ShouldPreferOpen()
		and GF.FindGroupTab
		and type(GF.FindGroupTab.FindQuestGroup) == "function"
	then
		local requestState = {}
		local ok, tookOwnership = pcall(
			GF.FindGroupTab.FindQuestGroup,
			GF.FindGroupTab,
			questID,
			requestState
		)
		if (ok and tookOwnership == true)
			or requestState.tookOwnership == true
		then
			self:DismissNativePremadeFrames()
			return
		end
	end
	if type(original) == "function" then
		return original(questID, isFromGreenEyeButton)
	end
end
