import { formatPaginatedResponse, formatResponse } from "../utils/responseData.mjs";
import { ErrorHandler } from "../utils/errors/ErrorHandler.mjs";
import { getDictionariesByTags } from "../services/dictionary.service.mjs";
import { findTags, getTagsByKeys } from "../services/tag.service.mjs";
import { askDocQuestion as askDocQuestion$1 } from "../utils/AI/askDocQuestion/askDocQuestion.mjs";
import { aiDefaultOptions, auditDictionary } from "../utils/AI/auditDictionary/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$1, auditDictionaryField } from "../utils/AI/auditDictionaryField/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$2, auditDictionaryMetadata as auditDictionaryMetadata$1 } from "../utils/AI/auditDictionaryMetadata/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$3, auditTag as auditTag$1 } from "../utils/AI/auditTag/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$4, autocomplete as autocomplete$1 } from "../utils/AI/autocomplete/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$5, customQuery as customQuery$2 } from "../utils/AI/customQuery/index.mjs";
import { aiDefaultOptions as aiDefaultOptions$6, translateJSON as translateJSON$2 } from "../utils/AI/translateJSON/index.mjs";
import { getDiscussionFiltersAndPagination } from "../utils/filtersAndPagination/getDiscussionFiltersAndPagination.mjs";
import { DiscussionModel } from "../models/discussion.model.mjs";
import { getAIConfig } from "@intlayer/ai";

