import { NextResponse } from "next/server";
import { z } from "zod";
import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
import { hasRequiredFeatures } from "../../../../../../lib/auth.js";
import {
  AiChatConversationAccessError,
  AiChatParticipantNotFoundError,
  createConversationStorage
} from "../../../../../../lib/conversation-storage.js";
import { emitAiAssistantEvent } from "../../../../../../events.js";
const REQUIRED_FEATURE = "ai_assistant.view";
const MANAGE_CONVERSATIONS_FEATURE = "ai_assistant.conversations.manage";
const SHARE_CONVERSATIONS_FEATURE = "ai_assistant.conversations.share";
const participantParamsSchema = z.object({
  conversationId: z.string().trim().min(1, "conversationId must be a non-empty string").max(128, "conversationId exceeds the maximum length of 128 characters"),
  userId: z.string().uuid("userId must be a valid UUID")
});
const openApi = {
  tag: "AI Assistant",
  summary: "Revoke a conversation participant",
  methods: {
    DELETE: {
      operationId: "aiAssistantRevokeConversationParticipant",
      summary: "Revoke a participant from a conversation (soft-delete).",
      description: 'Soft-deletes the participant row. If no active non-owner participants remain, the conversation visibility is reset to "private". Only the conversation owner or a manager may revoke participants.',
      responses: [
        {
          status: 204,
          description: "Participant revoked."
        }
      ],
      errors: [
        { status: 400, description: "Invalid path parameters." },
        { status: 401, description: "Unauthenticated caller." },
        { status: 403, description: "Caller lacks required features or is not the owner." },
        { status: 404, description: "Conversation not found." }
      ]
    }
  }
};
const metadata = {
  DELETE: { requireAuth: true, requireFeatures: [REQUIRED_FEATURE] }
};
function jsonError(status, message, code, extra) {
  return NextResponse.json({ error: message, code, ...extra ?? {} }, { status });
}
async function DELETE(req, context) {
  const auth = await getAuthFromRequest(req);
  if (!auth) return jsonError(401, "Unauthorized", "unauthenticated");
  const rawParams = await context.params;
  const parseResult = participantParamsSchema.safeParse(rawParams);
  if (!parseResult.success) {
    return jsonError(400, "Invalid path parameters.", "validation_error", {
      issues: parseResult.error.issues
    });
  }
  if (!auth.tenantId) return jsonError(404, "Conversation not found.", "conversation_not_found");
  const container = await createRequestContainer();
  const rbacService = container.resolve("rbacService");
  const acl = await rbacService.loadAcl(auth.sub, {
    tenantId: auth.tenantId,
    organizationId: auth.orgId
  });
  if (!hasRequiredFeatures([REQUIRED_FEATURE], acl.features, acl.isSuperAdmin, rbacService)) {
    return jsonError(403, `Caller lacks required feature "${REQUIRED_FEATURE}".`, "forbidden");
  }
  const canShare = hasRequiredFeatures(
    [SHARE_CONVERSATIONS_FEATURE],
    acl.features,
    acl.isSuperAdmin,
    rbacService
  );
  if (!canShare) {
    return jsonError(
      403,
      `Caller lacks required feature "${SHARE_CONVERSATIONS_FEATURE}".`,
      "forbidden"
    );
  }
  try {
    const repo = createConversationStorage(container);
    await repo.revokeParticipant(
      parseResult.data.conversationId,
      parseResult.data.userId,
      {
        tenantId: auth.tenantId,
        organizationId: auth.orgId ?? null,
        userId: auth.sub,
        canManageConversations: hasRequiredFeatures(
          [MANAGE_CONVERSATIONS_FEATURE],
          acl.features,
          acl.isSuperAdmin,
          rbacService
        )
      }
    );
    try {
      await emitAiAssistantEvent(
        "ai_assistant.conversation.unshared",
        {
          conversationId: parseResult.data.conversationId,
          tenantId: auth.tenantId,
          organizationId: auth.orgId ?? null,
          ownerUserId: auth.sub,
          participantUserId: parseResult.data.userId
        },
        { persistent: false }
      );
    } catch {
    }
    return new NextResponse(null, { status: 204 });
  } catch (err) {
    if (err instanceof AiChatParticipantNotFoundError) {
      return jsonError(404, err.message || "Participant not found or already revoked.", "participant_not_found");
    }
    if (err instanceof AiChatConversationAccessError) {
      return jsonError(403, err.message || "Access denied.", "forbidden");
    }
    return jsonError(500, "Internal server error.", "internal_error");
  }
}
export {
  DELETE,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
