// Shared Event Emission for webview lifecycle events
// Uses __sparkbunEventBridge which is available on ALL webviews (including sandboxed)
// Falls back to __sparkbunInternalBridge for backwards compatibility until native code
// is updated to include the eventBridge handler
// This is a one-way channel for emitting events to native/bun - no RPC capability

import "./globals.d.ts";

// Emit a webview event to native code
export function emitWebviewEvent(eventName: string, detail: string) {
	// setTimeout works around a race condition with Bun FFI
	setTimeout(() => {
		// Prefer eventBridge (available on all webviews), fall back to internalBridge
		// (for backwards compatibility until native code adds eventBridge handler)
		const bridge =
			window.__sparkbunEventBridge || window.__sparkbunInternalBridge;
		bridge?.postMessage(
			JSON.stringify({
				id: "webviewEvent",
				type: "message",
				payload: {
					id: window.__sparkbunWebviewId,
					eventName,
					detail,
				},
			}),
		);
	});
}

// Set up standard lifecycle event listeners
export function initLifecycleEvents() {
	// Emit dom-ready when page loads (top-level window only)
	window.addEventListener("load", () => {
		if (window === window.top) {
			emitWebviewEvent("dom-ready", document.location.href);
		}
	});

	// Track in-page navigation
	window.addEventListener("popstate", () => {
		emitWebviewEvent("did-navigate-in-page", window.location.href);
	});

	window.addEventListener("hashchange", () => {
		emitWebviewEvent("did-navigate-in-page", window.location.href);
	});
}

// Track cmd key state for SPA navigation detection
let cmdKeyHeld = false;
let cmdKeyTimestamp = 0;
const CMD_KEY_THRESHOLD_MS = 500;

export function isCmdHeld(): boolean {
	if (cmdKeyHeld) return true;
	return (
		Date.now() - cmdKeyTimestamp < CMD_KEY_THRESHOLD_MS && cmdKeyTimestamp > 0
	);
}

// Set up cmd+click detection for opening links in new windows
export function initCmdClickHandling() {
	window.addEventListener(
		"keydown",
		(event) => {
			if (event.key === "Meta" || event.metaKey) {
				cmdKeyHeld = true;
				cmdKeyTimestamp = Date.now();
			}
		},
		true,
	);

	window.addEventListener(
		"keyup",
		(event) => {
			if (event.key === "Meta") {
				cmdKeyHeld = false;
				cmdKeyTimestamp = Date.now();
			}
		},
		true,
	);

	window.addEventListener("blur", () => {
		cmdKeyHeld = false;
	});

	// Intercept cmd+clicks on anchors before SPA frameworks can handle them
	window.addEventListener(
		"click",
		(event) => {
			if (event.metaKey || event.ctrlKey) {
				const anchor = (event.target as HTMLElement)?.closest?.("a");
				if (anchor && (anchor as HTMLAnchorElement).href) {
					event.preventDefault();
					event.stopPropagation();
					event.stopImmediatePropagation();
					emitWebviewEvent(
						"new-window-open",
						JSON.stringify({
							url: (anchor as HTMLAnchorElement).href,
							isCmdClick: true,
							isSPANavigation: false,
						}),
					);
				}
			}
		},
		true,
	);
}

// Intercept SPA navigation (history.pushState/replaceState) when cmd is held
export function initSPANavigationInterception() {
	const originalPushState = history.pushState;
	const originalReplaceState = history.replaceState;

	history.pushState = function (
		state: unknown,
		title: string,
		url?: string | URL | null,
	) {
		if (isCmdHeld() && url) {
			const resolvedUrl = new URL(String(url), window.location.href).href;
			emitWebviewEvent(
				"new-window-open",
				JSON.stringify({
					url: resolvedUrl,
					isCmdClick: true,
					isSPANavigation: true,
				}),
			);
			return;
		}
		return originalPushState.apply(this, [state, title, url]);
	};

	history.replaceState = function (
		state: unknown,
		title: string,
		url?: string | URL | null,
	) {
		if (isCmdHeld() && url) {
			const resolvedUrl = new URL(String(url), window.location.href).href;
			emitWebviewEvent(
				"new-window-open",
				JSON.stringify({
					url: resolvedUrl,
					isCmdClick: true,
					isSPANavigation: true,
				}),
			);
			return;
		}
		return originalReplaceState.apply(this, [state, title, url]);
	};
}

// Prevent overscroll bounce effect
export function initOverscrollPrevention() {
	document.addEventListener("DOMContentLoaded", () => {
		const style = document.createElement("style");
		style.type = "text/css";
		style.appendChild(
			document.createTextNode("html, body { overscroll-behavior: none; }"),
		);
		document.head.appendChild(style);
	});
}
