import { useEffect } from "react" import type { RefObject } from "react" import { resolveAiEmbedOrigin } from "@/lib/ai/embed-url" function normalizePublicPath(publicPath: string): string { const path = (publicPath || "/ai").replace(/\/$/, "") || "/ai" return path.startsWith("/") ? path : `/${path}` } /** Ultimail suite routes — never prefix with /ai (would 404 in OpenWebUI). */ const SUITE_ROOT_PATHS = new Set([ "/mail", "/drive", "/chat", "/contacts", "/cloud", "/agenda", "/office", ]) function isSuiteRoute(pathname: string): boolean { for (const root of SUITE_ROOT_PATHS) { if (pathname === root || pathname.startsWith(`${root}/`)) return true } return false } /** Keep UltiAI iframe on the OpenWebUI subpath (e.g. /ai) — block suite landing at /. */ export function useAiIframeNavigation( iframeRef: RefObject, publicPath: string ) { useEffect(() => { const iframe = iframeRef.current if (!iframe) return const base = normalizePublicPath(publicPath) const embedOrigin = resolveAiEmbedOrigin(publicPath) const enforceBasePath = () => { try { const win = iframe.contentWindow if (!win) return const { pathname, search, hash, origin } = win.location if (embedOrigin && origin !== embedOrigin) return const inBase = pathname === base || pathname.startsWith(`${base}/`) if (inBase) return // Suite landing or explicit suite module — stay on OpenWebUI home. if (pathname === "/" || pathname === "" || isSuiteRoute(pathname)) { win.location.replace(`${base}/${search}${hash}`) return } // OpenWebUI route without /ai prefix (e.g. /notes, /workspace) — preserve path. win.location.replace(`${base}${pathname}${search}${hash}`) } catch { // Cross-origin — parent cannot read location. } } iframe.addEventListener("load", enforceBasePath) const timer = window.setInterval(enforceBasePath, 400) return () => { iframe.removeEventListener("load", enforceBasePath) window.clearInterval(timer) } }, [iframeRef, publicPath]) } /** Open external links from the embed in the parent tab, not inside the iframe. */ export function useAiIframeExternalLinks(embedOrigin: string) { useEffect(() => { if (!embedOrigin) return const onMessage = (event: MessageEvent) => { if (event.origin !== embedOrigin) return const data = event.data as { type?: string; href?: string } | null if (data?.type !== "ULTI_OPEN_LINK" || typeof data.href !== "string") return window.open(data.href, "_blank", "noopener,noreferrer") } window.addEventListener("message", onMessage) return () => window.removeEventListener("message", onMessage) }, [embedOrigin]) }