import type { IWorkflowSettings, WorkflowFEMeta } from 'n8n-workflow';
import z from 'zod';

export const nodeSchema = z
	.object({
		name: z.string(),
		type: z.string(),
	})
	.passthrough();

export const tagSchema = z.object({ id: z.string(), name: z.string() }).passthrough();

export const toTagSummary = (tags: Array<{ id: string; name: string }> | undefined | null) =>
	(tags ?? []).map((tag) => ({ id: tag.id, name: tag.name }));

export const workflowSettingsSchema = z
	.custom<IWorkflowSettings>((_value): _value is IWorkflowSettings => true)
	.nullable();

export const workflowMetaSchema = z
	.custom<WorkflowFEMeta>((_value): _value is WorkflowFEMeta => true)
	.nullable();

export const dataTableColumnTypeSchema = z
	.enum(['string', 'number', 'boolean', 'date'])
	.describe('The data type of the column');

export const dataTableColumnSchema = z.object({
	id: z.string().describe('The unique identifier of the column'),
	name: z.string().describe('The name of the column'),
	type: dataTableColumnTypeSchema,
	index: z.number().int().describe('The position of the column in the table'),
});

export const dataTableSchema = z.object({
	id: z.string().describe('Autogenerated unique identifier of the data table.'),
	name: z.string().describe('The name of the data table'),
	projectId: z.string().describe('The project this data table belongs to'),
	createdAt: z.string().describe('Autogenerated ISO timestamp when the data table was created'),
	updatedAt: z
		.string()
		.describe('Autogenerated ISO timestamp when the data table was last updated'),
	columns: z.array(dataTableColumnSchema).describe('The columns defined in this data table'),
});

export const createLimitSchema = (max: number) =>
	z
		.number()
		.int()
		.positive()
		.max(max)
		.optional()
		.describe(`Limit the number of results (max ${max})`);

export const dataTableProjectIdSchema = z
	.string()
	.describe('The project ID the data table belongs to');

export const columnNameSchema = z
	.string()
	.min(1)
	.max(63)
	.regex(/^[a-zA-Z][a-zA-Z0-9_]*$/)
	.describe(
		'Column name. Must start with a letter, contain only letters, numbers, and underscores (max 63 chars)',
	);

export const successMessageOutputSchema = {
	success: z.boolean().describe('Whether the operation succeeded'),
	message: z.string().describe('Description of the result'),
} satisfies z.ZodRawShape;

const nodeGroupSchema = z
	.object({
		id: z.string(),
		name: z.string(),
		nodeIds: z.array(z.string()),
	})
	.describe('A named visual grouping of nodes');

export const workflowDetailsOutputSchema = z.object({
	workflow: z
		.object({
			id: z.string(),
			name: z.string().nullable(),
			active: z.boolean(),
			isArchived: z.boolean(),
			versionId: z.string().describe('The current workflow version ID'),
			activeVersionId: z
				.string()
				.nullable()
				.describe('The active workflow version ID, if available'),
			triggerCount: z.number(),
			createdAt: z.string().nullable(),
			updatedAt: z.string().nullable(),
			settings: workflowSettingsSchema,
			connections: z.record(z.unknown()),
			nodes: z.array(nodeSchema),
			nodeGroups: z.array(nodeGroupSchema).describe('Node groups in the workflow'),
			activeVersion: z
				.object({
					nodes: z.array(nodeSchema),
					connections: z.record(z.unknown()),
					nodeGroups: z.array(nodeGroupSchema).describe('Node groups in the active version'),
				})
				.nullable()
				.describe('Active workflow graph, if available'),
			tags: z.array(tagSchema),
			meta: workflowMetaSchema,
			parentFolderId: z.string().nullable(),
			description: z.string().optional().describe('The description of the workflow'),
			scopes: z.array(z.string()).describe('User permissions for this workflow'),
			canExecute: z.boolean().describe('Whether the user has permission to execute this workflow'),
		})
		.passthrough()
		.describe('Sanitized workflow data safe for MCP consumption'),
	triggerInfo: z
		.string()
		.describe('Human-readable instructions describing how to trigger the workflow'),
});
