import { z } from "zod";

const Recipient = z.object({
  name: z.string().optional(),
  email: z.string().email(),
});

export const MailMessageSchema = z.object({
  fromEmail: z.string().email().optional(),
  to: z.array(Recipient).min(1),
  cc: z.array(Recipient).optional(),
  bcc: z.array(Recipient).optional(),

  replyTo: z.array(Recipient).optional(),
  replyToList: z.array(Recipient).optional(),
  templateID: z.string().min(1),
  templateData: z.record(z.string(), z.unknown()).optional(),
  subject: z.string().optional(),
  attachments: z
    .array(
      z.object({
        content: z.string(),
        filename: z.string(),
        type: z.string(),
        disposition: z.string(),
      }),
    )
    .optional(),
});

export type MailMessage = z.infer<typeof MailMessageSchema>;

export type ParseResult =
  | { ok: true; message: MailMessage }
  | { ok: false; reason: string };


export function parseMessage(raw: Buffer): ParseResult {
  let json: unknown;
  try {
    json = JSON.parse(raw.toString());
  } catch (err) {
    return {
      ok: false,
      reason: `not JSON: ${err instanceof Error ? err.message : String(err)}`,
    };
  }

  const parsed = MailMessageSchema.safeParse(json);
  if (!parsed.success) {
    const issue = parsed.error.issues[0];
    return {
      ok: false,
      reason: issue
        ? `${issue.path.join(".") || "message"}: ${issue.message}`
        : "did not match the mail schema",
    };
  }

  return { ok: true, message: parsed.data };
}

export function describe(message: MailMessage): string {
  const domains = [
    ...new Set(message.to.map((entry) => entry.email.split("@")[1] ?? "?")),
  ];
  return `${message.templateID} -> ${message.to.length} recipient(s) @${domains.join(",")}`;
}
