import { EmptyRequest, StringRequest } from "@shared/proto/cline/common"
import open from "open"
import { HostProvider } from "@/hosts/host-provider"

/**
 * Writes text to the system clipboard
 * @param text The text to write to the clipboard
 * @returns Promise that resolves when the operation is complete
 * @throws Error if the operation fails
 */
export async function writeTextToClipboard(text: string): Promise<void> {
	try {
		await HostProvider.env.clipboardWriteText(StringRequest.create({ value: text }))
	} catch (error) {
		const errorMessage = error instanceof Error ? error.message : String(error)
		throw new Error(`Failed to write to clipboard: ${errorMessage}`)
	}
}

/**
 * Reads text from the system clipboard
 * @returns Promise that resolves to the clipboard text
 * @throws Error if the operation fails
 */
export async function readTextFromClipboard(): Promise<string> {
	try {
		const response = await HostProvider.env.clipboardReadText(EmptyRequest.create({}))
		return response.value
	} catch (error) {
		const errorMessage = error instanceof Error ? error.message : String(error)
		throw new Error(`Failed to read from clipboard: ${errorMessage}`)
	}
}

/**
 * Opens an external URL in the default browser
 * @param url The URL to open
 * @returns Promise that resolves when the operation is complete
 * @throws Error if the operation fails
 */
export async function openExternal(url: string): Promise<void> {
	console.log("Opening browser:", url)
	await open(url)
}

/**
 * Opens `filePath` in a specific application (by binary path/name) rather than the OS default —
 * e.g. handing a captured `.pcap`/`.btmon` off to Wireshark. Spawns detached; resolves once launched,
 * does not wait for the app to exit.
 * @throws Error if the operation fails
 */
export async function openWithApp(filePath: string, appPath: string): Promise<void> {
	console.log("Opening in app:", appPath, filePath)
	try {
		await open(filePath, { app: { name: appPath } })
	} catch (error) {
		const errorMessage = error instanceof Error ? error.message : String(error)
		throw new Error(`Failed to open ${filePath} in ${appPath}: ${errorMessage}`)
	}
}
