import { getNodeType } from "../core/dist/esm/dictionaryManipulator/getNodeType.mjs";
import { NodeType } from "../types/dist/esm/nodeType.mjs";
import { IndentationText, NewLineKind, Node, Project, QuoteKind, SyntaxKind, ts } from "ts-morph";

//#region ../chokidar/dist/esm/writeContentDeclaration/transformJSFile.mjs
/**
* Builds a translation initializer string for the 't' function call.
* Creates a properly formatted translation object with locale keys and values.
*
* @param translationMap - Map of locale codes to translation values
* @param typeArgumentsText - Optional generic type arguments for the translation function
* @returns Formatted string for the translation function call
*/
const buildTranslationInitializer = (translationMap, typeArgumentsText) => {
	const translationEntries = Object.entries(translationMap).sort(([firstKey], [secondKey]) => firstKey.localeCompare(secondKey));
	const translationParts = [];
	for (const [localeCode, translationValue] of translationEntries) {
		const formattedLocaleKey = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(localeCode) ? localeCode : JSON.stringify(localeCode);
		if (typeof translationValue === "string") translationParts.push(`${formattedLocaleKey}: ${JSON.stringify(translationValue)}`);
		else if (Array.isArray(translationValue)) {
			const serializedArrayElements = translationValue.map((arrayElement) => JSON.stringify(arrayElement)).join(", ");
			translationParts.push(`${formattedLocaleKey}: [ ${serializedArrayElements} ]`);
		} else translationParts.push(`${formattedLocaleKey}: ${JSON.stringify(translationValue)}`);
	}
	return `t${typeArgumentsText ?? ""}({ ${translationParts.join(", ")} })`;
};
/**
* Synchronizes numeric suffixes across locales to maintain consistency.
* When updating a fallback locale's numeric suffix, this function updates
* the corresponding numeric suffixes in other locales to match.
*
* This is useful for maintaining numbered lists across translations,
* e.g., "Hello 1" / "Bonjour 1" when updating to "Hello 3".
*
* @param existingTranslationMap - Current translation map with locale values
* @param fallbackLocaleCode - The locale being updated (fallback)
* @param newFallbackValue - The new value for the fallback locale
* @returns Updated translation map with synchronized numeric suffixes
*/
const syncNumericSuffixAcrossLocales = (existingTranslationMap, fallbackLocaleCode, newFallbackValue) => {
	const updatedTranslationMap = {
		...existingTranslationMap,
		[fallbackLocaleCode]: newFallbackValue
	};
	const trailingNumberMatch = newFallbackValue.match(/\d+(?!.*\d)/);
	if (!trailingNumberMatch) return updatedTranslationMap;
	const newTrailingNumber = trailingNumberMatch[0];
	for (const [localeCode, currentValue] of Object.entries(existingTranslationMap)) {
		if (localeCode === fallbackLocaleCode) continue;
		if (!currentValue.match(/\d+(?!.*\d)/)) continue;
		updatedTranslationMap[localeCode] = currentValue.replace(/(\d+)(?!.*\d)/, newTrailingNumber);
	}
	return updatedTranslationMap;
};
/**
* Safely formats a key for use in object literals.
* Handles special cases like reserved keywords and non-identifier keys.
*
* @param objectKey - The key to format
* @returns Properly formatted key string
*/
const stringifyKey = (objectKey) => {
	if (!/^[A-Za-z_$][A-Za-z0-9_$]*$/.test(objectKey)) return JSON.stringify(objectKey);
	if (objectKey === "true" || objectKey === "false") return JSON.stringify(objectKey);
	return objectKey;
};
/**
* Builds an enumeration initializer string for the 'enu' function call.
* Creates a properly formatted enumeration object with key-value pairs.
*
* @param enumerationMap - Map of enumeration keys to string values
* @returns Formatted string for the enumeration function call, or empty string if invalid
*/
const buildEnumerationInitializer = (enumerationMap) => {
	const enumerationParts = [];
	for (const [enumerationKey, enumerationValue] of Object.entries(enumerationMap)) {
		if (typeof enumerationValue !== "string") return "";
		enumerationParts.push(`${stringifyKey(enumerationKey)}: ${JSON.stringify(enumerationValue)}`);
	}
	return `enu({ ${enumerationParts.join(", ")} })`;
};
/**
* Builds a condition initializer string for the 'cond' function call.
* Creates a properly formatted condition object with key-value pairs.
*
* @param conditionMap - Map of condition keys to string values
* @returns Formatted string for the condition function call, or empty string if invalid
*/
const buildConditionInitializer = (conditionMap) => {
	const conditionParts = [];
	for (const [conditionKey, conditionValue] of Object.entries(conditionMap)) {
		if (typeof conditionValue !== "string") return "";
		conditionParts.push(`${stringifyKey(conditionKey)}: ${JSON.stringify(conditionValue)}`);
	}
	return `cond({ ${conditionParts.join(", ")} })`;
};
/**
* Builds a gender initializer string for the 'gender' function call.
* Creates a properly formatted gender object with key-value pairs.
*
* @param genderMap - Map of gender keys to string values
* @returns Formatted string for the gender function call, or empty string if invalid
*/
const buildGenderInitializer = (genderMap) => {
	const genderParts = [];
	for (const [genderKey, genderValue] of Object.entries(genderMap)) {
		if (typeof genderValue !== "string") return "";
		genderParts.push(`${stringifyKey(genderKey)}: ${JSON.stringify(genderValue)}`);
	}
	return `gender({ ${genderParts.join(", ")} })`;
};
/**
* Builds an insertion initializer string for the 'insert' function call.
* Handles both string content and translation content for insertions.
*
* @param insertionContent - The content to be inserted (string or translation)
* @returns Formatted string for the insertion function call, or undefined if invalid
*/
const buildInsertionInitializer = (insertionContent) => {
	if (typeof insertionContent === "string") return `insert(${JSON.stringify(insertionContent)})`;
	if (getNodeType(insertionContent) === NodeType.Translation) {
		const translationMap = insertionContent[NodeType.Translation] ?? {};
		if (!Object.values(translationMap).every((translationValue) => typeof translationValue === "string")) return void 0;
		return `insert(${buildTranslationInitializer(translationMap)})`;
	}
};
/**
* Builds a file initializer string for the 'file' function call.
* Creates a properly formatted file path reference.
*
* @param filePath - The file path to reference
* @returns Formatted string for the file function call, or undefined if invalid
*/
const buildFileInitializer = (filePath) => {
	if (typeof filePath === "string") return `file(${JSON.stringify(filePath)})`;
};
/**
* Builds a markdown initializer string for the 'md' function call.
* Handles string content, translation content, and file references for markdown.
*
* @param markdownContent - The markdown content (string, translation, or file reference)
* @returns Formatted string for the markdown function call, or undefined if invalid
*/
const buildMarkdownInitializer = (markdownContent) => {
	if (typeof markdownContent === "string") return `md(${JSON.stringify(markdownContent)})`;
	if (getNodeType(markdownContent) === NodeType.Translation) {
		const translationMap = markdownContent[NodeType.Translation] ?? {};
		if (!Object.values(translationMap).every((translationValue) => typeof translationValue === "string")) return void 0;
		return `md(${buildTranslationInitializer(translationMap)})`;
	}
	if (getNodeType(markdownContent) === NodeType.File) {
		const filePath = markdownContent[NodeType.File];
		const fileInitializer = buildFileInitializer(filePath);
		if (!fileInitializer) return void 0;
		return `md(${fileInitializer})`;
	}
};
/**
* Builds a nested initializer string for the 'nest' function call.
* Creates a properly formatted nested dictionary reference.
*
* @param nestedContent - The nested content with dictionary key and optional path
* @returns Formatted string for the nested function call, or undefined if invalid
*/
const buildNestedInitializer = (nestedContent) => {
	if (!nestedContent || typeof nestedContent.dictionaryKey !== "string") return void 0;
	if (nestedContent.path && typeof nestedContent.path === "string") return `nest(${JSON.stringify(nestedContent.dictionaryKey)}, ${JSON.stringify(nestedContent.path)})`;
	return `nest(${JSON.stringify(nestedContent.dictionaryKey)})`;
};
/**
* Reads an existing translation map from a property in a content object.
* Parses the 't' function call and extracts the translation key-value pairs.
*
* @param contentObject - The object containing the property
* @param propertyName - The name of the property to read
* @returns Translation map with locale keys and values, or undefined if not found
*/
const readExistingTranslationMap = (contentObject, propertyName) => {
	const property = contentObject.getProperty(propertyName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const propertyInitializer = property.getInitializer();
	if (!propertyInitializer) return void 0;
	if (!Node.isCallExpression(propertyInitializer)) return void 0;
	const callExpression = propertyInitializer.getExpression();
	if (!Node.isIdentifier(callExpression) || callExpression.getText() !== "t") return void 0;
	const translationArgument = propertyInitializer.getArguments()[0];
	if (!translationArgument || !Node.isObjectLiteralExpression(translationArgument)) return void 0;
	const translationMap = {};
	for (const propertyAssignment of translationArgument.getProperties()) {
		if (!Node.isPropertyAssignment(propertyAssignment)) continue;
		const cleanPropertyName = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
		const valueInitializer = propertyAssignment.getInitializer();
		if (valueInitializer && Node.isStringLiteral(valueInitializer)) translationMap[cleanPropertyName] = valueInitializer.getLiteralValue();
		else if (valueInitializer && Node.isArrayLiteralExpression(valueInitializer)) {
			const stringArray = [];
			for (const arrayElement of valueInitializer.getElements()) {
				if (!Node.isStringLiteral(arrayElement)) return void 0;
				stringArray.push(arrayElement.getLiteralValue());
			}
			translationMap[cleanPropertyName] = stringArray;
		} else return;
	}
	return translationMap;
};
/**
* Reads an existing map from a function call (enu, cond, or gender).
* Parses the function call and extracts the key-value pairs.
*
* @param contentObject - The object containing the property
* @param propertyName - The name of the property to read
* @param functionName - The name of the function to look for ('enu', 'cond', or 'gender')
* @returns Map with keys and string values, or undefined if not found
*/
const readExistingMapFromCall = (contentObject, propertyName, functionName) => {
	const property = contentObject.getProperty(propertyName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const propertyInitializer = property.getInitializer();
	if (!propertyInitializer || !Node.isCallExpression(propertyInitializer)) return void 0;
	const callExpression = propertyInitializer.getExpression();
	if (!Node.isIdentifier(callExpression) || callExpression.getText() !== functionName) return void 0;
	const functionArgument = propertyInitializer.getArguments()[0];
	if (!functionArgument || !Node.isObjectLiteralExpression(functionArgument)) return void 0;
	const keyValueMap = {};
	for (const propertyAssignment of functionArgument.getProperties()) {
		if (!Node.isPropertyAssignment(propertyAssignment)) continue;
		const cleanPropertyName = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
		const valueInitializer = propertyAssignment.getInitializer();
		if (valueInitializer && Node.isStringLiteral(valueInitializer)) keyValueMap[cleanPropertyName] = valueInitializer.getLiteralValue();
	}
	return keyValueMap;
};
/**
* Extracts generic type arguments text from a call expression.
* Returns the type arguments as a string (e.g., "<string[]>").
*
* @param callExpression - The call expression to extract type arguments from
* @returns Type arguments as a string, or undefined if none found
*/
const getCallExpressionTypeArgsText = (callExpression) => {
	try {
		const typeArguments = callExpression.getTypeArguments();
		if (!typeArguments || typeArguments.length === 0) return void 0;
		return `<${typeArguments.map((typeArgument) => typeArgument.getText()).join(", ")}>`;
	} catch {
		return;
	}
};
/**
* Reads existing type arguments used in a specific property call.
* Supports both direct calls and nested calls (e.g., md(t<...>(...))).
*
* @param contentObject - The object containing the property
* @param propertyName - The name of the property to read
* @param functionName - The name of the function to look for
* @returns Type arguments as a string, or undefined if not found
*/
const readExistingTypeArgsForCall = (contentObject, propertyName, functionName) => {
	const property = contentObject.getProperty(propertyName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const propertyInitializer = property.getInitializer();
	if (!propertyInitializer || !Node.isCallExpression(propertyInitializer)) return void 0;
	const callExpression = propertyInitializer.getExpression();
	if (Node.isIdentifier(callExpression) && callExpression.getText() === functionName) return getCallExpressionTypeArgsText(propertyInitializer);
	if (functionName === "t" && Node.isIdentifier(callExpression) && callExpression.getText() === "md") {
		const markdownArgument = propertyInitializer.getArguments()[0];
		if (markdownArgument && Node.isCallExpression(markdownArgument)) {
			const innerExpression = markdownArgument.getExpression();
			if (Node.isIdentifier(innerExpression) && innerExpression.getText() === "t") return getCallExpressionTypeArgsText(markdownArgument);
		}
	}
};
/**
* Compares two string maps for equality.
* Filters out non-string values from the first map before comparison.
*
* @param firstMap - First map to compare (may contain non-string values)
* @param secondMap - Second map to compare (should contain only strings)
* @returns True if the string values in both maps are equal
*/
const areStringMapsEqual = (firstMap, secondMap) => {
	if (!secondMap) return false;
	const firstMapStringEntries = Object.entries(firstMap).filter(([, value]) => typeof value === "string");
	if (firstMapStringEntries.length !== Object.keys(firstMap).length) return false;
	if (firstMapStringEntries.length !== Object.keys(secondMap).length) return false;
	for (const [key, value] of firstMapStringEntries) {
		if (!(key in secondMap)) return false;
		if (secondMap[key] !== value) return false;
	}
	return true;
};
/**
* Compares translation maps for equality.
* Handles both string and array values in translations.
*
* @param desiredTranslationMap - The desired translation map
* @param existingTranslationMap - The existing translation map to compare against
* @returns True if both translation maps are equal
*/
const areTranslationsEqual = (desiredTranslationMap, existingTranslationMap) => {
	if (!existingTranslationMap) return false;
	for (const [localeCode, desiredValue] of Object.entries(desiredTranslationMap)) {
		if (!(localeCode in existingTranslationMap)) return false;
		const existingValue = existingTranslationMap[localeCode];
		if (typeof desiredValue === "string") {
			if (typeof existingValue !== "string") return false;
			if (existingValue !== desiredValue) return false;
		} else if (Array.isArray(desiredValue)) {
			if (!Array.isArray(existingValue)) return false;
			if (existingValue.length !== desiredValue.length) return false;
			for (let arrayIndex = 0; arrayIndex < desiredValue.length; arrayIndex++) if (existingValue[arrayIndex] !== desiredValue[arrayIndex]) return false;
		} else return false;
	}
	return true;
};
/**
* Gets existing property names from the content object.
* Handles both regular property assignments and shorthand properties.
*
* @param contentObject - The object literal expression to extract property names from
* @returns Set of existing property names
*/
const getExistingPropertyNames = (contentObject) => {
	const existingPropertyNames = /* @__PURE__ */ new Set();
	for (const property of contentObject.getProperties()) {
		if (Node.isPropertyAssignment(property)) {
			const propertyName = property.getName();
			if (propertyName) existingPropertyNames.add(propertyName.replace(/^['"]|['"]$/g, ""));
			continue;
		}
		if (Node.isShorthandPropertyAssignment(property)) {
			const shorthandPropertyName = property.getNameNode().getText();
			if (shorthandPropertyName) existingPropertyNames.add(shorthandPropertyName);
		}
	}
	return existingPropertyNames;
};
/**
* Processes array content entries.
* Handles arrays of various content types including strings, objects, and complex content nodes.
* Supports nested objects within arrays and maintains existing translation structures.
*
* @param contentObject - The object containing the array property
* @param propertyKey - The key of the array property
* @param arrayValue - The array of values to process
* @param existingPropertyKeys - Set of existing property names in the content object
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processArrayContent = (contentObject, propertyKey, arrayValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile) => {
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processArrayContent(spreadTargetObject, propertyKey, arrayValue, getExistingPropertyNames(spreadTargetObject), effectiveFallbackLocale, requiredImports, sourceFile);
	}
	const serializedArrayElements = [];
	let hasUnsupportedContent = false;
	let existingArrayElements;
	let existingArrayHasTranslation = false;
	let existingArrayTypeArguments;
	let arrayWasChanged = false;
	const existingProperty = contentObject.getProperty(propertyKey);
	if (existingProperty && Node.isPropertyAssignment(existingProperty)) {
		const propertyInitializer = existingProperty.getInitializer();
		let existingPropertyTypeArguments;
		const areAllDesiredValuesStrings = arrayValue.every((arrayElement) => typeof arrayElement === "string");
		if (propertyInitializer && Node.isCallExpression(propertyInitializer) && Node.isIdentifier(propertyInitializer.getExpression()) && propertyInitializer.getExpression().getText() === "t" && areAllDesiredValuesStrings) {
			existingPropertyTypeArguments = getCallExpressionTypeArgsText(propertyInitializer);
			const existingTranslationMap = readExistingTranslationMap(contentObject, propertyKey);
			if (existingTranslationMap) {
				const translationInitializerText = buildTranslationInitializer({
					...existingTranslationMap,
					[effectiveFallbackLocale]: arrayValue
				}, existingPropertyTypeArguments);
				requiredImports.add("t");
				const property$1 = contentObject.getProperty(propertyKey);
				if (property$1 && Node.isPropertyAssignment(property$1)) {
					if (property$1.getInitializer()?.getText() !== translationInitializerText) {
						property$1.setInitializer(translationInitializerText);
						return true;
					}
				}
				return false;
			}
		}
		if (propertyInitializer && Node.isArrayLiteralExpression(propertyInitializer)) {
			existingArrayElements = propertyInitializer.getElements();
			existingArrayHasTranslation = propertyInitializer.getElements().some((arrayElement) => {
				if (!Node.isCallExpression(arrayElement)) return false;
				const callExpression = arrayElement.getExpression();
				return Node.isIdentifier(callExpression) && callExpression.getText() === "t";
			});
			if (existingArrayHasTranslation) {
				for (const arrayElement of existingArrayElements) if (Node.isCallExpression(arrayElement)) {
					const callExpression = arrayElement.getExpression();
					if (Node.isIdentifier(callExpression) && callExpression.getText() === "t") {
						existingArrayTypeArguments = getCallExpressionTypeArgsText(arrayElement);
						if (existingArrayTypeArguments) break;
					}
				}
			}
		}
	}
	for (let elementIndex = 0; elementIndex < arrayValue.length; elementIndex++) {
		const currentElement = arrayValue[elementIndex];
		if (currentElement === null || currentElement === void 0 || typeof currentElement === "string" || typeof currentElement === "number" || typeof currentElement === "boolean") {
			let serializedElementValue = serializeValue(currentElement);
			if (typeof currentElement === "string" && existingArrayElements && elementIndex < existingArrayElements.length) {
				const existingArrayElement = existingArrayElements[elementIndex];
				if (Node.isCallExpression(existingArrayElement)) {
					const callExpression = existingArrayElement.getExpression();
					if (Node.isIdentifier(callExpression) && callExpression.getText() === "t") {
						const translationArgument = existingArrayElement.getArguments()[0];
						if (translationArgument && Node.isObjectLiteralExpression(translationArgument)) {
							const translationMap = {};
							for (const propertyAssignment of translationArgument.getProperties()) {
								if (!Node.isPropertyAssignment(propertyAssignment)) continue;
								const cleanPropertyName = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
								const propertyValue = propertyAssignment.getInitializer();
								if (propertyValue && Node.isStringLiteral(propertyValue)) translationMap[cleanPropertyName] = propertyValue.getLiteralValue();
							}
							serializedElementValue = buildTranslationInitializer(syncNumericSuffixAcrossLocales(translationMap, effectiveFallbackLocale, currentElement), getCallExpressionTypeArgsText(existingArrayElement));
							requiredImports.add("t");
						}
					}
				}
			}
			if (typeof currentElement === "string" && existingArrayHasTranslation && serializedElementValue && serializedElementValue.startsWith("\"")) {
				serializedElementValue = buildTranslationInitializer({ [effectiveFallbackLocale]: currentElement }, existingArrayTypeArguments);
				requiredImports.add("t");
			}
			if (serializedElementValue === void 0) {
				hasUnsupportedContent = true;
				break;
			}
			serializedArrayElements.push(serializedElementValue);
		} else if (typeof currentElement === "object" && currentElement !== null) {
			if (existingArrayElements && elementIndex < existingArrayElements.length) {
				const existingArrayElement = existingArrayElements[elementIndex];
				if (Node.isObjectLiteralExpression(existingArrayElement)) {
					if (processContentEntries(existingArrayElement, currentElement, effectiveFallbackLocale, requiredImports, sourceFile)) arrayWasChanged = true;
					serializedArrayElements.push(existingArrayElement.getText());
				} else {
					const serializedElementValue = serializeValue(currentElement);
					if (serializedElementValue === void 0) {
						hasUnsupportedContent = true;
						break;
					}
					serializedArrayElements.push(serializedElementValue);
				}
			} else {
				const serializedElementValue = serializeValue(currentElement);
				if (serializedElementValue === void 0) {
					hasUnsupportedContent = true;
					break;
				}
				serializedArrayElements.push(serializedElementValue);
			}
			const elementNodeType = getNodeType(currentElement);
			if (elementNodeType === NodeType.Translation) requiredImports.add("t");
			else if (elementNodeType === NodeType.Enumeration) requiredImports.add("enu");
			else if (elementNodeType === NodeType.Condition) requiredImports.add("cond");
			else if (elementNodeType === NodeType.Gender) requiredImports.add("gender");
			else if (elementNodeType === NodeType.Insertion) {
				requiredImports.add("insert");
				const insertionContent = currentElement[NodeType.Insertion];
				if (typeof insertionContent === "object" && insertionContent !== null && getNodeType(insertionContent) === NodeType.Translation) requiredImports.add("t");
			} else if (elementNodeType === NodeType.Markdown) {
				requiredImports.add("md");
				const markdownContent = currentElement[NodeType.Markdown];
				if (typeof markdownContent === "object" && markdownContent !== null && getNodeType(markdownContent) === NodeType.File) requiredImports.add("file");
			} else if (elementNodeType === NodeType.File) requiredImports.add("file");
			else if (elementNodeType === NodeType.Nested) requiredImports.add("nest");
		} else {
			hasUnsupportedContent = true;
			break;
		}
	}
	if (hasUnsupportedContent) return false;
	if (arrayWasChanged) return true;
	const arrayInitializerText = `[ ${serializedArrayElements.join(", ")} ]`;
	if (!existingPropertyKeys.has(propertyKey)) {
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: arrayInitializerText
		});
		return true;
	}
	const property = contentObject.getProperty(propertyKey);
	if (property && Node.isPropertyAssignment(property)) {
		const existingSerializedArray = readExistingArraySerialized(contentObject, propertyKey);
		if (!(existingSerializedArray !== void 0 && existingSerializedArray.length === serializedArrayElements.length && existingSerializedArray.every((existingElement, elementIndex) => existingElement === serializedArrayElements[elementIndex]))) {
			property.setInitializer(arrayInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes primitive content entries (string, number, boolean, null).
* Handles simple value types and updates existing translation maps when appropriate.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param primitiveValue - The primitive value to process
* @param existingPropertyKeys - Set of existing property names
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processPrimitiveContent = (contentObject, propertyKey, primitiveValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile) => {
	if (typeof primitiveValue === "string" && existingPropertyKeys.has(propertyKey)) {
		const property$1 = contentObject.getProperty(propertyKey);
		if (property$1 && Node.isPropertyAssignment(property$1)) {
			const propertyInitializer = property$1.getInitializer();
			if (propertyInitializer && !Node.isStringLiteral(propertyInitializer) && !Node.isCallExpression(propertyInitializer)) {
				console.log(`Skipping update for key "${propertyKey}" because existing value is not a string literal`);
				return false;
			}
		}
		const existingTranslationMap = readExistingTranslationMap(contentObject, propertyKey);
		if (existingTranslationMap) {
			const translationInitializerText = buildTranslationInitializer({
				...existingTranslationMap,
				[effectiveFallbackLocale]: primitiveValue
			}, readExistingTypeArgsForCall(contentObject, propertyKey, "t"));
			requiredImports.add("t");
			if (property$1 && Node.isPropertyAssignment(property$1)) {
				property$1.setInitializer(translationInitializerText);
				return true;
			}
			return false;
		}
	}
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processPrimitiveContent(spreadTargetObject, propertyKey, primitiveValue, getExistingPropertyNames(spreadTargetObject), effectiveFallbackLocale, requiredImports, sourceFile);
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: typeof primitiveValue === "string" ? JSON.stringify(primitiveValue) : String(primitiveValue)
		});
		return true;
	}
	const property = contentObject.getProperty(propertyKey);
	if (property && Node.isPropertyAssignment(property)) {
		const propertyInitializer = property.getInitializer();
		const isPrimitiveLiteral = propertyInitializer && (Node.isStringLiteral(propertyInitializer) || Node.isNumericLiteral(propertyInitializer) || propertyInitializer.getKind() === SyntaxKind.TrueKeyword || propertyInitializer.getKind() === SyntaxKind.FalseKeyword || Node.isNullLiteral(propertyInitializer) || Node.isCallExpression(propertyInitializer));
		if (propertyInitializer && !isPrimitiveLiteral) {
			console.log(`Skipping update for key "${propertyKey}" because existing value is not a primitive literal`);
			return false;
		}
		const currentInitializerText = propertyInitializer?.getText();
		const desiredInitializerText = typeof primitiveValue === "string" ? JSON.stringify(primitiveValue) : String(primitiveValue);
		if (currentInitializerText !== desiredInitializerText) {
			property.setInitializer(desiredInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes complex content entries (translation, enumeration, condition, etc.).
* Routes content to the appropriate specialized processor based on node type.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The complex content node to process
* @param existingPropertyKeys - Set of existing property names
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processComplexContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile) => {
	switch (getNodeType(contentNode)) {
		case NodeType.Translation: return processTranslationContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Enumeration: return processEnumerationContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Condition: return processConditionContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Gender: return processGenderContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Insertion: return processInsertionContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Markdown: return processMarkdownContent(contentObject, propertyKey, contentNode, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile);
		case NodeType.File: return processFileContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		case NodeType.Nested: return processNestedContent(contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile);
		default: return false;
	}
};
/**
* Processes translation content.
* Handles translation objects with locale keys and string/array values.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The translation content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processTranslationContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const translationMap = contentNode[NodeType.Translation] ?? {};
	const areAllValuesStringsOrArrays = Object.values(translationMap).every((translationValue) => typeof translationValue === "string" || Array.isArray(translationValue));
	if (Object.values(translationMap).some((translationValue) => typeof translationValue === "object" && translationValue !== null && !Array.isArray(translationValue) && getNodeType(translationValue) !== NodeType.Text) && !areAllValuesStringsOrArrays) {
		if (!existingPropertyKeys.has(propertyKey)) {
			const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
			if (spreadTargetObject) return processTranslationContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		}
		const translationParts$1 = [];
		let hasUnsupportedValue = false;
		for (const [localeCode, translationValue] of Object.entries(translationMap)) {
			const formattedLocaleKey = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(localeCode) ? localeCode : JSON.stringify(localeCode);
			if (typeof translationValue === "object" && translationValue !== null && !Array.isArray(translationValue)) {
				const serializedValue = serializeValue(translationValue);
				if (serializedValue === void 0) {
					hasUnsupportedValue = true;
					break;
				}
				translationParts$1.push(`${formattedLocaleKey}: ${serializedValue}`);
				const nodeType = getNodeType(translationValue);
				if (nodeType === NodeType.Markdown) {
					requiredImports.add("md");
					const markdownContent = translationValue[NodeType.Markdown];
					if (typeof markdownContent === "object" && markdownContent !== null && getNodeType(markdownContent) === NodeType.File) requiredImports.add("file");
				} else if (nodeType === NodeType.File) requiredImports.add("file");
				else if (nodeType === NodeType.Insertion) requiredImports.add("insert");
				else if (nodeType === NodeType.Enumeration) requiredImports.add("enu");
				else if (nodeType === NodeType.Condition) requiredImports.add("cond");
				else if (nodeType === NodeType.Gender) requiredImports.add("gender");
				else if (nodeType === NodeType.Nested) requiredImports.add("nest");
			} else if (typeof translationValue === "string") translationParts$1.push(`${formattedLocaleKey}: ${JSON.stringify(translationValue)}`);
			else if (Array.isArray(translationValue)) {
				const serializedArrayElements = translationValue.map((arrayElement) => JSON.stringify(arrayElement)).join(", ");
				translationParts$1.push(`${formattedLocaleKey}: [ ${serializedArrayElements} ]`);
			}
		}
		if (hasUnsupportedValue) return false;
		const translationInitializerText$1 = `t${readExistingTypeArgsForCall(contentObject, propertyKey, "t") ?? ""}({ ${translationParts$1.join(", ")} })`;
		if (!existingPropertyKeys.has(propertyKey)) {
			requiredImports.add("t");
			contentObject.addPropertyAssignment({
				name: propertyKey,
				initializer: translationInitializerText$1
			});
			return true;
		}
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			if (property.getInitializer()?.getText() !== translationInitializerText$1) {
				requiredImports.add("t");
				property.setInitializer(translationInitializerText$1);
				return true;
			}
		}
		return false;
	}
	if (!areAllValuesStringsOrArrays) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processTranslationContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
	}
	const translationParts = [];
	for (const [localeCode, translationValue] of Object.entries(translationMap)) {
		const formattedLocaleKey = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(localeCode) ? localeCode : JSON.stringify(localeCode);
		if (typeof translationValue === "string") translationParts.push(`${formattedLocaleKey}: ${JSON.stringify(translationValue)}`);
		else if (Array.isArray(translationValue)) {
			const serializedArrayElements = translationValue.map((arrayElement) => JSON.stringify(arrayElement)).join(", ");
			translationParts.push(`${formattedLocaleKey}: [ ${serializedArrayElements} ]`);
		}
	}
	const translationInitializerText = `t${readExistingTypeArgsForCall(contentObject, propertyKey, "t") ?? ""}({ ${translationParts.join(", ")} })`;
	if (!existingPropertyKeys.has(propertyKey)) {
		requiredImports.add("t");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: translationInitializerText
		});
		return true;
	}
	if (!areTranslationsEqual(translationMap, readExistingTranslationMap(contentObject, propertyKey))) {
		requiredImports.add("t");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(translationInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes enumeration content.
* Handles enumeration objects with key-value string pairs.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The enumeration content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processEnumerationContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const enumerationMap = contentNode[NodeType.Enumeration];
	if (!Object.values(enumerationMap).every((enumerationValue) => typeof enumerationValue === "string")) return false;
	const enumerationInitializerText = buildEnumerationInitializer(enumerationMap);
	if (!enumerationInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processEnumerationContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		requiredImports.add("enu");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: enumerationInitializerText
		});
		return true;
	}
	if (!areStringMapsEqual(enumerationMap, readExistingMapFromCall(contentObject, propertyKey, "enu"))) {
		requiredImports.add("enu");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(enumerationInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes condition content.
* Handles condition objects with key-value string pairs.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The condition content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processConditionContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const conditionMap = contentNode[NodeType.Condition];
	if (Object.values(conditionMap).every((conditionValue) => typeof conditionValue === "string")) {
		const conditionInitializerText = buildConditionInitializer(conditionMap);
		if (!conditionInitializerText) return false;
		if (!existingPropertyKeys.has(propertyKey)) {
			const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
			if (spreadTargetObject) return processConditionContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
			requiredImports.add("cond");
			contentObject.addPropertyAssignment({
				name: propertyKey,
				initializer: conditionInitializerText
			});
			return true;
		}
		if (!areStringMapsEqual(conditionMap, readExistingMapFromCall(contentObject, propertyKey, "cond"))) {
			requiredImports.add("cond");
			const property$1 = contentObject.getProperty(propertyKey);
			if (property$1 && Node.isPropertyAssignment(property$1)) {
				property$1.setInitializer(conditionInitializerText);
				return true;
			}
		}
		return false;
	}
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processConditionContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		return false;
	}
	const property = contentObject.getProperty(propertyKey);
	if (!property || !Node.isPropertyAssignment(property)) return false;
	const propertyInitializer = property.getInitializer();
	if (!propertyInitializer || !Node.isCallExpression(propertyInitializer)) return false;
	const callExpression = propertyInitializer.getExpression();
	if (!Node.isIdentifier(callExpression) || callExpression.getText() !== "cond") return false;
	const condArgument = propertyInitializer.getArguments()[0];
	if (!condArgument || !Node.isObjectLiteralExpression(condArgument)) return false;
	requiredImports.add("cond");
	let hasModifications = false;
	for (const [conditionKey, conditionValue] of Object.entries(conditionMap)) {
		const nodeType = getNodeType(conditionValue);
		if (!nodeType) continue;
		let condProperty = condArgument.getProperty(conditionKey);
		if (!condProperty) condProperty = condArgument.getProperty(stringifyKey(conditionKey));
		if (!condProperty || !Node.isPropertyAssignment(condProperty)) continue;
		const condValueInitializer = condProperty.getInitializer();
		if (!condValueInitializer) continue;
		if (nodeType === NodeType.Translation) {
			if (!Node.isCallExpression(condValueInitializer)) continue;
			const tCallExpression = condValueInitializer.getExpression();
			if (!Node.isIdentifier(tCallExpression) || tCallExpression.getText() !== "t") continue;
			const tArgument = condValueInitializer.getArguments()[0];
			if (!tArgument || !Node.isObjectLiteralExpression(tArgument)) continue;
			const translationMap = conditionValue[NodeType.Translation];
			if (!translationMap || typeof translationMap !== "object") continue;
			const existingTranslationMap = {};
			for (const propertyAssignment of tArgument.getProperties()) {
				if (!Node.isPropertyAssignment(propertyAssignment)) continue;
				const cleanPropertyName = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
				const valueInitializer = propertyAssignment.getInitializer();
				if (valueInitializer && Node.isStringLiteral(valueInitializer)) existingTranslationMap[cleanPropertyName] = valueInitializer.getLiteralValue();
				else if (valueInitializer && Node.isArrayLiteralExpression(valueInitializer)) {
					const stringArray = [];
					for (const arrayElement of valueInitializer.getElements()) if (Node.isStringLiteral(arrayElement)) stringArray.push(arrayElement.getLiteralValue());
					existingTranslationMap[cleanPropertyName] = stringArray;
				}
			}
			if (!areTranslationsEqual(translationMap, existingTranslationMap)) {
				requiredImports.add("t");
				for (const [locale, localeValue] of Object.entries(translationMap)) {
					const isLocaleCodeValidIdentifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(locale);
					const formattedLocaleKey = isLocaleCodeValidIdentifier ? locale : JSON.stringify(locale);
					let existingProperty = tArgument.getProperty(locale);
					if (!existingProperty && !isLocaleCodeValidIdentifier) existingProperty = tArgument.getProperty(JSON.stringify(locale));
					if (existingProperty && Node.isPropertyAssignment(existingProperty)) {
						const currentValue = existingProperty.getInitializer();
						const newValue = Array.isArray(localeValue) ? `[${localeValue.map((v) => JSON.stringify(v)).join(", ")}]` : JSON.stringify(localeValue);
						if (currentValue?.getText() !== newValue) {
							existingProperty.setInitializer(newValue);
							hasModifications = true;
						}
					} else if (!existingProperty) {
						const newValue = Array.isArray(localeValue) ? `[${localeValue.map((v) => JSON.stringify(v)).join(", ")}]` : JSON.stringify(localeValue);
						tArgument.addPropertyAssignment({
							name: formattedLocaleKey,
							initializer: newValue
						});
						hasModifications = true;
					}
				}
			}
		}
	}
	return hasModifications;
};
/**
* Processes gender content.
* Handles gender objects with key-value string pairs.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The gender content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processGenderContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const genderMap = contentNode[NodeType.Gender];
	if (!Object.values(genderMap).every((genderValue) => typeof genderValue === "string")) return false;
	const genderInitializerText = buildGenderInitializer(genderMap);
	if (!genderInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processGenderContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		requiredImports.add("gender");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: genderInitializerText
		});
		return true;
	}
	if (!areStringMapsEqual(genderMap, readExistingMapFromCall(contentObject, propertyKey, "gender"))) {
		requiredImports.add("gender");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(genderInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes insertion content.
* Handles insertion objects with string or translation content.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The insertion content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processInsertionContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const insertionContent = contentNode[NodeType.Insertion];
	const insertionInitializerText = buildInsertionInitializer(insertionContent);
	if (!insertionInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processInsertionContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		requiredImports.add("insert");
		if (typeof insertionContent === "object" && insertionContent !== null && getNodeType(insertionContent) === NodeType.Translation) requiredImports.add("t");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: insertionInitializerText
		});
		return true;
	}
	const existingInsertion = readExistingInsertion(contentObject, propertyKey);
	if (!(typeof insertionContent === "string" && existingInsertion?.kind === "string" && existingInsertion.value === insertionContent || typeof insertionContent === "object" && insertionContent !== null && getNodeType(insertionContent) === NodeType.Translation && existingInsertion?.kind === "translation" && areStringMapsEqual(insertionContent[NodeType.Translation] ?? {}, existingInsertion.map))) {
		requiredImports.add("insert");
		if (typeof insertionContent === "object" && insertionContent !== null && getNodeType(insertionContent) === NodeType.Translation) requiredImports.add("t");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(insertionInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes markdown content.
* Handles markdown objects with string, translation, or file content.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The markdown content node
* @param existingPropertyKeys - Set of existing property names
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processMarkdownContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile) => {
	const markdownContent = contentNode[NodeType.Markdown];
	const markdownInitializerText = buildMarkdownInitializer(markdownContent);
	if (!markdownInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processMarkdownContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), effectiveFallbackLocale, requiredImports, sourceFile);
		requiredImports.add("md");
		const markdownNodeType$1 = getNodeType(markdownContent);
		if (markdownNodeType$1 === NodeType.File) requiredImports.add("file");
		else if (markdownNodeType$1 === NodeType.Translation) requiredImports.add("t");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: markdownInitializerText
		});
		return true;
	}
	const markdownNodeType = getNodeType(markdownContent);
	const existingSimpleMarkdown = readExistingMarkdown(contentObject, propertyKey);
	const existingMarkdownTranslationMap = readExistingMarkdownTranslationMap(contentObject, propertyKey);
	const existingTranslationTypeArguments = readExistingTypeArgsForCall(contentObject, propertyKey, "t");
	if (typeof markdownContent === "string" && existingMarkdownTranslationMap && effectiveFallbackLocale) {
		const updatedTranslationMap = {
			...existingMarkdownTranslationMap,
			[effectiveFallbackLocale]: markdownContent
		};
		requiredImports.add("md");
		requiredImports.add("t");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(`md(${buildTranslationInitializer(updatedTranslationMap, existingTranslationTypeArguments)})`);
			return true;
		}
		return false;
	}
	if (markdownNodeType === NodeType.Translation) {
		const markdownTranslationMap = markdownContent[NodeType.Translation];
		if (!Object.values(markdownTranslationMap).every((translationValue) => typeof translationValue === "string")) return false;
		if (!areStringMapsEqual(markdownTranslationMap, existingMarkdownTranslationMap)) {
			requiredImports.add("md");
			requiredImports.add("t");
			const property = contentObject.getProperty(propertyKey);
			if (property && Node.isPropertyAssignment(property)) {
				property.setInitializer(`md(${buildTranslationInitializer(markdownTranslationMap, existingTranslationTypeArguments)})`);
				return true;
			}
		}
		return false;
	}
	if (!(typeof markdownContent === "string" && existingSimpleMarkdown?.kind === "string" && existingSimpleMarkdown.value === markdownContent || markdownNodeType === NodeType.File && existingSimpleMarkdown?.kind === "file" && existingSimpleMarkdown.path === markdownContent[NodeType.File])) {
		requiredImports.add("md");
		if (markdownNodeType === NodeType.File) requiredImports.add("file");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(markdownInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes file content.
* Handles file objects with file path references.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The file content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processFileContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const filePath = contentNode[NodeType.File];
	const fileInitializerText = buildFileInitializer(filePath);
	if (!fileInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processFileContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		requiredImports.add("file");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: fileInitializerText
		});
		return true;
	}
	if (readExistingFilePath(contentObject, propertyKey) !== filePath) {
		requiredImports.add("file");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(fileInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes nested content.
* Handles nested objects with dictionary key and optional path references.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param contentNode - The nested content node
* @param existingPropertyKeys - Set of existing property names
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processNestedContent = (contentObject, propertyKey, contentNode, existingPropertyKeys, requiredImports, sourceFile) => {
	const nestedContent = contentNode[NodeType.Nested];
	const nestedInitializerText = buildNestedInitializer(nestedContent);
	if (!nestedInitializerText) return false;
	if (!existingPropertyKeys.has(propertyKey)) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processNestedContent(spreadTargetObject, propertyKey, contentNode, getExistingPropertyNames(spreadTargetObject), requiredImports, sourceFile);
		requiredImports.add("nest");
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: nestedInitializerText
		});
		return true;
	}
	const existingNestedContent = readExistingNest(contentObject, propertyKey);
	if (!(!!nestedContent && existingNestedContent?.dictionaryKey === nestedContent.dictionaryKey && existingNestedContent?.path === nestedContent.path)) {
		requiredImports.add("nest");
		const property = contentObject.getProperty(propertyKey);
		if (property && Node.isPropertyAssignment(property)) {
			property.setInitializer(nestedInitializerText);
			return true;
		}
	}
	return false;
};
/**
* Processes nested object content.
* Handles nested objects within content structures.
*
* @param contentObject - The object containing the property
* @param propertyKey - The key of the property to process
* @param nestedObjectValue - The nested object value to process
* @param _existingPropertyKeys - Set of existing property names (unused)
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if the content was modified
*/
const processNestedObjectContent = (contentObject, propertyKey, nestedObjectValue, _existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile) => {
	let childObject;
	const existingProperty = contentObject.getProperty(propertyKey);
	if (existingProperty && Node.isPropertyAssignment(existingProperty)) childObject = existingProperty.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
	if (!childObject) {
		const shorthandProperty = contentObject.getProperty(propertyKey);
		if (shorthandProperty && Node.isShorthandPropertyAssignment(shorthandProperty)) childObject = resolveNameToObjectLiteral(contentObject.getSourceFile(), propertyKey);
		else if (existingProperty && Node.isPropertyAssignment(existingProperty)) {
			const propertyInitializer = existingProperty.getInitializer();
			if (propertyInitializer) {
				if (Node.isIdentifier(propertyInitializer)) childObject = resolveNameToObjectLiteral(sourceFile, propertyInitializer.getText());
				else if (Node.isPropertyAccessExpression(propertyInitializer)) childObject = resolveExpressionToObjectLiteral(sourceFile, propertyInitializer);
			}
		}
	}
	if (!childObject) {
		const spreadTargetObject = findSpreadTargetObjectForKey(contentObject, propertyKey, sourceFile);
		if (spreadTargetObject) return processNestedObjectContent(spreadTargetObject, propertyKey, nestedObjectValue, getExistingPropertyNames(spreadTargetObject), effectiveFallbackLocale, requiredImports, sourceFile);
		contentObject.addPropertyAssignment({
			name: propertyKey,
			initializer: "{ }"
		});
		const newProperty = contentObject.getProperty(propertyKey);
		if (newProperty && Node.isPropertyAssignment(newProperty)) childObject = newProperty.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
	}
	if (childObject) return processContentEntries(childObject, nestedObjectValue, effectiveFallbackLocale, requiredImports, sourceFile);
	return false;
};
/**
* Processes content entries in a dictionary object.
* Routes different content types to appropriate processors.
*
* @param contentObject - The object containing the content
* @param dictionaryContent - The dictionary content to process
* @param effectiveFallbackLocale - The fallback locale for translations
* @param requiredImports - Set to track required imports
* @param sourceFile - The source file being processed
* @returns True if any content was modified
*/
const processContentEntries = (contentObject, dictionaryContent, effectiveFallbackLocale, requiredImports, sourceFile) => {
	let contentWasChanged = false;
	const existingPropertyKeys = getExistingPropertyNames(contentObject);
	for (const [propertyKey, propertyValue] of Object.entries(dictionaryContent)) {
		if (Array.isArray(propertyValue)) {
			if (processArrayContent(contentObject, propertyKey, propertyValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile)) contentWasChanged = true;
			continue;
		}
		if (typeof propertyValue === "string" || typeof propertyValue === "number" || typeof propertyValue === "boolean" || propertyValue === null) {
			if (processPrimitiveContent(contentObject, propertyKey, propertyValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile)) contentWasChanged = true;
			continue;
		}
		const nodeType = getNodeType(propertyValue);
		if (nodeType !== NodeType.Text && nodeType !== NodeType.Number && nodeType !== NodeType.Boolean && nodeType !== NodeType.Null) {
			if (processComplexContent(contentObject, propertyKey, propertyValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile)) {
				contentWasChanged = true;
				continue;
			}
		}
		if (propertyValue && typeof propertyValue === "object" && !Array.isArray(propertyValue) && !propertyValue.nodeType) {
			if (processNestedObjectContent(contentObject, propertyKey, propertyValue, existingPropertyKeys, effectiveFallbackLocale, requiredImports, sourceFile)) contentWasChanged = true;
		}
	}
	return contentWasChanged;
};
const readExistingInsertion = (contentObject, propName) => {
	const prop = contentObject.getProperty(propName);
	if (!prop || !Node.isPropertyAssignment(prop)) return void 0;
	const init = prop.getInitializer();
	if (!init || !Node.isCallExpression(init)) return void 0;
	const exp = init.getExpression();
	if (!Node.isIdentifier(exp) || exp.getText() !== "insert") return void 0;
	const argument = init.getArguments()[0];
	if (!argument) return void 0;
	if (Node.isStringLiteral(argument)) return {
		kind: "string",
		value: argument.getLiteralValue()
	};
	if (Node.isCallExpression(argument)) {
		const argumentExpression = argument.getExpression();
		if (Node.isIdentifier(argumentExpression) && argumentExpression.getText() === "t") {
			const translationArgument = argument.getArguments()[0];
			if (translationArgument && Node.isObjectLiteralExpression(translationArgument)) {
				const map = {};
				for (const propertyAssignment of translationArgument.getProperties()) {
					if (!Node.isPropertyAssignment(propertyAssignment)) continue;
					const name = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
					const valueInitializer = propertyAssignment.getInitializer();
					if (valueInitializer && Node.isStringLiteral(valueInitializer)) map[name] = valueInitializer.getLiteralValue();
				}
				return {
					kind: "translation",
					map
				};
			}
		}
	}
};
const readExistingMarkdown = (contentObject, propName) => {
	const property = contentObject.getProperty(propName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const initializer = property.getInitializer();
	if (!initializer) return void 0;
	if (Node.isCallExpression(initializer)) {
		const expression = initializer.getExpression();
		if (!Node.isIdentifier(expression)) return void 0;
		if (expression.getText() === "md") {
			const argument = initializer.getArguments()[0];
			if (!argument) return void 0;
			if (Node.isStringLiteral(argument)) return {
				kind: "string",
				value: argument.getLiteralValue()
			};
			if (Node.isCallExpression(argument)) {
				const argumentExpression = argument.getExpression();
				if (Node.isIdentifier(argumentExpression) && argumentExpression.getText() === "file") {
					const fileArgument = argument.getArguments()[0];
					if (fileArgument && Node.isStringLiteral(fileArgument)) return {
						kind: "file",
						path: fileArgument.getLiteralValue()
					};
				}
			}
		}
	}
};
const readExistingFilePath = (contentObject, propName) => {
	const property = contentObject.getProperty(propName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const initializer = property.getInitializer();
	if (!initializer || !Node.isCallExpression(initializer)) return void 0;
	const expression = initializer.getExpression();
	if (!Node.isIdentifier(expression) || expression.getText() !== "file") return void 0;
	const argument = initializer.getArguments()[0];
	if (argument && Node.isStringLiteral(argument)) return argument.getLiteralValue();
};
const readExistingMarkdownTranslationMap = (contentObject, propName) => {
	const property = contentObject.getProperty(propName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const initializer = property.getInitializer();
	if (!initializer) return void 0;
	if (Node.isCallExpression(initializer)) {
		const exp = initializer.getExpression();
		if (Node.isIdentifier(exp) && exp.getText() === "md") {
			const arg = initializer.getArguments()[0];
			if (arg && Node.isCallExpression(arg)) {
				const tExp = arg.getExpression();
				if (Node.isIdentifier(tExp) && tExp.getText() === "t") {
					const tArg = arg.getArguments()[0];
					if (tArg && Node.isObjectLiteralExpression(tArg)) {
						const map = {};
						for (const prop of tArg.getProperties()) {
							if (!Node.isPropertyAssignment(prop)) continue;
							const name = prop.getNameNode().getText().replace(/^['"]|['"]$/g, "");
							const valueInit = prop.getInitializer();
							if (valueInit && Node.isStringLiteral(valueInit)) map[name] = valueInit.getLiteralValue();
							else return;
						}
						return map;
					}
				}
			}
		}
	}
	if (Node.isCallExpression(initializer)) {
		const exp = initializer.getExpression();
		if (Node.isIdentifier(exp) && exp.getText() === "t") {
			const tArg = initializer.getArguments()[0];
			if (tArg && Node.isObjectLiteralExpression(tArg)) {
				const map = {};
				for (const prop of tArg.getProperties()) {
					if (!Node.isPropertyAssignment(prop)) continue;
					const name = prop.getNameNode().getText().replace(/^['"]|['"]$/g, "");
					const valueInit = prop.getInitializer();
					if (valueInit && Node.isCallExpression(valueInit) && Node.isIdentifier(valueInit.getExpression()) && valueInit.getExpression().getText() === "md") {
						const mdArg = valueInit.getArguments()[0];
						if (mdArg && Node.isStringLiteral(mdArg)) map[name] = mdArg.getLiteralValue();
						else return;
					} else return;
				}
				return map;
			}
		}
	}
};
const readExistingNest = (contentObject, propName) => {
	const property = contentObject.getProperty(propName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	let initializer = property.getInitializer();
	if (!initializer) return void 0;
	let safetyCounter = 0;
	while (safetyCounter++ < 5) {
		if (Node.isCallExpression(initializer)) break;
		const nextExpression = initializer.getExpression?.();
		if (nextExpression && typeof nextExpression === "object" && nextExpression !== initializer) {
			initializer = nextExpression;
			continue;
		}
		break;
	}
	if (!Node.isCallExpression(initializer)) return void 0;
	const expression = initializer.getExpression();
	if (!Node.isIdentifier(expression) || expression.getText() !== "nest") return void 0;
	const [firstArgument, secondArgument] = initializer.getArguments();
	if (!firstArgument || !Node.isStringLiteral(firstArgument)) return void 0;
	const dictionaryKey = firstArgument.getLiteralValue();
	let path;
	if (secondArgument && Node.isStringLiteral(secondArgument)) path = secondArgument.getLiteralValue();
	return {
		dictionaryKey,
		path
	};
};
const unwrapToObjectLiteral = (node) => {
	if (!node || typeof node !== "object") return void 0;
	let current = node;
	let safetyCounter = 0;
	while (safetyCounter++ < 8) {
		if (Node.isObjectLiteralExpression(current)) return current;
		const next = current?.getExpression?.();
		if (next && typeof next === "object" && next !== current) {
			current = next;
			continue;
		}
		break;
	}
};
const resolveNameToObjectLiteral = (sourceFile, name) => {
	const varDecl = sourceFile.getVariableDeclaration(name);
	if (varDecl) {
		const obj = unwrapToObjectLiteral(varDecl.getInitializer());
		if (obj) return obj;
	}
	const decl = sourceFile.getDescendants().find((n) => {
		return Node.isIdentifier(n) && n.getText() === name;
	})?.getSymbol()?.getDeclarations()?.[0];
	if (decl && Node.isVariableDeclaration(decl)) {
		const obj = unwrapToObjectLiteral(decl.getInitializer());
		if (obj) return obj;
	}
};
const resolveExpressionToObjectLiteral = (sourceFile, expr) => {
	if (Node.isIdentifier(expr)) return resolveNameToObjectLiteral(sourceFile, expr.getText());
	if (Node.isPropertyAccessExpression(expr)) {
		const leftResolved = resolveExpressionToObjectLiteral(sourceFile, expr.getExpression());
		if (!leftResolved) return void 0;
		const propName = expr.getName();
		const prop = leftResolved.getProperty(propName);
		if (prop && Node.isPropertyAssignment(prop)) {
			const init = prop.getInitializer();
			const obj = unwrapToObjectLiteral(init);
			if (obj) return obj;
			if (init && Node.isIdentifier(init)) return resolveNameToObjectLiteral(sourceFile, init.getText());
		}
	}
};
const getSpreadSourceObjects = (contentObject, sourceFile) => {
	const spreads = [];
	for (const prop of contentObject.getProperties()) if (Node.isSpreadAssignment(prop)) {
		const resolved = resolveExpressionToObjectLiteral(sourceFile, prop.getExpression());
		if (resolved) spreads.push(resolved);
	}
	return spreads;
};
const findSpreadTargetObjectForKey = (contentObject, key, sourceFile) => {
	const spreads = getSpreadSourceObjects(contentObject, sourceFile);
	for (let i = spreads.length - 1; i >= 0; i--) {
		const spreadObj = spreads[i];
		const prop = spreadObj.getProperty(key);
		if (prop && Node.isPropertyAssignment(prop)) return spreadObj;
	}
};
const readExistingArraySerialized = (contentObject, propName) => {
	const property = contentObject.getProperty(propName);
	if (!property || !Node.isPropertyAssignment(property)) return void 0;
	const initializer = property.getInitializer();
	if (!initializer || !Node.isArrayLiteralExpression(initializer)) return void 0;
	const serialized = [];
	for (const element of initializer.getElements()) {
		if (Node.isStringLiteral(element)) {
			serialized.push(JSON.stringify(element.getLiteralValue()));
			continue;
		}
		if (Node.isNumericLiteral(element)) {
			serialized.push(element.getText());
			continue;
		}
		if (element.getKind() === SyntaxKind.TrueKeyword || element.getKind() === SyntaxKind.FalseKeyword) {
			serialized.push(element.getText());
			continue;
		}
		if (Node.isNullLiteral(element)) {
			serialized.push("null");
			continue;
		}
		if (Node.isCallExpression(element)) {
			const expression = element.getExpression();
			if (Node.isIdentifier(expression) && expression.getText() === "t") {
				const argument = element.getArguments()[0];
				if (argument && Node.isObjectLiteralExpression(argument)) {
					const map = {};
					for (const propertyAssignment of argument.getProperties()) {
						if (!Node.isPropertyAssignment(propertyAssignment)) return void 0;
						const name = propertyAssignment.getNameNode().getText().replace(/^['"]|['"]$/g, "");
						const valueInitializer = propertyAssignment.getInitializer();
						if (valueInitializer && Node.isStringLiteral(valueInitializer)) map[name] = valueInitializer.getLiteralValue();
						else return;
					}
					serialized.push(buildTranslationInitializer(map));
					continue;
				}
			}
		}
		return;
	}
	return serialized;
};
const serializeValue = (value) => {
	const nodeType = getNodeType(value);
	if (nodeType === NodeType.Text) return JSON.stringify(value);
	if (nodeType === NodeType.Number || nodeType === NodeType.Boolean) return String(value);
	if (nodeType === NodeType.Null) return "null";
	if (nodeType === NodeType.Translation) {
		const translations = value[NodeType.Translation] ?? {};
		if (!Object.values(translations).every((v) => typeof v === "string")) return void 0;
		return buildTranslationInitializer(translations);
	}
	if (nodeType === NodeType.Enumeration) {
		const map = value[NodeType.Enumeration];
		return buildEnumerationInitializer(map);
	}
	if (nodeType === NodeType.Condition) {
		const map = value[NodeType.Condition];
		return buildConditionInitializer(map);
	}
	if (nodeType === NodeType.Gender) {
		const map = value[NodeType.Gender];
		return buildGenderInitializer(map);
	}
	if (nodeType === NodeType.Insertion) {
		const content = value[NodeType.Insertion];
		return buildInsertionInitializer(content);
	}
	if (nodeType === NodeType.Markdown) {
		const content = value[NodeType.Markdown];
		return buildMarkdownInitializer(content);
	}
	if (nodeType === NodeType.File) {
		const path = value[NodeType.File];
		return buildFileInitializer(path);
	}
	if (nodeType === NodeType.Nested) {
		const content = value[NodeType.Nested];
		return buildNestedInitializer(content);
	}
};
/**
* Gets the existing imports from @intlayer/core in the source file
*/
const getExistingIntlayerImports = (sourceFile) => {
	const imported = /* @__PURE__ */ new Set();
	for (const importDecl of sourceFile.getImportDeclarations()) {
		const moduleSpecifier = importDecl.getModuleSpecifierValue();
		if (moduleSpecifier === "intlayer") {
			const namedImports = importDecl.getNamedImports();
			for (const namedImport of namedImports) imported.add(namedImport.getName());
		}
		if (moduleSpecifier === "intlayer/file") {
			const namedImports = importDecl.getNamedImports();
			for (const namedImport of namedImports) {
				const alias = namedImport.getAliasNode();
				imported.add(alias ? alias.getText() : namedImport.getName());
			}
		}
	}
	return imported;
};
/**
* Adds missing imports to the source file
*/
const addMissingImports = (sourceFile, requiredImports) => {
	if (requiredImports.size === 0) return false;
	const existingImports = getExistingIntlayerImports(sourceFile);
	const missingImports = [...requiredImports].filter((imp) => !existingImports.has(imp));
	if (missingImports.length === 0) return false;
	const hasMissingFile = missingImports.includes("file");
	const otherMissingImports = missingImports.filter((imp) => imp !== "file");
	if (otherMissingImports.length > 0) {
		const coreImport = sourceFile.getImportDeclarations().find((imp) => imp.getModuleSpecifierValue() === "intlayer");
		if (coreImport) {
			const existingNamedImports = coreImport.getNamedImports().map((ni) => ni.getName());
			const allImports = [...new Set([...existingNamedImports, ...otherMissingImports])].sort();
			coreImport.removeNamedImports();
			coreImport.addNamedImports(allImports.map((name) => ({ name })));
		} else sourceFile.insertImportDeclaration(0, {
			moduleSpecifier: "intlayer",
			namedImports: otherMissingImports.sort().map((name) => ({ name }))
		});
	}
	if (hasMissingFile) {
		if (!sourceFile.getImportDeclarations().find((imp) => imp.getModuleSpecifierValue() === "intlayer/file")) {
			const coreImportIndex = sourceFile.getImportDeclarations().findIndex((imp) => imp.getModuleSpecifierValue() === "intlayer");
			const insertIndex = coreImportIndex >= 0 ? coreImportIndex + 1 : 0;
			sourceFile.insertImportDeclaration(insertIndex, {
				moduleSpecifier: "intlayer/file",
				namedImports: [{ name: "file" }]
			});
		}
	}
	return true;
};
/**
* Detect whether the current source file is written in CommonJS style.
* Prefers ESM when import/export syntax is present; otherwise detects CJS via require/module.exports.
*/
const isCommonJS = (sourceFile) => {
	if (sourceFile.getImportDeclarations().length > 0) return false;
	if (sourceFile.getExportDeclarations().length > 0) return false;
	if (sourceFile.getExportAssignments().length > 0) return false;
	for (const statement of sourceFile.getStatements()) {
		if (!Node.isExpressionStatement(statement)) continue;
		const expression = statement.getExpression();
		if (!Node.isBinaryExpression(expression)) continue;
		const leftSide = expression.getLeft();
		if (!Node.isPropertyAccessExpression(leftSide)) continue;
		const leftExpression = leftSide.getExpression();
		const leftName = leftSide.getName();
		const isModuleExports = Node.isIdentifier(leftExpression) && leftExpression.getText() === "module" && leftName === "exports";
		const isExportsDefault = Node.isIdentifier(leftExpression) && leftExpression.getText() === "exports";
		if (isModuleExports || isExportsDefault) return true;
	}
	return sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression).some((call) => {
		const exp = call.getExpression();
		return Node.isIdentifier(exp) && exp.getText() === "require";
	});
};
/**
* Adds missing CommonJS requires for intlayer helpers.
* - Core helpers (t, md, insert, enu, cond, gender, nest) come from require('intlayer') via destructuring
* - file helper comes from require('intlayer/file') via destructuring
* Existing destructured requires are respected to avoid duplicates.
*/
const addMissingRequires = (sourceFile, requiredImports) => {
	if (requiredImports.size === 0) return false;
	const existingCoreNames = /* @__PURE__ */ new Set();
	let hasFileHelper = false;
	for (const varDecl of sourceFile.getVariableDeclarations()) {
		const init = varDecl.getInitializer();
		if (!init || !Node.isCallExpression(init)) continue;
		const callee = init.getExpression();
		if (!Node.isIdentifier(callee) || callee.getText() !== "require") continue;
		const arg = init.getArguments()[0];
		if (!arg || !Node.isStringLiteral(arg)) continue;
		const spec = arg.getLiteralValue();
		const nameNode = varDecl.getNameNode();
		if (spec === "intlayer") {
			if (Node.isObjectBindingPattern(nameNode)) for (const el of nameNode.getElements()) existingCoreNames.add(el.getNameNode().getText());
		}
		if (spec === "intlayer/file") {
			if (Node.isObjectBindingPattern(nameNode)) {
				for (const el of nameNode.getElements()) if (el.getNameNode().getText() === "file") hasFileHelper = true;
			} else if (Node.isIdentifier(nameNode) && nameNode.getText() === "file") hasFileHelper = true;
		}
	}
	const missingCore = Array.from(requiredImports).filter((n) => n !== "file").filter((n) => !existingCoreNames.has(n));
	const needsFile = requiredImports.has("file") && !hasFileHelper;
	if (missingCore.length === 0 && !needsFile) return false;
	let insertIndex = 0;
	const statements = sourceFile.getStatements();
	for (const st of statements) {
		if (Node.isExpressionStatement(st)) {
			const expr = st.getExpression();
			if (Node.isStringLiteral(expr)) {
				insertIndex += 1;
				continue;
			}
		}
		break;
	}
	const lines = [];
	if (missingCore.length > 0) {
		const sorted = Array.from(new Set(missingCore)).sort();
		lines.push(`const { ${sorted.join(", ")} } = require('intlayer');`);
	}
	if (needsFile) lines.push("const { file } = require('intlayer/file');");
	if (lines.length > 0) {
		sourceFile.insertStatements(insertIndex, lines.join("\n"));
		return true;
	}
	return false;
};
/**
* Serializes a metadata value to its string representation for code generation
* Handles: boolean, number, string, and array of strings
*/
const serializeMetadataValue = (value) => {
	if (Array.isArray(value)) return `[${value.map((item) => JSON.stringify(item)).join(", ")}]`;
	if (typeof value === "boolean" || typeof value === "number") return String(value);
	return JSON.stringify(value);
};
/**
* Updates a single property in the root object if the value has changed
*/
const updateMetadataProperty = (rootObject, propertyName, value) => {
	const property = rootObject.getProperty(propertyName);
	const serializedValue = serializeMetadataValue(value);
	if (property && Node.isPropertyAssignment(property)) {
		if (property.getInitializer()?.getText() !== serializedValue) {
			property.setInitializer(serializedValue);
			return true;
		}
	} else if (!property) {
		rootObject.addPropertyAssignment({
			name: propertyName,
			initializer: serializedValue
		});
		return true;
	}
	return false;
};
/**
* Updates dictionary metadata properties in the root object
* Supports: id, locale, filled, fill, title, description, tags, version, priority, live
* and any future fields that may be added
*/
const updateDictionaryMetadata = (rootObject, dictionary) => {
	let changed = false;
	for (const prop of [
		"id",
		"locale",
		"filled",
		"fill",
		"title",
		"description",
		"tags",
		"version",
		"priority",
		"live"
	]) {
		const value = dictionary[prop];
		if (value !== void 0) {
			if (updateMetadataProperty(rootObject, prop, value)) changed = true;
		}
	}
	return changed;
};
/**
* Locates the root dictionary object in the source file
*/
const findRootDictionaryObject = (sourceFile) => {
	const exportAssignment = sourceFile.getExportAssignment((_) => true);
	if (exportAssignment) {
		const expression = exportAssignment.getExpression();
		if (Node.isIdentifier(expression)) {
			const declarationByName = expression.getSymbol()?.getDeclarations()?.[0] ?? sourceFile.getVariableDeclaration(expression.getText());
			if (declarationByName && Node.isVariableDeclaration(declarationByName)) {
				const objectLiteral = unwrapToObjectLiteral(declarationByName.getInitializer());
				if (objectLiteral) return objectLiteral;
			}
		} else {
			const objectLiteral = unwrapToObjectLiteral(expression);
			if (objectLiteral) return objectLiteral;
		}
	}
	const variableDeclaration = sourceFile.getVariableDeclaration((variable) => {
		try {
			return variable.getType().getText().includes("Dictionary") || variable.getName() === "content" || variable.getName().toLowerCase().includes("dictionary");
		} catch {
			return variable.getName() === "content";
		}
	});
	if (variableDeclaration) {
		const objectLiteral = unwrapToObjectLiteral(variableDeclaration.getInitializer());
		if (objectLiteral) return objectLiteral;
	}
	for (const statement of sourceFile.getStatements()) {
		if (!Node.isExpressionStatement(statement)) continue;
		const expression = statement.getExpression();
		if (!Node.isBinaryExpression(expression)) continue;
		if (expression.getOperatorToken().getText() !== "=") continue;
		const leftSide = expression.getLeft();
		if (!Node.isPropertyAccessExpression(leftSide)) continue;
		const leftExpression = leftSide.getExpression();
		const leftName = leftSide.getName();
		const isModuleExports = Node.isIdentifier(leftExpression) && leftExpression.getText() === "module" && leftName === "exports";
		const isExportsDefault = Node.isIdentifier(leftExpression) && leftExpression.getText() === "exports" && leftName === "default";
		if (!isModuleExports && !isExportsDefault) continue;
		const rightSide = expression.getRight();
		if (Node.isObjectLiteralExpression(rightSide)) return rightSide;
		if (Node.isIdentifier(rightSide)) {
			const declaration = rightSide.getSymbol()?.getDeclarations()?.[0];
			if (declaration && Node.isVariableDeclaration(declaration)) {
				const objectLiteral = unwrapToObjectLiteral(declaration.getInitializer());
				if (objectLiteral) return objectLiteral;
			}
		}
	}
};
/**
* Updates a JavaScript/TypeScript file based on the provided dictionary.
* It targets a specific dictionary object within the file and updates its
* metadata (title, description, tags) and content entries.
*
* This function now supports inserting translation keys into nested objects
* within arrays. For example, if you have:
* ```
* content: [
*   { question: t({ en: '...', fr: '...' }) }
* ]
* ```
*
* You can add a new locale (e.g., 'pl') by providing a dictionary with:
* ```
* {
*   content: [
*     { question: { [NodeType.Translation]: { en: '...', fr: '...', pl: '...' } } }
*   ]
* }
* ```
*
* The function will:
* 1. Detect the existing array structure
* 2. Navigate into each array element (if it's an object)
* 3. Recursively process nested properties
* 4. Update translation maps while preserving existing locales
*/
const transformJSFile = async (fileContent, dictionary, fallbackLocale) => {
	try {
		if (!dictionary || typeof dictionary !== "object") return fileContent;
		const sourceFile = new Project({
			useInMemoryFileSystem: true,
			skipAddingFilesFromTsConfig: true,
			skipFileDependencyResolution: true,
			compilerOptions: {
				allowJs: true,
				jsx: ts.JsxEmit.Preserve
			},
			manipulationSettings: {
				indentationText: IndentationText.TwoSpaces,
				quoteKind: QuoteKind.Double,
				newLineKind: NewLineKind.LineFeed
			}
		}).createSourceFile("file.tsx", fileContent, { overwrite: true });
		const rootObject = findRootDictionaryObject(sourceFile);
		if (!rootObject) return fileContent;
		let changed = false;
		const requiredImports = /* @__PURE__ */ new Set();
		if (updateDictionaryMetadata(rootObject, dictionary)) changed = true;
		if (dictionary.content) {
			const contentProperty = rootObject.getProperty("content");
			let contentObject;
			let isContentArrayInSource = false;
			if (contentProperty && Node.isPropertyAssignment(contentProperty)) {
				contentObject = contentProperty.getInitializerIfKind(SyntaxKind.ObjectLiteralExpression);
				isContentArrayInSource = !!contentProperty.getInitializerIfKind(SyntaxKind.ArrayLiteralExpression);
			}
			const effectiveFallbackLocale = fallbackLocale ?? "en";
			if (contentObject && !Array.isArray(dictionary.content)) {
				const dictContent = dictionary.content ?? {};
				if (processContentEntries(contentObject, dictContent, effectiveFallbackLocale, requiredImports, sourceFile)) changed = true;
			} else if (Array.isArray(dictionary.content) && isContentArrayInSource) {
				if (processArrayContent(rootObject, "content", dictionary.content ?? [], getExistingPropertyNames(rootObject), effectiveFallbackLocale, requiredImports, sourceFile)) changed = true;
			}
		}
		if (!changed) return fileContent;
		if ((isCommonJS(sourceFile) ? addMissingRequires(sourceFile, requiredImports) : addMissingImports(sourceFile, requiredImports)) || changed) return sourceFile.getFullText();
		return fileContent;
	} catch {
		return fileContent;
	}
};

//#endregion
export { transformJSFile };
//# sourceMappingURL=transformJSFile.mjs.map