import { z } from "zod";
import { registerCommand } from "@open-mercato/shared/lib/commands";
import { Message, MessageAccessToken, MessageRecipient } from "../data/entities.js";
import { emitMessagesEvent } from "../events.js";
import { hashAuthToken } from "../../auth/lib/tokenHash.js";
import { MAX_TOKEN_USE_COUNT, consumeMessageAccessToken } from "../lib/tokenConsumption.js";
const consumeTokenSchema = z.object({
  token: z.string().min(1)
});
const consumeTokenCommand = {
  id: "messages.tokens.consume",
  async execute(rawInput, ctx) {
    const input = consumeTokenSchema.parse(rawInput);
    const em = ctx.container.resolve("em").fork();
    const hashedToken = hashAuthToken(input.token);
    const accessToken = await em.findOne(MessageAccessToken, { token: hashedToken });
    if (!accessToken) {
      throw new Error("Invalid or expired link");
    }
    const result = await consumeMessageAccessToken(em, accessToken.id);
    if (!result.ok) {
      if (result.reason === "expired") throw new Error("This link has expired");
      throw new Error("This link can no longer be used");
    }
    em.clear();
    const message = await em.findOne(Message, {
      id: accessToken.messageId,
      deletedAt: null
    });
    if (!message) {
      throw new Error("Message not found");
    }
    const recipient = await em.findOne(MessageRecipient, {
      messageId: accessToken.messageId,
      recipientUserId: accessToken.recipientUserId,
      deletedAt: null
    });
    if (!recipient) {
      throw new Error("Invalid or expired link");
    }
    let becameRead = false;
    if (recipient.status === "unread") {
      recipient.status = "read";
      recipient.readAt = /* @__PURE__ */ new Date();
      becameRead = true;
    }
    await em.flush();
    if (becameRead) {
      await emitMessagesEvent(
        "messages.message.read",
        {
          messageId: message.id,
          recipientUserId: accessToken.recipientUserId,
          userId: accessToken.recipientUserId,
          source: "token",
          tenantId: message.tenantId,
          organizationId: message.organizationId ?? null
        },
        { persistent: true }
      );
    }
    return {
      messageId: message.id,
      recipientUserId: accessToken.recipientUserId
    };
  }
};
registerCommand(consumeTokenCommand);
export {
  MAX_TOKEN_USE_COUNT
};
//# sourceMappingURL=tokens.js.map
