/**
 * Reports the device's network transport to the Rust backend, so the download
 * queue can honour the "WiFi Only" setting.
 *
 * Android exposes the real transport through the `AndroidNetworkType`
 * JavascriptInterface (backed by NetworkCapabilities). On desktop that
 * interface is absent and we report nothing — the backend defaults to unmetered
 * ethernet, so desktop downloads are never gated.
 *
 * TRACES: UR-053 | DR-074
 */

import { commands } from '$lib/api/bindings';
import type { NetworkType } from '$lib/api/bindings';

/** The Android bridge, present only in the Android WebView. */
interface AndroidNetworkTypeBridge {
	currentType(): NetworkType;
	isUnmetered(): boolean;
	isAcceptable(wifiOnly: boolean): boolean;
	isSupported(): boolean;
}

declare global {
	interface Window {
		AndroidNetworkType?: AndroidNetworkTypeBridge;
	}
}

/** Event dispatched into the WebView by MainActivity on any network change. */
const NETWORK_CHANGED_EVENT = 'jellytau-network-changed';

function bridge(): AndroidNetworkTypeBridge | undefined {
	if (typeof window === 'undefined') return undefined;
	return window.AndroidNetworkType;
}

/** Whether native network detection is available (Android only). */
export function isNetworkDetectionSupported(): boolean {
	try {
		return bridge()?.isSupported() ?? false;
	} catch {
		return false;
	}
}

/**
 * Read the current transport from Android and push it into Rust.
 *
 * No-op on desktop, where the backend's unmetered-ethernet default already
 * means downloads run unconditionally.
 */
export async function reportNetworkState(): Promise<void> {
	const android = bridge();
	if (!android) return;

	try {
		const networkType = android.currentType();
		const unmetered = android.isUnmetered();

		await commands.setNetworkState({ networkType, unmetered });
	} catch (error) {
		// Never let network reporting break the UI — the gate fails closed on
		// the Rust side, so a missed report at worst delays a queued download.
		console.warn('[NetworkType] Failed to report network state:', error);
	}
}

/**
 * Start reporting network state: once immediately, then on every native network
 * change. Reporting an acceptable network re-pumps the download queue on the
 * Rust side, so a queue parked on "waiting for WiFi" drains itself.
 *
 * Returns a teardown function.
 */
export function startNetworkReporting(): () => void {
	if (typeof window === 'undefined') return () => {};

	void reportNetworkState();

	const onChange = () => {
		void reportNetworkState();
	};

	window.addEventListener(NETWORK_CHANGED_EVENT, onChange);
	// The browser's own online/offline events are a useful extra nudge on
	// desktop-style webviews where the native callback may not fire.
	window.addEventListener('online', onChange);
	window.addEventListener('offline', onChange);

	return () => {
		window.removeEventListener(NETWORK_CHANGED_EVENT, onChange);
		window.removeEventListener('online', onChange);
		window.removeEventListener('offline', onChange);
	};
}

/**
 * Whether downloads are currently permitted by the WiFi-only gate. Used by the
 * downloads UI to show "Waiting for WiFi" instead of a stuck-looking queue.
 */
export async function areDownloadsAllowed(): Promise<boolean> {
	try {
		return await commands.getDownloadsAllowed();
	} catch (error) {
		console.warn('[NetworkType] Failed to query download gate:', error);
		return true;
	}
}
