import { describe, expect, test } from "bun:test";
import { AiEventRequestSchema } from "@/lib/types";

// ---------------------------------------------------------------------------
// AiEventRequestSchema – behavioral validation tests
//
// The schema is the contract between the client and the API route.
// Tests verify what the schema ALLOWS and what it REJECTS.
// ---------------------------------------------------------------------------

const VALID_PNG =
	"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==";
const VALID_JPEG =
	"data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEASABIAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFAABAAAAAAAAAAAAAAAAAAAACf/EABQQAQAAAAAAAAAAAAAAAAAAAAD/xAAUAQEAAAAAAAAAAAAAAAAAAAAA/8QAFBEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AJQAB/9k=";

describe("AiEventRequestSchema – images array", () => {
	test("accepts a prompt with no images", () => {
		const result = AiEventRequestSchema.safeParse({ prompt: "Team standup every Monday at 9am" });
		expect(result.success).toBe(true);
	});

	test("accepts images array with one valid base64 image", () => {
		const result = AiEventRequestSchema.safeParse({
			prompt: "What events are on this flyer?",
			images: [VALID_PNG],
		});
		expect(result.success).toBe(true);
	});

	test("accepts images array with multiple valid base64 images", () => {
		const result = AiEventRequestSchema.safeParse({
			images: [VALID_PNG, VALID_JPEG],
		});
		expect(result.success).toBe(true);
		if (result.success) {
			expect(result.data.images).toHaveLength(2);
		}
	});

	test("accepts request with images only (no prompt)", () => {
		const result = AiEventRequestSchema.safeParse({ images: [VALID_PNG] });
		expect(result.success).toBe(true);
	});

	test("rejects request with neither prompt nor images", () => {
		const result = AiEventRequestSchema.safeParse({});
		expect(result.success).toBe(false);
	});

	test("rejects images array containing an invalid data URL", () => {
		const result = AiEventRequestSchema.safeParse({
			images: ["not-a-data-url"],
		});
		expect(result.success).toBe(false);
	});

	test("rejects images array containing a non-image data URL (e.g. PDF)", () => {
		const result = AiEventRequestSchema.safeParse({
			images: ["data:application/pdf;base64,abc123"],
		});
		expect(result.success).toBe(false);
	});

	test("rejects empty images array (must have at least one image OR a prompt)", () => {
		// An empty images array with no prompt should fail the 'prompt or images' refinement
		const result = AiEventRequestSchema.safeParse({ images: [] });
		expect(result.success).toBe(false);
	});

	test("returns data.images as string[] when images are valid", () => {
		const result = AiEventRequestSchema.safeParse({
			images: [VALID_PNG, VALID_JPEG],
		});
		expect(result.success).toBe(true);
		if (result.success) {
			expect(Array.isArray(result.data.images)).toBe(true);
			for (const img of result.data.images ?? []) {
				expect(typeof img).toBe("string");
			}
		}
	});
});

describe("AiEventRequestSchema – prompt validation", () => {
	test("accepts a plain text prompt with no images", () => {
		const result = AiEventRequestSchema.safeParse({ prompt: "Birthday party Saturday" });
		expect(result.success).toBe(true);
	});

	test("rejects a prompt that exceeds 2000 characters", () => {
		const longPrompt = "a".repeat(2001);
		const result = AiEventRequestSchema.safeParse({ prompt: longPrompt });
		expect(result.success).toBe(false);
	});

	test("accepts a prompt of exactly 2000 characters", () => {
		const maxPrompt = "a".repeat(2000);
		const result = AiEventRequestSchema.safeParse({ prompt: maxPrompt });
		expect(result.success).toBe(true);
	});
});
