import "server-only";

import { EventEmitter } from "events";

export type MailboxAutoSendCompletedEvent = {
  at: string;
  deliveryCount: number;
  mailbox: string;
  recipientEmail: string;
  subject: string;
};

type MailboxAutoSendNotificationListener = (event: MailboxAutoSendCompletedEvent) => void;

class MailboxAutoSendNotificationManager {
  private emitters = new Map<string, EventEmitter>();

  subscribe(email: string, listener: MailboxAutoSendNotificationListener) {
    const key = email.trim().toLowerCase();
    if (!key) {
      return () => {};
    }

    let emitter = this.emitters.get(key);
    if (!emitter) {
      emitter = new EventEmitter();
      emitter.setMaxListeners(0);
      this.emitters.set(key, emitter);
    }

    emitter.on("auto-send-completed", listener);

    return () => {
      emitter.off("auto-send-completed", listener);
      if (emitter.listenerCount("auto-send-completed") === 0) {
        this.emitters.delete(key);
      }
    };
  }

  publish(ownerEmail: string, event: MailboxAutoSendCompletedEvent) {
    const key = ownerEmail.trim().toLowerCase();
    if (!key) {
      return;
    }

    this.emitters.get(key)?.emit("auto-send-completed", event);
  }
}

type MailboxNotificationGlobal = typeof globalThis & {
  __officialMailAutoSendNotificationManager?: MailboxAutoSendNotificationManager;
};

function getMailboxAutoSendNotificationManager() {
  const globalScope = globalThis as MailboxNotificationGlobal;
  if (!globalScope.__officialMailAutoSendNotificationManager) {
    globalScope.__officialMailAutoSendNotificationManager =
      new MailboxAutoSendNotificationManager();
  }
  return globalScope.__officialMailAutoSendNotificationManager;
}

export function subscribeMailboxAutoSendNotificationsByOwnerEmail(
  ownerEmail: string,
  listener: MailboxAutoSendNotificationListener,
) {
  return getMailboxAutoSendNotificationManager().subscribe(ownerEmail, listener);
}

export function publishMailboxAutoSendCompleted(input: {
  deliveryCount: number;
  mailbox: string;
  ownerEmail: string;
  recipientEmail: string;
  subject: string;
}) {
  getMailboxAutoSendNotificationManager().publish(input.ownerEmail, {
    at: new Date().toISOString(),
    deliveryCount: Math.max(1, Math.round(input.deliveryCount)),
    mailbox: input.mailbox,
    recipientEmail: input.recipientEmail,
    subject: input.subject,
  });
}
