import { z } from "@hono/zod-openapi";

//#region src/validation/json-schemas.ts
const JsonSchemaPropertyLazySchema = z.lazy(() => JsonSchemaPropertySchema).meta({
	type: "object",
	$ref: "#/components/schemas/JsonSchemaPropertySchema"
});
const JsonSchemaDescription = z.string("Each property must have a \"description\" for LLM compatibility").trim().nonempty("Each property must have a non-empty description for LLM compatibility").openapi("JsonSchemaPropertyDescription");
/**
* Zod schema representing a valid JSON Schema Draft 7 property.
*
* `z.lazy` are used for recursive fields (`items`, `properties`) so the schema
* can reference itself without causing an infinite loop at definition time.
* Without `z.lazy`, Zod would hit an infinite loop at definition time, not at runtime.
*/
const JsonSchemaPropertySchema = z.discriminatedUnion("type", [
	z.looseObject({
		type: z.enum([
			"string",
			"number",
			"integer",
			"boolean",
			"null"
		]),
		description: JsonSchemaDescription
	}),
	z.looseObject({
		type: z.literal("array"),
		description: JsonSchemaDescription,
		items: z.union([JsonSchemaPropertyLazySchema, z.array(JsonSchemaPropertyLazySchema)]).optional()
	}),
	z.looseObject({
		type: z.literal("object"),
		description: JsonSchemaDescription,
		properties: z.record(z.string(), JsonSchemaPropertyLazySchema).optional()
	})
], "Each property must have a valid \"type\"").openapi("JsonSchemaPropertySchema");
const JsonSchemaForLlmSchema = z.looseObject({
	type: z.literal("object", "Schema must have type: \"object\" for LLM compatibility"),
	properties: z.record(z.string(), JsonSchemaPropertySchema, "Schema must have a \"properties\" object"),
	required: z.array(z.string(), "Schema must have a \"required\" array").default([]).optional(),
	additionalProperties: z.boolean().optional(),
	description: z.string().trim().optional()
}, "Schema must be an object").superRefine((schema, ctx) => {
	for (const requiredProp of schema.required ?? []) {
		if (schema.properties[requiredProp]) continue;
		ctx.addIssue({
			code: "custom",
			path: ["required"],
			message: `Required property "${requiredProp}" must exist in properties`
		});
	}
}).openapi("JsonSchemaForLlmSchema");

//#endregion
export { JsonSchemaForLlmSchema };