import { t as validateIdentifier } from "../../../../../../validate-VPnKoIzW.mjs";
import "../../../../../../after-B1IIdH3Y.mjs";
import "../../../../../../object-cache-Bok5j2ae.mjs";
import "../../../../../../base64-CmWvODNW.mjs";
import "../../../../../../types-CuW0zWDA.mjs";
import { t as CommentRepository } from "../../../../../../comment-CzeatwBV.mjs";
import "../../../../../../options-DTTML-Tx.mjs";
import { a as unwrapResult, i as requireDb, n as apiSuccess, r as handleError, t as apiError } from "../../../../../../error-CkAseSqZ.mjs";
import { n as parseBody, t as isParseError } from "../../../../../../parse-GmjecGct.mjs";
import { yt as createCommentBody } from "../../../../../../redirects-DXEXBAII.mjs";
import "../../../../../../byline-fields-2Lp5Hbgf.mjs";
import "../../../../../../status-CqJQX1QN.mjs";
import "../../../../../../api/schemas/index.mjs";
import { t as extractRequestMeta } from "../../../../../../request-meta-DbvXaAvU.mjs";
import { i as resolveSecretsCached } from "../../../../../../secrets-kp760LlD.mjs";
import { c as hashIp, s as handleCommentList, t as checkRateLimit } from "../../../../../../comments-BLE-jv5k.mjs";
import { t as getSiteBaseUrl } from "../../../../../../site-url-BBfDTgZB.mjs";
import { i as sendCommentNotification, t as createComment } from "../../../../../../service-DQmiBMzt.mjs";

