import { getLogger as getLogger$1 } from "../../../logger.js";
import { ImageUrlSchema } from "../types/chat.js";
import { z } from "@hono/zod-openapi";
import { FilePartSchema, TextPartSchema } from "@inkeep/agents-core";

//#region src/domains/run/utils/message-parts.ts
const logger = getLogger$1("message-parts");
const isTextContentItem = (item) => {
	return item.type === "text" && "text" in item && typeof item.text === "string";
};
const isImageContentItem = (item) => {
	return item.type === "image_url" && "image_url" in item && item.image_url != null && ImageUrlSchema.safeParse(item.image_url.url).success;
};
const textContentPartSchema = z.object({
	type: z.literal("text"),
	text: z.string()
});
const imageContentPartSchema = z.object({
	type: z.literal("image"),
	text: ImageUrlSchema
});
const vercelMessageContentPartSchema = z.union([textContentPartSchema, imageContentPartSchema]);
const buildTextPart = (text) => {
	return TextPartSchema.parse({
		kind: "text",
		text
	});
};
const parseDataUri = (dataUri) => {
	const match = dataUri.match(/^data:([^;]+);base64,(.+)$/);
	if (!match) return null;
	return {
		mimeType: match[1],
		base64Data: match[2]
	};
};
const buildFilePart = (uri, options) => {
	const parsed = parseDataUri(uri);
	if (parsed) return FilePartSchema.parse({
		kind: "file",
		file: {
			bytes: parsed.base64Data,
			mimeType: parsed.mimeType
		},
		...options?.detail && { metadata: { detail: options.detail } }
	});
	try {
		new URL(uri);
	} catch {
		throw new Error(`Invalid image URI: expected valid data URI or HTTP URL`);
	}
	return FilePartSchema.parse({
		kind: "file",
		file: {
			uri,
			mimeType: "image/*"
		},
		...options?.detail && { metadata: { detail: options.detail } }
	});
};
const extractTextFromParts = (parts) => {
	return parts.filter((p) => p.kind === "text").map((p) => p.text).join(" ");
};
const getMessagePartsFromOpenAIContent = (content) => {
	if (typeof content === "string") return [buildTextPart(content)];
	const textChunks = [];
	const imageParts = [];
	let skipped = 0;
	for (const item of content) if (isTextContentItem(item)) textChunks.push(item.text);
	else if (isImageContentItem(item)) imageParts.push(buildFilePart(item.image_url.url, { detail: item.image_url.detail }));
	else skipped += 1;
	if (skipped > 0) logger.warn({
		total: content.length,
		skipped,
		accepted: content.length - skipped
	}, "Some content items were dropped due to invalid or unsupported type");
	return [...textChunks.length > 0 ? [buildTextPart(textChunks.join(" "))] : [], ...imageParts];
};
const getMessagePartsFromVercelContent = (content, parts) => {
	if (typeof content === "string") return [buildTextPart(content)];
	const rawParts = parts ?? [];
	const parsedParts = rawParts.map((part) => vercelMessageContentPartSchema.safeParse(part)).filter((result) => result.success).map((result) => result.data);
	if (parsedParts.length < rawParts.length) logger.warn({
		expected: rawParts.length,
		received: parsedParts.length
	}, "Some message parts were dropped due to invalid schema");
	const assertNever = (x) => {
		throw new Error(`Unexpected part type: ${JSON.stringify(x)}`);
	};
	return parsedParts.map((part) => {
		if (part.type === "text") return buildTextPart(part.text);
		if (part.type === "image") return buildFilePart(part.text);
		return assertNever(part);
	});
};

//#endregion
export { extractTextFromParts, getMessagePartsFromOpenAIContent, getMessagePartsFromVercelContent };