import { runParallel } from "./chokidar/dist/esm/utils/runParallel/index.mjs";
import { buildDictionary } from "./chokidar/dist/esm/buildIntlayerDictionary/buildIntlayerDictionary.mjs";
import { getUnmergedDictionaries } from "./unmerged-dictionaries-entry/dist/esm/index.mjs";
import { getDictionaries } from "./dictionaries-entry/dist/esm/index.mjs";
import { getLocalizedContent } from "./core/dist/esm/deepTransformPlugins/getLocalizedContent.mjs";
import { IntlayerEventListener } from "./IntlayerEventListener.mjs";
import { version } from "./config/package.mjs";
import { getAppLogger, getConfiguration } from "@intlayer/config";
import { createServer } from "node:http";

//#region ../@intlayer/cli/dist/esm/liveSync.mjs
const writeDictionary = async (dictionary, configuration) => {
	getAppLogger(configuration)(`Writing dictionary ${dictionary.key}`);
	await buildDictionary([dictionary], configuration);
};
const liveSync = async (options) => {
	const configuration = getConfiguration(options?.configOptions);
	const appLogger = getAppLogger(configuration);
	const { liveSyncPort, liveSyncURL } = configuration.editor;
	let parallelProcess = null;
	let eventListener = null;
	if (options?.with) {
		parallelProcess = runParallel(options.with);
		parallelProcess.result.catch(() => {});
	}
	if (configuration.editor.liveSync && configuration.editor.backendURL && configuration.editor.clientId && configuration.editor.clientSecret) {
		eventListener = new IntlayerEventListener(configuration);
		eventListener.onConnectionOpen = () => {
			appLogger("Live sync connection established");
		};
		eventListener.onConnectionError = (error) => {
			const errorEvent = error;
			appLogger(`Live sync connection error: ${errorEvent.message ?? "Unknown error"}`, { level: "warn" });
			if (errorEvent.message?.includes("terminated") || errorEvent.message?.includes("closed")) appLogger("Server connection was terminated, automatic reconnection will be attempted...", { level: "info" });
		};
		eventListener.onDictionaryAdded = (dictionary) => writeDictionary(dictionary, configuration);
		eventListener.onDictionaryChange = (dictionary) => writeDictionary(dictionary, configuration);
		eventListener.onDictionaryDeleted = (dictionary) => writeDictionary(dictionary, configuration);
		try {
			await eventListener.initialize();
		} catch (error) {
			appLogger("Failed to initialize IntlayerEventListener:", { level: "error" });
			appLogger(`Error: ${error instanceof Error ? error.message : String(error)}`, { level: "error" });
		}
	} else if (!configuration.editor.liveSync) appLogger("Hot reload is disabled. Please enable it in the configuration (editor.liveSync).");
	else if (!configuration.editor.clientId || !configuration.editor.clientSecret) appLogger("Missing client credentials for hot reload. Please configure clientId and clientSecret");
	const server = createServer(async (req, res) => {
		if (req.method === "OPTIONS") {
			res.writeHead(200, {
				"Access-Control-Allow-Origin": "*",
				"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
				"Access-Control-Allow-Headers": "Content-Type, Authorization"
			});
			res.end();
			return;
		}
		if (req.url?.startsWith("/dictionaries")) {
			res.writeHead(200, {
				"Content-Type": "application/json; charset=utf-8",
				"Cache-Control": "no-store",
				"Access-Control-Allow-Origin": "*",
				"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
				"Access-Control-Allow-Headers": "Content-Type, Authorization"
			});
			const dictionaries = getDictionaries(configuration);
			if (req.url.startsWith("/dictionaries/")) {
				const [key, locale] = decodeURIComponent(req.url).slice(14).split("/");
				const dictionary = dictionaries[key] ?? null;
				if (locale) {
					const sourceLocaleContent = getLocalizedContent(dictionary.content, locale, {
						dictionaryKey: key,
						keyPath: []
					});
					res.end(JSON.stringify(sourceLocaleContent));
					return;
				}
				res.end(JSON.stringify(dictionary));
				return;
			}
			res.end(JSON.stringify(dictionaries));
			return;
		}
		if (req.url?.startsWith("/unmerged_dictionaries")) {
			res.writeHead(200, {
				"Content-Type": "application/json; charset=utf-8",
				"Cache-Control": "no-store",
				"Access-Control-Allow-Origin": "*",
				"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
				"Access-Control-Allow-Headers": "Content-Type, Authorization"
			});
			const unmergedDictionaries = getUnmergedDictionaries(configuration);
			if (req.url.startsWith("/unmerged_dictionaries/")) {
				const one = unmergedDictionaries[decodeURIComponent(req.url.slice(23))] ?? null;
				res.end(JSON.stringify(one));
				return;
			}
			res.end(JSON.stringify(unmergedDictionaries));
			return;
		}
		if (req.url === "/configuration") {
			res.writeHead(200, {
				"Content-Type": "application/json; charset=utf-8",
				"Cache-Control": "no-store",
				"Access-Control-Allow-Origin": "*",
				"Access-Control-Allow-Methods": "GET, POST, PUT, DELETE, OPTIONS",
				"Access-Control-Allow-Headers": "Content-Type, Authorization"
			});
			res.end(JSON.stringify(configuration));
			return;
		}
		if (req.url === "/health") {
			res.writeHead(200, { "Content-Type": "application/json; charset=utf-8" });
			res.end(JSON.stringify({ status: "ok" }));
			return;
		}
		res.end("Not found");
	});
	const getLiveSyncParam = () => {
		if (!configuration.editor.liveSync) return "\x1B[31m✗ Disabled\x1B[0m";
		return "\x1B[32m✓ Enabled\x1B[0m";
	};
	server.listen(liveSyncPort, () => {
		console.log(`
      \x1b[1;90mINTLAYER v${version}\x1b[0m
  
      Live server running at:          \x1b[90m${liveSyncURL}\x1b[0m
      - Backend URL:                   \x1b[90m${configuration.editor.backendURL ?? "-"}\x1b[0m
      - Live sync:                     ${getLiveSyncParam()}
      - Parallel process:              ${options?.with ? `\x1b[90m${Array.isArray(options.with) ? options.with.join(" ") : options.with}\x1b[0m` : "-"}
      - Access key:                    ${configuration.editor.clientId ?? "-"}
      `);
	});
	const cleanup = () => {
		if (eventListener) {
			appLogger("Closing SSE connection...");
			eventListener.cleanup();
		}
		if (parallelProcess) parallelProcess.kill();
		server.close(() => {
			appLogger("Live sync server stopped");
			process.exit(0);
		});
	};
	process.on("SIGINT", cleanup);
	process.on("SIGTERM", cleanup);
	process.on("exit", cleanup);
};

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