//#region src/controllers/ai.controller.ts
const customQuery = async (req, res, _next) => {
	const { aiOptions, tagsKeys, ...rest } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions$5,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		const auditResponse = await customQuery$2({
			...rest,
			aiConfig,
			applicationContext: aiOptions?.applicationContext
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "QUERY_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
const translateJSON = async (req, res, _next) => {
	const { project } = res.locals;
	const { aiOptions, tagsKeys, ...rest } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions$6,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		let tags = [];
		if (project?.organizationId && tagsKeys) tags = await getTagsByKeys(tagsKeys, project.organizationId);
		const auditResponse = await translateJSON$2({
			...rest,
			aiConfig,
			applicationContext: aiOptions?.applicationContext,
			tags
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "AUDIT_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const auditContentDeclaration = async (req, res, _next) => {
	const { project } = res.locals;
	const { fileContent, filePath, aiOptions, locales, defaultLocale, tagsKeys } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		let tags = [];
		if (project?.organizationId) tags = await getTagsByKeys(tagsKeys, project.organizationId);
		const auditResponse = await auditDictionary({
			fileContent,
			filePath,
			aiConfig,
			applicationContext: aiOptions?.applicationContext,
			locales,
			defaultLocale,
			tags
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "AUDIT_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const auditContentDeclarationField = async (req, res, _next) => {
	const { project } = res.locals;
	const { fileContent, aiOptions, locales, tagsKeys, keyPath } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions$1,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		let tags = [];
		if (project?.organizationId) tags = await getTagsByKeys(tagsKeys, project.organizationId);
		const auditResponse = await auditDictionaryField({
			fileContent,
			aiConfig,
			applicationContext: aiOptions?.applicationContext,
			locales,
			tags,
			keyPath
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "AUDIT_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const auditContentDeclarationMetadata = async (req, res, _next) => {
	const { organization } = res.locals;
	const { fileContent, aiOptions } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions$2,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		const tags = await findTags({ organizationId: organization?.id }, 0, 1e3);
		const auditResponse = await auditDictionaryMetadata$1({
			fileContent,
			aiConfig,
			applicationContext: aiOptions?.applicationContext,
			tags
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "AUDIT_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of dictionaries based on filters and pagination.
*/
const auditTag = async (req, res, _next) => {
	const { project } = res.locals;
	const { aiOptions, tag } = req.body;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: aiOptions,
			defaultOptions: aiDefaultOptions$3,
			accessType: ["registered_user", "apiKey"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	try {
		let dictionaries = [];
		if (project?.organizationId) dictionaries = await getDictionariesByTags([tag.key], project.id);
		const auditResponse = await auditTag$1({
			aiConfig,
			dictionaries,
			tag,
			applicationContext: aiOptions?.applicationContext
		});
		if (!auditResponse) {
			ErrorHandler.handleGenericErrorResponse(res, "AUDIT_FAILED");
			return;
		}
		const responseData = formatResponse({ data: auditResponse });
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
const askDocQuestion = async (req, res, _next) => {
	const { messages = [], discussionId } = req.body;
	const { user, project, organization } = res.locals;
	let aiConfig;
	try {
		aiConfig = await getAIConfig({
			userOptions: {},
			accessType: ["public"]
		}, !!res.locals.user);
	} catch (_error) {
		ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
		return;
	}
	res.setHeader("Content-Type", "text/event-stream; charset=utf-8");
	res.setHeader("Cache-Control", "no-cache, no-transform");
	res.setHeader("Connection", "keep-alive");
	res.setHeader("X-Accel-Buffering", "no");
	res.flushHeaders?.();
	res.write(": connected\n\n");
	res.flush?.();
	askDocQuestion$1(messages, aiConfig, { onMessage: (chunk) => {
		res.write(`data: ${JSON.stringify({ chunk })}\n\n`);
		res.flush?.();
	} }).then(async (fullResponse) => {
		const lastUserMessageContent = messages.findLast((message) => message.role === "user")?.content;
		if ((lastUserMessageContent ? lastUserMessageContent.split(" ").length : 0) > 2) await DiscussionModel.findOneAndUpdate({ discussionId }, { $set: {
			discussionId,
			userId: user?.id,
			projectId: project?.id,
			organizationId: organization?.id,
			messages: [...messages.map((msg) => ({
				role: msg.role,
				content: msg.content,
				timestamp: msg.timestamp
			})), {
				role: "assistant",
				content: fullResponse.response,
				relatedFiles: fullResponse.relatedFiles,
				timestamp: /* @__PURE__ */ new Date()
			}]
		} }, {
			upsert: true,
			new: true
		});
		res.write(`data: ${JSON.stringify({
			done: true,
			response: fullResponse
		})}\n\n`);
		res.end();
	}).catch((err) => {
		res.write(`event: error\ndata: ${JSON.stringify({ message: err.message })}\n\n`);
		res.end();
	});
};
const autocomplete = async (req, res, _next) => {
	try {
		const { text, aiOptions, contextBefore, currentLine, contextAfter } = req.body;
		let aiConfig;
		try {
			aiConfig = await getAIConfig({
				userOptions: aiOptions,
				defaultOptions: aiDefaultOptions$4,
				accessType: ["public"]
			}, !!res.locals.user);
		} catch (_error) {
			ErrorHandler.handleGenericErrorResponse(res, "AI_ACCESS_DENIED");
			return;
		}
		const responseData = formatResponse({ data: await autocomplete$1({
			text,
			aiConfig,
			applicationContext: aiOptions?.applicationContext,
			contextBefore,
			currentLine,
			contextAfter
		}) ?? {
			autocompletion: "",
			tokenUsed: 0
		} });
		res.json(responseData);
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};
/**
* Retrieves a list of discussions with filters and pagination.
* Only the owner or admins can access. By default, users only see their own.
*/
const getDiscussions = async (req, res, _next) => {
	const { user, roles } = res.locals;
	const { filters, sortOptions, pageSize, skip, page, getNumberOfPages } = getDiscussionFiltersAndPagination(req, res);
	const includeMessages = req.query?.includeMessages !== "false";
	if (!user) {
		ErrorHandler.handleGenericErrorResponse(res, "USER_NOT_DEFINED");
		return;
	}
	try {
		const projection = includeMessages ? {} : { messages: 0 };
		const discussions = await DiscussionModel.find(filters, projection).sort(sortOptions).skip(skip).limit(pageSize).lean();
		const numberOfMessagesById = {};
		if (!includeMessages && discussions.length > 0) {
			const ids = discussions.map((d) => d._id);
			const counts = await DiscussionModel.aggregate([{ $match: { _id: { $in: ids } } }, { $project: { numberOfMessages: { $size: { $ifNull: ["$messages", []] } } } }]);
			for (const c of counts) numberOfMessagesById[String(c._id)] = c.numberOfMessages ?? 0;
		}
		const allOwnedByUser = discussions.every((d) => String(d.userId) === String(user.id));
		if (!(roles.includes("admin") || allOwnedByUser)) {
			ErrorHandler.handleGenericErrorResponse(res, "PERMISSION_DENIED");
			return;
		}
		const totalItems = await DiscussionModel.countDocuments(filters);
		const responseData = formatPaginatedResponse({
			data: discussions.map((d) => ({
				...d,
				id: String(d._id ?? d.id),
				numberOfMessages: includeMessages ? Array.isArray(d.messages) ? d.messages.length : 0 : numberOfMessagesById[String(d._id ?? d.id)] ?? 0
			})),
			page,
			pageSize,
			totalPages: getNumberOfPages(totalItems),
			totalItems
		});
		res.json(responseData);
		return;
	} catch (error) {
		ErrorHandler.handleAppErrorResponse(res, error);
		return;
	}
};

//#endregion
export { askDocQuestion, auditContentDeclaration, auditContentDeclarationField, auditContentDeclarationMetadata, auditTag, autocomplete, customQuery, getDiscussions, translateJSON };
//# sourceMappingURL=ai.controller.mjs.map