import { SignJWT, jwtVerify } from "jose";
import { z } from "zod";
import { deriveKey } from "../security/keys.js";

const MessageReferenceSchema = z.object({
  mailbox_id: z.string().min(1).max(64),
  folder: z.string().min(1).max(512),
  uid: z.number().int().positive(),
  uid_validity: z.string().regex(/^\d+$/),
});

export type MessageReference = z.infer<typeof MessageReferenceSchema>;

export class MessageReferenceCodec {
  private readonly key: Uint8Array;

  constructor(masterSecret: Uint8Array) {
    this.key = deriveKey(masterSecret, "mail-message-reference");
  }

  async encode(reference: MessageReference): Promise<string> {
    const parsed = MessageReferenceSchema.parse(reference);
    return new SignJWT(parsed)
      .setProtectedHeader({ alg: "HS256", typ: "mail-ref+jwt" })
      .setIssuer("cpanel-mail-mcp")
      .setAudience("mail-message-ref")
      .setIssuedAt()
      .sign(this.key);
  }

  async decode(token: string): Promise<MessageReference> {
    try {
      const result = await jwtVerify(token, this.key, {
        issuer: "cpanel-mail-mcp",
        audience: "mail-message-ref",
        algorithms: ["HS256"],
      });
      return MessageReferenceSchema.parse(result.payload);
    } catch {
      throw new Error("Invalid message_ref");
    }
  }
}
