import { ensureArray, getTargetUnmergedDictionaries } from "../getTargetDictionary.mjs";
import { checkAIAccess } from "../utils/checkAccess.mjs";
import { listTranslationsTasks } from "./listTranslationsTasks.mjs";
import { translateDictionary } from "./translateDictionary.mjs";
import { writeFill } from "./writeFill.mjs";
import { formatPath, getGlobalLimiter, getTaskLimiter, prepareIntlayer, writeContentDeclaration } from "@intlayer/chokidar";
import { ANSIColors, colon, colorize, colorizeKey, colorizePath, getAppLogger, getConfiguration } from "@intlayer/config";
import { basename, relative } from "node:path";

//#region src/fill/fill.ts
const NB_CONCURRENT_TRANSLATIONS = 7;
/**
* Fill translations based on the provided options.
*/
const fill = async (options) => {
	const configuration = getConfiguration(options?.configOptions);
	const appLogger = getAppLogger(configuration);
	if (options?.build === true) await prepareIntlayer(configuration, { forceRun: true });
	else if (typeof options?.build === "undefined") await prepareIntlayer(configuration);
	const { defaultLocale, locales } = configuration.internationalization;
	const mode = options?.mode ?? "complete";
	const baseLocale = options?.sourceLocale ?? defaultLocale;
	const outputLocales = options?.outputLocales ? ensureArray(options.outputLocales) : locales;
	if (!await checkAIAccess(configuration, options?.aiOptions)) return;
	const targetUnmergedDictionaries = await getTargetUnmergedDictionaries(options);
	const affectedDictionaryKeys = /* @__PURE__ */ new Set();
	targetUnmergedDictionaries.forEach((dict) => {
		affectedDictionaryKeys.add(dict.key);
	});
	const keysToProcess = Array.from(affectedDictionaryKeys);
	appLogger(["Affected dictionary keys for processing:", keysToProcess.length > 0 ? keysToProcess.map((key) => colorizeKey(key)).join(", ") : colorize("No keys found", ANSIColors.YELLOW)]);
	if (keysToProcess.length === 0) return;
	/**
	* List the translations tasks
	*
	* Create a list of per-locale dictionaries to translate
	*
	* In 'complete' mode, filter only the missing locales to translate
	*/
	const translationTasks = listTranslationsTasks(targetUnmergedDictionaries.map((dictionary) => dictionary.localId), outputLocales, mode, baseLocale, configuration);
	const nbConcurrentTranslations = options?.nbConcurrentTranslations ?? NB_CONCURRENT_TRANSLATIONS;
	const globalLimiter = getGlobalLimiter(nbConcurrentTranslations);
	const taskLimiter = getTaskLimiter(Math.max(1, Math.min(options?.nbConcurrentTasks ?? nbConcurrentTranslations, translationTasks.length)));
	const runners = translationTasks.map((task) => taskLimiter(async () => {
		const relativePath = relative(configuration?.content?.baseDir ?? process.cwd(), task?.dictionaryFilePath ?? "");
		appLogger(`${task.dictionaryPreset} Processing ${colorizePath(basename(relativePath))}`, { level: "info" });
		const translationTaskResult = await translateDictionary(task, configuration, {
			mode,
			aiOptions: options?.aiOptions,
			fillMetadata: !options?.skipMetadata,
			onHandle: globalLimiter
		});
		if (!translationTaskResult?.dictionaryOutput) return;
		const { dictionaryOutput, sourceLocale } = translationTaskResult;
		if (typeof dictionaryOutput.fill === "string" || typeof dictionaryOutput.fill === "object") await writeFill(dictionaryOutput, outputLocales, [sourceLocale], configuration);
		else {
			await writeContentDeclaration(dictionaryOutput, configuration);
			if (dictionaryOutput.filePath) appLogger(`${colon([
				" - ",
				colorize("[", ANSIColors.GREY_DARK),
				colorizeKey(dictionaryOutput.key),
				colorize("]", ANSIColors.GREY_DARK)
			].join(""), { colSize: 15 })} Content declaration written to ${formatPath(basename(dictionaryOutput.filePath))}`, { level: "info" });
		}
	}));
	await Promise.all(runners);
	await globalLimiter.onIdle();
};

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