import { Worker } from "node:worker_threads";
import { resizeImageInProcess } from "./image-resize-core.js";
function toTransferableBytes(input) {
    // Transfer detaches the buffer, so transfer a worker-owned copy and leave the
    // caller's bytes intact.
    return new Uint8Array(input);
}
function isResizeImageWorkerResponse(value) {
    return value !== null && typeof value === "object";
}
function createResizeWorker(workerSpecifier) {
    return new Worker(workerSpecifier);
}
async function resizeImageInWorker(workerSpecifier, inputBytes, mimeType, options) {
    const worker = createResizeWorker(workerSpecifier);
    try {
        const inputBytesForWorker = toTransferableBytes(inputBytes);
        return await new Promise((resolve, reject) => {
            let settled = false;
            const settle = (result) => {
                if (settled)
                    return;
                settled = true;
                resolve(result);
            };
            const fail = (error) => {
                if (settled)
                    return;
                settled = true;
                reject(error);
            };
            worker.once("message", (message) => {
                if (!isResizeImageWorkerResponse(message)) {
                    fail(new Error("Invalid image resize worker response"));
                    return;
                }
                if (message.error) {
                    fail(new Error(message.error));
                    return;
                }
                settle(message.result ?? null);
            });
            worker.once("error", fail);
            worker.once("exit", (code) => {
                if (!settled) {
                    fail(new Error(`Image resize worker exited with code ${code}`));
                }
            });
            worker.postMessage({
                inputBytes: inputBytesForWorker,
                mimeType,
                options,
            }, [inputBytesForWorker.buffer]);
        });
    }
    finally {
        void worker.terminate().catch(() => undefined);
    }
}
/**
 * Resize an image to fit within the specified max dimensions and encoded file size.
 * Runs Photon in a worker thread so WASM decoding, resizing, and encoding do not
 * block the TUI event loop. If the worker cannot be loaded (for example in some
 * Bun compiled executable layouts), fall back to in-process resizing so image
 * reads still work.
 */
export async function resizeImage(inputBytes, mimeType, options) {
    const isTypeScriptRuntime = import.meta.url.endsWith(".ts");
    const workerUrl = new URL(isTypeScriptRuntime ? "./image-resize-worker.ts" : "./image-resize-worker.js", import.meta.url);
    // Bun compiled executables resolve worker entrypoints by string path, not via
    // new URL(..., import.meta.url). Try the string path first under Bun so the
    // release binary uses the embedded worker instead of falling back in-process.
    if (typeof process.versions.bun === "string") {
        try {
            return await resizeImageInWorker("./src/utils/image-resize-worker.ts", inputBytes, mimeType, options);
        }
        catch { }
    }
    try {
        return await resizeImageInWorker(workerUrl, inputBytes, mimeType, options);
    }
    catch {
        return resizeImageInProcess(inputBytes, mimeType, options);
    }
}
/**
 * Format a dimension note for resized images.
 * This helps the model understand the coordinate mapping.
 */
export function formatDimensionNote(result) {
    if (!result.wasResized) {
        return undefined;
    }
    const scale = result.originalWidth / result.width;
    return `[Image: original ${result.originalWidth}x${result.originalHeight}, displayed at ${result.width}x${result.height}. Multiply coordinates by ${scale.toFixed(2)} to map to original image.]`;
}
//# sourceMappingURL=image-resize.js.map