import type { StartVariable } from '@/nodes/src/start'

export const RUN_WORKFLOW_QUERY_VARIABLE = 'query'

export function createEmptyValue(formType: string) {
	switch (formType) {
		case 'number':
			return undefined
		case 'checkbox':
			return false
		case 'file':
			return {}
		case 'file-list':
			return []
		case 'json_object':
			return {}
		default:
			return ''
	}
}

export function isEmptyValue(value: unknown, formType: string) {
	if (formType === 'checkbox') return false
	if (formType === 'number') {
		return value === null || value === undefined || Number.isNaN(Number(value))
	}
	if (formType === 'file-list') return !Array.isArray(value) || value.length === 0
	if (formType === 'file') {
		if (!value || Array.isArray(value) || typeof value !== 'object') return true
		return !Object.keys(value as Record<string, unknown>).length
	}
	if (formType === 'json_object') {
		return (
			!value ||
			typeof value !== 'object' ||
			Array.isArray(value) ||
			!Object.keys(value as Record<string, unknown>).length
		)
	}
	return !`${value ?? ''}`.trim()
}

export function buildExecuteParams(options: {
	startVariables: StartVariable[]
	inputValues: Record<string, any>
	jsonDrafts: Record<string, string>
	validationErrors: Record<string, string>
	validateVisibleRequired?: boolean
	excludeNames?: string[]
	translateFieldRequired: (name: string) => string
	translateInvalidJson: () => string
	translateFieldTooLong: (name: string, max: string) => string
}) {
	const {
		startVariables,
		inputValues,
		jsonDrafts,
		validationErrors,
		validateVisibleRequired = true,
		excludeNames = [],
		translateFieldRequired,
		translateInvalidJson,
		translateFieldTooLong
	} = options

	Object.keys(validationErrors).forEach((key) => {
		delete validationErrors[key]
	})

	const excluded = new Set(excludeNames)
	const params: Record<string, any> = {}
	let hasError = false

	startVariables.forEach((variable) => {
		const fieldName = variable.name
		if (!fieldName || excluded.has(fieldName)) return

		let value = structuredClone(inputValues[fieldName])

		if (variable.formType === 'json_object') {
			const draft = `${jsonDrafts[fieldName] || ''}`.trim()
			if (draft) {
				try {
					value = JSON.parse(draft)
				} catch {
					if (!variable.is_hide) {
						validationErrors[fieldName] = translateInvalidJson()
					}
					hasError = true
					return
				}
			} else {
				value = {}
			}

			if (!value || typeof value !== 'object' || Array.isArray(value)) {
				if (!variable.is_hide) {
					validationErrors[fieldName] = translateInvalidJson()
				}
				hasError = true
				return
			}
		}

		if (
			validateVisibleRequired &&
			!variable.is_hide &&
			variable.is_require &&
			isEmptyValue(value, variable.formType)
		) {
			validationErrors[fieldName] = translateFieldRequired(variable.label || fieldName)
			hasError = true
			return
		}

		if (
			!variable.is_hide &&
			['text-input', 'text-area'].includes(variable.formType) &&
			variable.max_length &&
			typeof value === 'string' &&
			value.length > variable.max_length
		) {
			validationErrors[fieldName] = translateFieldTooLong(
				variable.label || fieldName,
				`${variable.max_length}`
			)
			hasError = true
			return
		}

		params[fieldName] = value
	})

	return hasError ? null : params
}
