import type { Transporter } from "nodemailer";
import type Mail from "nodemailer/lib/mailer";
import type { MailOption } from "../types";
import type { AccountVerificationProps } from "./account-verification";
import { sendAccountVerificationMail } from "./account-verification";
import type { FailedLoginAttemptProps } from "./failed-login-attempt";
import { sendFailedLoginAttemptMail } from "./failed-login-attempt";
import type { NewsletterSubscriptionProps } from "./newsletter-subscription";
import { sendNewsletterConfirmationEmail } from "./newsletter-subscription";
import type { ResetPasswordProps } from "./reset-password";
import { sendResetPasswordMail } from "./reset-password";
import type { WeddingBrochureProps } from "./send-wedding-brochure";
import { sendWeddingBrochure } from "./send-wedding-brochure";
import type { ShareCommunityPostcardReceiverProps } from "./share-community-postcard-receiver";
import { sendSharePostcardReceiverMail } from "./share-community-postcard-receiver";
import type { ShareCommunityPostcardSenderProps } from "./share-community-postcard-sender";
import { sendSharePostcardSenderMail } from "./share-community-postcard-sender";
import type { UploadMomentConfirmationProps } from "./upload-moment-confirmation";
import { sendUploadMomentSubmissionMail } from "./upload-moment-confirmation";
import type { UploadPostcardConfirmationProps } from "./upload-postcard-confirmation";
import { sendUploadPostcardSubmissionMail } from "./upload-postcard-confirmation";

export enum Template {
  AccountVerification = "AccountVerification",
  ResetPassword = "ResetPassword",
  NewsletterSubscription = "NewsletterSubscription",
  UploadPostcardConfirmation = "UploadPostcardConfirmation",
  ShareCommunityPostcardReceiver = "ShareCommunityPostcardReceiver",
  ShareCommunityPostcardSender = "ShareCommunityPostcardSender",
  UploadMomentConfirmation = "UploadMomentConfirmation",
  WeddingBrochure = "WeddingBrochure",
  FailedLoginAttempt = "FailedLoginAttempt",
}

interface TemplatePropsMap {
  [Template.AccountVerification]: AccountVerificationProps;
  [Template.ResetPassword]: ResetPasswordProps;
  [Template.NewsletterSubscription]: NewsletterSubscriptionProps;
  [Template.UploadPostcardConfirmation]: UploadPostcardConfirmationProps;
  [Template.ShareCommunityPostcardReceiver]: ShareCommunityPostcardReceiverProps;
  [Template.ShareCommunityPostcardSender]: ShareCommunityPostcardSenderProps;
  [Template.UploadMomentConfirmation]: UploadMomentConfirmationProps;
  [Template.WeddingBrochure]: WeddingBrochureProps;
  [Template.FailedLoginAttempt]: FailedLoginAttemptProps;
}

type TemplateFunction<T extends Template> = (
  props: TemplatePropsMap[T],
  addressOptions: MailOption,
) => Promise<Mail.Options>;

const templates: {
  [T in Template]: TemplateFunction<T>;
} = {
  [Template.AccountVerification]: sendAccountVerificationMail,
  [Template.ResetPassword]: sendResetPasswordMail,
  [Template.NewsletterSubscription]: sendNewsletterConfirmationEmail,
  [Template.UploadPostcardConfirmation]: sendUploadPostcardSubmissionMail,
  [Template.ShareCommunityPostcardReceiver]: sendSharePostcardReceiverMail,
  [Template.ShareCommunityPostcardSender]: sendSharePostcardSenderMail,
  [Template.UploadMomentConfirmation]: sendUploadMomentSubmissionMail,
  [Template.WeddingBrochure]: sendWeddingBrochure,
  [Template.FailedLoginAttempt]: sendFailedLoginAttemptMail,
};

export function useMailTemplate<T extends Template>(
  templateName: T,
  transporter: Transporter,
) {
  async function sendMail(props: TemplatePropsMap[T], opts: MailOption) {
    try {
      const mailOptions = await templates[templateName](props, opts);
      await transporter.sendMail(mailOptions);
    } catch (error) {
      console.error(`Failed to send ${templateName} email:`, error);
      throw error;
    }
  }
  return sendMail;
}
