import { z } from "zod";
import nodeCron from "node-cron";
//#region src/cron/validation.ts
const cronExpression = z.string().superRefine((val, ctx) => {
	if (!nodeCron.validate(val)) ctx.addIssue({
		code: z.ZodIssueCode.custom,
		message: `Invalid cron expression: ${val}`
	});
});
const validTimezones = [
	"UTC",
	"America/New_York",
	"America/Chicago",
	"America/Denver",
	"America/Los_Angeles",
	"America/Toronto",
	"Europe/London",
	"Europe/Paris",
	"Europe/Berlin",
	"Europe/Moscow",
	"Asia/Tokyo",
	"Asia/Shanghai",
	"Asia/Hong_Kong",
	"Asia/Singapore",
	"Asia/Seoul",
	"Asia/Dubai",
	"Asia/Mumbai",
	"Australia/Sydney",
	"Pacific/Auckland"
];
const CronDeliveryMode = z.enum([
	"none",
	"announce",
	"direct"
]);
/** Treat `''` / `null` / whitespace-only as absent so optional fields do not fail `.min(1)` */
function optionalTrimmedString(max, min = 1) {
	return z.preprocess((v) => {
		if (v === null || v === void 0) return void 0;
		if (typeof v !== "string") return v;
		const t = v.trim();
		return t.length === 0 ? void 0 : t;
	}, z.string().min(min).max(max).optional());
}
/** Optional agent id on create; empty string → undefined. */
const optionalJobAgentId = optionalTrimmedString(64, 1);
/** Optional absolute workspace path on create; empty string → undefined. */
const optionalJobWorkingDirectory = optionalTrimmedString(4096, 1);
/**
* PATCH: set string, or `null` / empty to clear `workingDirectory` on the job.
*/
const patchJobWorkingDirectory = z.preprocess((v) => {
	if (v === null) return null;
	if (v === void 0) return void 0;
	if (typeof v !== "string") return v;
	const t = v.trim();
	return t.length === 0 ? null : t;
}, z.union([z.string().min(1).max(4096), z.null()]).optional());
/**
* PATCH: set string, or `null` / empty to clear `agentId` on the job.
*/
const patchJobAgentId = z.preprocess((v) => {
	if (v === null) return null;
	if (v === void 0) return void 0;
	if (typeof v !== "string") return v;
	const t = v.trim();
	return t.length === 0 ? null : t;
}, z.union([z.string().min(1).max(64), z.null()]).optional());
const CronSystemEventPayloadSchema = z.object({
	kind: z.literal("systemEvent"),
	text: z.string().min(1).max(5e4)
});
const CronAgentTurnPayloadSchema = z.object({
	kind: z.literal("agentTurn"),
	message: z.string().min(1).max(5e4),
	model: optionalTrimmedString(100, 1),
	timeoutSeconds: z.number().int().min(10).max(3600).optional()
});
const CronPayloadSchema = z.union([CronSystemEventPayloadSchema, CronAgentTurnPayloadSchema]);
const CronDeliverySchema = z.object({
	mode: CronDeliveryMode.default("none"),
	channel: optionalTrimmedString(32, 1),
	to: z.preprocess((v) => v === "" || v === null || v === void 0 ? void 0 : v, z.string().max(100).optional()),
	bestEffort: z.boolean().optional()
});
const JobDataSchema = z.object({
	id: z.string().min(1).max(32),
	name: z.string().max(100).optional(),
	schedule: cronExpression,
	enabled: z.boolean(),
	timezone: z.string().superRefine((val, ctx) => {
		if (val && !validTimezones.includes(val)) ctx.addIssue({
			code: z.ZodIssueCode.custom,
			message: `Invalid timezone: ${val}. Use IANA timezone names.`
		});
	}).optional(),
	maxRetries: z.number().int().min(0).max(10).default(3),
	timeout: z.number().int().min(1e3).max(3e5).default(18e4),
	created_at: z.string().datetime(),
	updated_at: z.string().datetime(),
	sessionTarget: z.enum(["main", "isolated"]).optional(),
	agentId: optionalTrimmedString(64, 1),
	workingDirectory: optionalJobWorkingDirectory,
	payload: CronPayloadSchema,
	delivery: CronDeliverySchema.optional(),
	model: optionalTrimmedString(100, 1),
	state: z.any().optional()
}).strict();
const AddJobRequestSchema = z.object({
	schedule: cronExpression,
	name: z.string().max(100).optional(),
	timezone: z.string().optional(),
	maxRetries: z.number().int().min(0).max(10).optional(),
	timeout: z.number().int().min(1e3).max(3e5).optional(),
	sessionTarget: z.enum(["main", "isolated"]).optional(),
	agentId: optionalJobAgentId,
	workingDirectory: optionalJobWorkingDirectory,
	payload: CronPayloadSchema,
	delivery: CronDeliverySchema.optional(),
	model: optionalTrimmedString(100, 1)
});
const UpdateJobRequestSchema = z.object({
	name: z.string().max(100).optional(),
	schedule: cronExpression.optional(),
	timezone: z.string().optional(),
	maxRetries: z.number().int().min(0).max(10).optional(),
	timeout: z.number().int().min(1e3).max(3e5).optional(),
	enabled: z.boolean().optional(),
	sessionTarget: z.enum(["main", "isolated"]).optional(),
	agentId: patchJobAgentId,
	workingDirectory: patchJobWorkingDirectory,
	payload: CronPayloadSchema.optional(),
	delivery: CronDeliverySchema.optional(),
	model: optionalTrimmedString(100, 1)
}).refine((data) => Object.keys(data).length > 0, { message: "At least one field must be provided for update" });
//#endregion
export { AddJobRequestSchema, JobDataSchema, UpdateJobRequestSchema, cronExpression };

//# sourceMappingURL=validation.js.map