import { Message, MessageRecipient } from "../../../data/entities.js";
import { attachOperationMetadataHeader } from "../../../lib/operationMetadata.js";
import { hasOrganizationAccess, resolveMessageContext } from "../../../lib/routeHelpers.js";
import { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from "../../guards.js";
import { errorResponseSchema, okResponseSchema } from "../../openapi.js";
const metadata = {
  PUT: { requireAuth: true, requireFeatures: ["messages.view"] },
  DELETE: { requireAuth: true, requireFeatures: ["messages.view"] }
};
const senderArchiveUnsupportedError = {
  code: "messages_sender_archive_unsupported",
  error: "You cannot archive messages you sent."
};
async function resolveRecipientContext(req, id) {
  const { ctx, scope } = await resolveMessageContext(req);
  const em = ctx.container.resolve("em").fork();
  const message = await em.findOne(Message, {
    id,
    tenantId: scope.tenantId,
    deletedAt: null
  });
  if (!message) {
    return { response: Response.json({ error: "Message not found" }, { status: 404 }) };
  }
  if (!hasOrganizationAccess(scope.organizationId, message.organizationId)) {
    return { response: Response.json({ error: "Access denied" }, { status: 403 }) };
  }
  const recipient = await em.findOne(MessageRecipient, {
    messageId: id,
    recipientUserId: scope.userId,
    deletedAt: null
  });
  if (!recipient) {
    if (message.senderUserId === scope.userId) {
      return { response: Response.json(senderArchiveUnsupportedError, { status: 403 }) };
    }
    return { response: Response.json({ error: "Access denied" }, { status: 403 }) };
  }
  return { ctx, scope, em, recipient };
}
async function PUT(req, { params }) {
  const context = await resolveRecipientContext(req, params.id);
  if ("response" in context) return context.response;
  const { ctx, scope } = context;
  const commandBus = ctx.container.resolve("commandBus");
  const guardResult = await runMessageMutationGuards(
    ctx.container,
    {
      tenantId: scope.tenantId,
      organizationId: scope.organizationId,
      userId: scope.userId,
      resourceKind: "messages.message",
      resourceId: params.id,
      operation: "update",
      requestMethod: req.method,
      requestHeaders: req.headers,
      mutationPayload: null
    },
    resolveUserFeatures(ctx.auth)
  );
  if (!guardResult.ok) {
    return Response.json(
      guardResult.errorBody ?? { error: "Operation blocked by guard" },
      { status: guardResult.errorStatus ?? 422 }
    );
  }
  const { logEntry } = await commandBus.execute("messages.recipients.archive", {
    input: {
      messageId: params.id,
      tenantId: scope.tenantId,
      organizationId: scope.organizationId,
      userId: scope.userId
    },
    ctx: {
      container: ctx.container,
      auth: ctx.auth ?? null,
      organizationScope: null,
      selectedOrganizationId: scope.organizationId,
      organizationIds: scope.organizationId ? [scope.organizationId] : null,
      request: req
    }
  });
  const response = Response.json({ ok: true });
  attachOperationMetadataHeader(response, logEntry, {
    resourceKind: "messages.message",
    resourceId: params.id
  });
  await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
    tenantId: scope.tenantId,
    organizationId: scope.organizationId,
    userId: scope.userId,
    resourceKind: "messages.message",
    resourceId: params.id,
    operation: "update",
    requestMethod: req.method,
    requestHeaders: req.headers
  });
  return response;
}
async function DELETE(req, { params }) {
  const context = await resolveRecipientContext(req, params.id);
  if ("response" in context) return context.response;
  const { ctx, scope } = context;
  const commandBus = ctx.container.resolve("commandBus");
  const guardResult = await runMessageMutationGuards(
    ctx.container,
    {
      tenantId: scope.tenantId,
      organizationId: scope.organizationId,
      userId: scope.userId,
      resourceKind: "messages.message",
      resourceId: params.id,
      operation: "update",
      requestMethod: req.method,
      requestHeaders: req.headers,
      mutationPayload: null
    },
    resolveUserFeatures(ctx.auth)
  );
  if (!guardResult.ok) {
    return Response.json(
      guardResult.errorBody ?? { error: "Operation blocked by guard" },
      { status: guardResult.errorStatus ?? 422 }
    );
  }
  const { logEntry } = await commandBus.execute("messages.recipients.unarchive", {
    input: {
      messageId: params.id,
      tenantId: scope.tenantId,
      organizationId: scope.organizationId,
      userId: scope.userId
    },
    ctx: {
      container: ctx.container,
      auth: ctx.auth ?? null,
      organizationScope: null,
      selectedOrganizationId: scope.organizationId,
      organizationIds: scope.organizationId ? [scope.organizationId] : null,
      request: req
    }
  });
  const response = Response.json({ ok: true });
  attachOperationMetadataHeader(response, logEntry, {
    resourceKind: "messages.message",
    resourceId: params.id
  });
  await runMessageMutationGuardAfterSuccess(guardResult.afterSuccessCallbacks, {
    tenantId: scope.tenantId,
    organizationId: scope.organizationId,
    userId: scope.userId,
    resourceKind: "messages.message",
    resourceId: params.id,
    operation: "update",
    requestMethod: req.method,
    requestHeaders: req.headers
  });
  return response;
}
const openApi = {
  tag: "Messages",
  methods: {
    PUT: {
      summary: "Archive message",
      responses: [
        { status: 200, description: "Message archived", schema: okResponseSchema }
      ],
      errors: [
        { status: 403, description: "Access denied or sender-only message cannot be archived", schema: errorResponseSchema },
        { status: 404, description: "Message not found", schema: errorResponseSchema }
      ]
    },
    DELETE: {
      summary: "Unarchive message",
      responses: [
        { status: 200, description: "Message unarchived", schema: okResponseSchema }
      ],
      errors: [
        { status: 403, description: "Access denied or sender-only message cannot be unarchived", schema: errorResponseSchema },
        { status: 404, description: "Message not found", schema: errorResponseSchema }
      ]
    }
  }
};
export {
  DELETE,
  PUT,
  metadata,
  openApi
};
//# sourceMappingURL=route.js.map
