import { z } from "zod";
import { parseBooleanFlag } from "@open-mercato/shared/lib/boolean";
import { sanitizeRichTextHref } from "@open-mercato/shared/lib/html/sanitizeRichText";
function collectDuplicateRecipientIds(recipients) {
  const seen = /* @__PURE__ */ new Set();
  const duplicates = /* @__PURE__ */ new Set();
  for (const recipient of recipients) {
    if (seen.has(recipient.userId)) {
      duplicates.add(recipient.userId);
      continue;
    }
    seen.add(recipient.userId);
  }
  return Array.from(duplicates);
}
function validateDefaultWithObjectsPayload(value, ctx) {
  if (value.type !== "messages.defaultWithObjects") return;
  if (!Array.isArray(value.objects) || value.objects.length === 0) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      path: ["objects"],
      message: "at least one object is required for messages.defaultWithObjects"
    });
    return;
  }
  value.objects.forEach((object, index) => {
    if (object.actionRequired === true) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["objects", index, "actionRequired"],
        message: "actionRequired must be false for messages.defaultWithObjects"
      });
    }
    if (typeof object.actionType === "string" && object.actionType.trim().length > 0) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["objects", index, "actionType"],
        message: "actionType is not allowed for messages.defaultWithObjects"
      });
    }
    if (typeof object.actionLabel === "string" && object.actionLabel.trim().length > 0) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["objects", index, "actionLabel"],
        message: "actionLabel is not allowed for messages.defaultWithObjects"
      });
    }
  });
}
const messageRecipientSchema = z.object({
  userId: z.string().uuid(),
  type: z.enum(["to", "cc", "bcc"]).optional().default("to")
});
const messageObjectSchema = z.object({
  entityModule: z.string().min(1),
  entityType: z.string().min(1),
  entityId: z.string().uuid(),
  actionRequired: z.boolean().optional().default(false),
  actionType: z.string().optional(),
  actionLabel: z.string().optional()
});
const messageActionSchema = z.object({
  id: z.string().min(1),
  label: z.string().min(1),
  labelKey: z.string().optional(),
  variant: z.enum(["default", "secondary", "destructive", "outline", "ghost"]).optional(),
  icon: z.string().optional(),
  commandId: z.string().optional(),
  href: z.string().optional().refine(
    (value) => value == null || sanitizeRichTextHref(value) != null,
    { message: "[internal] message action href must be http(s), mailto, tel, or a relative path" }
  ),
  isTerminal: z.boolean().optional(),
  confirmRequired: z.boolean().optional(),
  confirmMessage: z.string().optional()
});
const messageActionDataSchema = z.object({
  actions: z.array(messageActionSchema),
  primaryActionId: z.string().optional(),
  expiresAt: z.string().datetime().optional()
});
const composeMessageSchema = z.object({
  type: z.string().optional().default("default"),
  visibility: z.enum(["public", "internal"]).nullable().optional(),
  sourceEntityType: z.string().min(1).optional(),
  sourceEntityId: z.string().uuid().optional(),
  externalEmail: z.string().email().optional(),
  externalName: z.string().min(1).max(255).optional(),
  recipients: z.array(messageRecipientSchema).max(100).optional().default([]),
  subject: z.string().max(500).optional().default(""),
  body: z.string().max(5e4).optional().default(""),
  bodyFormat: z.enum(["text", "markdown"]).optional().default("text"),
  priority: z.enum(["low", "normal", "high", "urgent"]).optional().default("normal"),
  objects: z.array(messageObjectSchema).optional(),
  attachmentIds: z.array(z.string().uuid()).optional(),
  attachmentRecordId: z.string().min(1).max(255).optional(),
  actionData: messageActionDataSchema.optional(),
  sendViaEmail: z.boolean().optional().default(false),
  parentMessageId: z.string().uuid().optional(),
  isDraft: z.boolean().optional().default(false)
}).superRefine((value, ctx) => {
  const isDraft = value.isDraft ?? false;
  const visibility = value.visibility ?? "internal";
  const recipientCount = value.recipients.length;
  const hasExternalEmail = Boolean(value.externalEmail?.trim());
  const hasSubject = value.subject.trim().length > 0;
  const hasBody = value.body.trim().length > 0;
  if (!isDraft) {
    if (visibility === "public") {
      if (!hasExternalEmail) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["externalEmail"],
          message: "externalEmail is required when visibility is public"
        });
      }
      if (recipientCount > 0) {
        ctx.addIssue({
          code: z.ZodIssueCode.custom,
          path: ["recipients"],
          message: "recipients must be empty when visibility is public"
        });
      }
    } else if (recipientCount === 0) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["recipients"],
        message: "at least one recipient is required when visibility is internal"
      });
    }
    if (!hasSubject) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["subject"],
        message: "subject is required"
      });
    }
    if (!hasBody) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["body"],
        message: "body is required"
      });
    }
  }
  const duplicateRecipientIds = collectDuplicateRecipientIds(value.recipients);
  if (duplicateRecipientIds.length > 0) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      path: ["recipients"],
      message: "recipient user ids must be unique"
    });
  }
  validateDefaultWithObjectsPayload(value, ctx);
});
const updateDraftSchema = z.object({
  type: z.string().optional(),
  visibility: z.enum(["public", "internal"]).nullable().optional(),
  sourceEntityType: z.string().min(1).optional(),
  sourceEntityId: z.string().uuid().optional(),
  externalEmail: z.string().email().optional(),
  externalName: z.string().min(1).max(255).optional(),
  recipients: z.array(messageRecipientSchema).optional(),
  subject: z.string().max(500).optional(),
  body: z.string().max(5e4).optional(),
  bodyFormat: z.enum(["text", "markdown"]).optional(),
  priority: z.enum(["low", "normal", "high", "urgent"]).optional(),
  objects: z.array(messageObjectSchema).optional(),
  attachmentIds: z.array(z.string().uuid()).optional(),
  actionData: messageActionDataSchema.optional(),
  sendViaEmail: z.boolean().optional(),
  isDraft: z.literal(false).optional()
}).superRefine((value, ctx) => {
  if (value.recipients) {
    const duplicateRecipientIds = collectDuplicateRecipientIds(value.recipients);
    if (duplicateRecipientIds.length > 0) {
      ctx.addIssue({
        code: z.ZodIssueCode.custom,
        path: ["recipients"],
        message: "recipient user ids must be unique"
      });
    }
  }
  validateDefaultWithObjectsPayload(value, ctx);
});
const listMessagesSchema = z.object({
  folder: z.enum(["inbox", "sent", "drafts", "archived", "all"]).optional().default("inbox"),
  status: z.enum(["unread", "read", "archived"]).optional(),
  type: z.string().optional(),
  visibility: z.enum(["public", "internal"]).optional(),
  sourceEntityType: z.string().optional(),
  sourceEntityId: z.string().uuid().optional(),
  externalEmail: z.string().email().optional(),
  hasObjects: z.string().transform(parseBooleanFlag).optional(),
  hasAttachments: z.string().transform(parseBooleanFlag).optional(),
  hasActions: z.string().transform(parseBooleanFlag).optional(),
  senderId: z.string().uuid().optional(),
  search: z.string().max(200).optional(),
  since: z.string().datetime().optional(),
  page: z.coerce.number().int().min(1).optional().default(1),
  pageSize: z.coerce.number().int().min(1).max(100).optional().default(20)
});
const forwardMessageSchema = z.object({
  recipients: z.array(messageRecipientSchema).min(1).max(100),
  body: z.string().max(5e4).optional(),
  additionalBody: z.string().max(1e4).optional(),
  includeAttachments: z.boolean().optional().default(true),
  sendViaEmail: z.boolean().optional().default(false)
}).superRefine((value, ctx) => {
  const duplicateRecipientIds = collectDuplicateRecipientIds(value.recipients);
  if (duplicateRecipientIds.length > 0) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      path: ["recipients"],
      message: "recipient user ids must be unique"
    });
  }
});
const replyMessageSchema = z.object({
  body: z.string().min(1).max(5e4),
  bodyFormat: z.enum(["text", "markdown"]).optional().default("text"),
  recipients: z.array(messageRecipientSchema).max(100).optional(),
  attachmentIds: z.array(z.string().uuid()).optional(),
  attachmentRecordId: z.string().min(1).max(255).optional(),
  replyAll: z.boolean().optional().default(false),
  sendViaEmail: z.boolean().optional().default(false)
}).superRefine((value, ctx) => {
  if (!value.recipients) return;
  const duplicateRecipientIds = collectDuplicateRecipientIds(value.recipients);
  if (duplicateRecipientIds.length > 0) {
    ctx.addIssue({
      code: z.ZodIssueCode.custom,
      path: ["recipients"],
      message: "recipient user ids must be unique"
    });
  }
});
const executeActionSchema = z.object({
  messageId: z.string().uuid(),
  actionId: z.string().min(1),
  payload: z.record(z.string(), z.unknown()).optional()
});
const confirmMessageSchema = z.object({
  messageId: z.string().uuid(),
  tenantId: z.string().uuid().optional(),
  organizationId: z.string().uuid().nullable().optional(),
  confirmed: z.boolean().optional().default(true)
});
const messageObjectTypesQuerySchema = z.object({
  messageType: z.string().min(1)
});
const attachmentIdsPayloadSchema = z.object({
  attachmentIds: z.array(z.string().uuid()).min(1).max(100)
});
const unlinkAttachmentPayloadSchema = z.object({
  attachmentId: z.string().uuid().optional(),
  attachmentIds: z.array(z.string().uuid()).min(1).max(100).optional()
}).refine(
  (value) => Boolean(value.attachmentId || value.attachmentIds?.length),
  { message: "attachmentId or attachmentIds is required" }
);
export {
  attachmentIdsPayloadSchema,
  composeMessageSchema,
  confirmMessageSchema,
  executeActionSchema,
  forwardMessageSchema,
  listMessagesSchema,
  messageActionDataSchema,
  messageActionSchema,
  messageObjectSchema,
  messageObjectTypesQuerySchema,
  messageRecipientSchema,
  replyMessageSchema,
  unlinkAttachmentPayloadSchema,
  updateDraftSchema
};
//# sourceMappingURL=validators.js.map