//#region src/astro/routes/api/comments/[collection]/[contentId]/index.ts
const prerender = false;
/**
* List approved comments for a content item (public, no auth required)
*/
const GET = async ({ params, url, locals }) => {
	const { emdash } = locals;
	const { collection, contentId } = params;
	if (!collection || !contentId) return apiError("VALIDATION_ERROR", "Collection and content ID required", 400);
	const dbErr = requireDb(emdash?.db);
	if (dbErr) return dbErr;
	try {
		const limit = Math.min(Number(url.searchParams.get("limit") || 50), 100);
		const cursor = url.searchParams.get("cursor") ?? void 0;
		const threaded = url.searchParams.get("threaded") === "true";
		const collectionRow = await emdash.db.selectFrom("_emdash_collections").select(["comments_enabled"]).where("slug", "=", collection).executeTakeFirst();
		if (!collectionRow) return apiError("NOT_FOUND", `Collection '${collection}' not found`, 404);
		if (!collectionRow.comments_enabled) return apiError("COMMENTS_DISABLED", "Comments are not enabled for this collection", 403);
		return unwrapResult(await handleCommentList(emdash.db, collection, contentId, {
			limit,
			cursor,
			threaded
		}));
	} catch (error) {
		return handleError(error, "Failed to list comments", "COMMENT_LIST_ERROR");
	}
};
/**
* Submit a comment (public, gated by anti-spam checks)
*/
const POST = async ({ params, request, locals }) => {
	const { emdash, user } = locals;
	const { collection, contentId } = params;
	if (!collection || !contentId) return apiError("VALIDATION_ERROR", "Collection and content ID required", 400);
	const dbErr = requireDb(emdash?.db);
	if (dbErr) return dbErr;
	try {
		const body = await parseBody(request, createCommentBody);
		if (isParseError(body)) return body;
		const collectionRow = await emdash.db.selectFrom("_emdash_collections").select([
			"comments_enabled",
			"comments_moderation",
			"comments_closed_after_days",
			"comments_auto_approve_users"
		]).where("slug", "=", collection).executeTakeFirst();
		if (!collectionRow) return apiError("NOT_FOUND", `Collection '${collection}' not found`, 404);
		if (!collectionRow.comments_enabled) return apiError("COMMENTS_DISABLED", "Comments are not enabled for this collection", 403);
		validateIdentifier(collection, "collection");
		const contentRow = await emdash.db.selectFrom(`ec_${collection}`).select([
			"id",
			"slug",
			"author_id",
			"published_at"
		]).where("id", "=", contentId).where("status", "=", "published").where("deleted_at", "is", null).executeTakeFirst();
		if (!contentRow) return apiError("NOT_FOUND", "Content not found", 404);
		if (collectionRow.comments_closed_after_days > 0) {
			const publishedAt = contentRow.published_at;
			if (publishedAt) {
				const closedDate = new Date(publishedAt);
				closedDate.setDate(closedDate.getDate() + collectionRow.comments_closed_after_days);
				if (/* @__PURE__ */ new Date() > closedDate) return apiError("COMMENTS_CLOSED", "Comments are closed for this content", 403);
			}
		}
		if (body.website_url) return apiSuccess({
			status: "pending",
			message: "Comment submitted for review"
		});
		const meta = extractRequestMeta(request, emdash.config);
		const { ipSalt } = await resolveSecretsCached(emdash.db);
		let ipHash;
		if (meta.ip) ipHash = await hashIp(meta.ip, ipSalt);
		else ipHash = "unknown";
		const unknownBucketLimit = ipHash === "unknown" ? 20 : void 0;
		if (await checkRateLimit(emdash.db, ipHash, unknownBucketLimit)) return apiError("RATE_LIMITED", "Too many comments. Please try again later.", 429);
		const collectionSettings = {
			commentsEnabled: collectionRow.comments_enabled === 1,
			commentsModeration: collectionRow.comments_moderation,
			commentsClosedAfterDays: collectionRow.comments_closed_after_days,
			commentsAutoApproveUsers: collectionRow.comments_auto_approve_users === 1
		};
		let authorName = body.authorName;
		let authorEmail = body.authorEmail;
		let authorUserId = null;
		if (user) {
			authorName = user.name || authorName;
			authorEmail = user.email;
			authorUserId = user.id;
		}
		let resolvedParentId = body.parentId ?? null;
		if (body.parentId) {
			const parent = await new CommentRepository(emdash.db).findById(body.parentId);
			if (!parent) return apiError("VALIDATION_ERROR", "Parent comment not found", 400);
			if (parent.collection !== collection || parent.contentId !== contentId) return apiError("VALIDATION_ERROR", "Parent comment belongs to different content", 400);
			resolvedParentId = parent.parentId ?? parent.id;
		}
		const hookRunner = {
			async runBeforeCreate(event) {
				return emdash.hooks.runCommentBeforeCreate(event);
			},
			async runModerate(event) {
				const result = await emdash.hooks.invokeExclusiveHook("comment:moderate", event);
				if (!result) return {
					status: "pending",
					reason: "No moderator configured"
				};
				if (result.error) {
					console.error(`[comments] Moderation error (${result.pluginId}):`, result.error.message);
					return {
						status: "pending",
						reason: "Moderation error"
					};
				}
				return result.result;
			},
			fireAfterCreate(event) {
				emdash.hooks.runCommentAfterCreate(event).catch((err) => console.error("[comments] afterCreate error:", err instanceof Error ? err.message : err));
			},
			fireAfterModerate(event) {
				emdash.hooks.runCommentAfterModerate(event).catch((err) => console.error("[comments] afterModerate error:", err instanceof Error ? err.message : err));
			}
		};
		const typedContent = contentRow;
		let contentAuthor;
		if (typedContent.author_id) {
			const authorRow = await emdash.db.selectFrom("users").select([
				"id",
				"name",
				"email",
				"email_verified"
			]).where("id", "=", typedContent.author_id).executeTakeFirst();
			if (authorRow && authorRow.email_verified) contentAuthor = {
				id: authorRow.id,
				name: authorRow.name,
				email: authorRow.email
			};
		}
		const result = await createComment(emdash.db, {
			collection,
			contentId,
			parentId: resolvedParentId,
			authorName,
			authorEmail,
			authorUserId,
			body: body.body,
			ipHash,
			userAgent: meta.userAgent
		}, collectionSettings, hookRunner, {
			id: typedContent.id,
			collection,
			slug: typedContent.slug,
			author: contentAuthor
		});
		if (!result) return apiError("COMMENT_REJECTED", "Comment was rejected", 403);
		if (result.comment.status === "approved" && emdash.email && contentAuthor) try {
			const adminBaseUrl = await getSiteBaseUrl(emdash.db, request);
			await sendCommentNotification({
				email: emdash.email,
				comment: result.comment,
				contentAuthor,
				adminBaseUrl
			});
		} catch (err) {
			console.error("[comments] notification error:", err instanceof Error ? err.message : err);
		}
		return apiSuccess({
			id: result.comment.id,
			status: result.comment.status,
			message: result.comment.status === "approved" ? "Comment published" : "Comment submitted for review"
		}, 201);
	} catch (error) {
		return handleError(error, "Failed to submit comment", "COMMENT_CREATE_ERROR");
	}
};

//#endregion
export { GET, POST, prerender };
//# sourceMappingURL=index.mjs.map