import { describe, expect, test } from "bun:test";
import { buildMultimodalMessages } from "@/lib/ai-event-messages";

// ---------------------------------------------------------------------------
// buildMultimodalMessages – behavioral tests
//
// Public behavior under test: given a system prompt, an optional text prompt,
// and an array of base64 image strings, returns a well-formed messages array
// for the OpenRouter chat API.
//
// We test WHAT the function produces (message structure), not HOW it does it.
// ---------------------------------------------------------------------------

const SYSTEM_PROMPT = "You are an assistant…";
const FAKE_PNG = "data:image/png;base64,abc123";
const FAKE_JPEG = "data:image/jpeg;base64,def456";

describe("buildMultimodalMessages – message structure", () => {
	test("first message is always the system prompt", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "hello", [FAKE_PNG]);
		expect(messages[0].role).toBe("system");
		expect((messages[0].content as string)).toBe(SYSTEM_PROMPT);
	});

	test("second message is the user message", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "hello", [FAKE_PNG]);
		expect(messages[1].role).toBe("user");
	});

	test("user message content array starts with the text part", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "any prompt", [FAKE_PNG]);
		const userContent = messages[1].content as Array<{ type: string }>;
		expect(userContent[0].type).toBe("text");
	});

	test("user message content array includes one image_url part per image", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "prompt", [FAKE_PNG, FAKE_JPEG]);
		const userContent = messages[1].content as Array<{ type: string }>;
		const imageparts = userContent.filter((p) => p.type === "image_url");
		expect(imageparts).toHaveLength(2);
	});

	test("each image_url part carries the correct base64 URL", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, undefined, [FAKE_PNG, FAKE_JPEG]);
		const userContent = messages[1].content as Array<{
			type: string;
			imageUrl?: { url: string };
		}>;
		const imageParts = userContent.filter((p) => p.type === "image_url");
		expect(imageParts[0].imageUrl?.url).toBe(FAKE_PNG);
		expect(imageParts[1].imageUrl?.url).toBe(FAKE_JPEG);
	});

	test("text part uses a fallback when prompt is undefined", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, undefined, [FAKE_PNG]);
		const userContent = messages[1].content as Array<{
			type: string;
			text?: string;
		}>;
		const textPart = userContent.find((p) => p.type === "text");
		expect(typeof textPart?.text).toBe("string");
		expect(textPart?.text?.length ?? 0).toBeGreaterThan(0);
	});

	test("text part carries the provided prompt text when given", () => {
		const prompt = "Extract all events from these flyers";
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, prompt, [FAKE_PNG]);
		const userContent = messages[1].content as Array<{
			type: string;
			text?: string;
		}>;
		const textPart = userContent.find((p) => p.type === "text");
		expect(textPart?.text).toBe(prompt);
	});

	test("produces exactly 2 messages (system + user)", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "x", [FAKE_PNG]);
		expect(messages).toHaveLength(2);
	});

	test("single image produces content array of length 2 (1 text + 1 image)", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "x", [FAKE_PNG]);
		const userContent = messages[1].content as unknown[];
		expect(userContent).toHaveLength(2);
	});

	test("three images produce content array of length 4 (1 text + 3 images)", () => {
		const messages = buildMultimodalMessages(SYSTEM_PROMPT, "x", [
			FAKE_PNG,
			FAKE_JPEG,
			FAKE_PNG,
		]);
		const userContent = messages[1].content as unknown[];
		expect(userContent).toHaveLength(4);
	});
});
