```
import Mailchimp from "@mailchimp/mailchimp_transactional";
import {getUpcStatusVariable} from "./upcStatus.server";
import {updateClientEmailHistory} from "./clients.server";
import db from "./db.server";
import {
  processEmailTemplate,
  processEmailSubject,
} from "../functions/emailProcessing";

const mailchimp = Mailchimp(process.env.MAILCHIMP_API_KEY!);

const baseUrl = process.env.BASE_URL;

export async function sendEmail(message: Mailchimp.MessagesMessage) {
  return await mailchimp.messages.send({
    message,
  });
}

export async function sendDeliverableAlert(
  userName: string,
  description: string,
  clientName: string,
  notes: string
) {
  const message = {
    from_email: "alert@point-topic.com",
    from_name: "Research App",
    subject: `${clientName} Deliverable updated by ${userName}`,
    text: `There has been an update that you should check out. Go to the Research App to see more details. \n \nClient: ${clientName} \nDeliverable Description: ${description} \nUpdated by: ${userName} \nUpdated at ${new Date().toLocaleString()} \nNotes: ${notes}`,
    to: [
      {
        email: "peter.donaghey@point-topic.com",
      },
    ],
  };
  return await mailchimp.messages.send({
    message,
  });
}

export const emailClientDeliverables = async (
  clientIds: string[],
  deliverableIds: string[]
) => {
  const clients = await db.client.findMany({
    where: {
      id: {
        in: clientIds,
      },
    },
    select: {
      id: true,
      clientName: true,
      contactEmail: true,
      deliverables: {
        where: {
          id: {
            in: deliverableIds,
          },
        },
        select: {
          id: true,
          downloadLink: true,
        },
      },
    },
  });

  const emailTemplate = (
    ((await getUpcStatusVariable("emailTemplate")) || "") as {value: string}
  ).value;

  const emailSubject = (
    ((await getUpcStatusVariable("emailSubject")) || "") as {value: string}
  ).value;

  const upcMonthPretty = (
    ((await getUpcStatusVariable("upcMonthPretty")) || "") as {value: string}
  ).value;

  const upcMonthRaw = (
    ((await getUpcStatusVariable("upcMonth")) || "") as {value: string}
  ).value;

  const upcQuarter = (
    ((await getUpcStatusVariable("upcQuarter")) || "") as {value: string}
  ).value;

  const messages = clients.map((client) => {
    const downloadLinks = client.deliverables.map(
      (deliverable) => deliverable.downloadLink!
    );

    const emailData = {
      clientName: client.clientName,
      deliverableLinks: downloadLinks,
      upcMonth: upcMonthPretty!,
      upcMonthRaw: upcMonthRaw!,
      upcQuarter: upcQuarter!,
    };

    const message_text = processEmailTemplate(emailTemplate, emailData);
    const message_subject = processEmailSubject(emailSubject, emailData);

    const emails = client.contactEmail;
    const recipients = emails.map((email) => ({
      email,
    }));
    return {
      clientId: client.id,
      deliverableIds: deliverableIds.filter((id) =>
        client.deliverables.map((deliverable) => deliverable.id).includes(id)
      ),
      upcMonth: upcMonthPretty,
      message: {
        from_email: "oliver.johnson@point-topic.com",
        from_name: "Point Topic",
        subject: message_subject,
        html:
          message_text.replace(/\n/g, "<br>") +
          '<br><br><b>Point Topic</b><br><a href="https://www.point-topic.com">www.point-topic.com</a><br><br><p style="font-size: 10px; color: gray">This email was sent automatically. If you have any concerns or technical questions about the data, please contact oliver.johnson@point-topic.com by replying to this email.</p>',
        to: recipients,
      },
    };
  });

  for (const messageObj of messages) {
    const resArray = (await emailDeliverables(
      messageObj.message
    )) as Mailchimp.MessagesSendResponse[];

    const recipients = messageObj.message.to.map((to) => ({
      email: to.email,
      // "queued" means Mailchimp accepted the email and will send it - treat as successful
      sent: ["sent", "queued"].includes(
        resArray.find((res) => res.email === to.email)?.status || ""
      ),
      response: resArray.find((res) => res.email === to.email)?.status || "",
    }));

    updateClientEmailHistory(
      messageObj.clientId,
      messageObj.message.html || "",
      messageObj.upcMonth,
      recipients
    );
  }
};

export async function emailDeliverables(message: Mailchimp.MessagesMessage) {
  const res = await mailchimp.messages.send({
    message,
  });
  return res;
}

export async function sendPasswordResetEmail(
  userEmail: string,
  resetToken: string
) {
  const message = {
    from_email: "passwordreset@point-topic.com",
    to: [{email: userEmail}],
    subject: "Password Reset Request",
    text: `You have requested to reset your password. Please click on the link below to reset your password:\n\n${baseUrl}password?token=${resetToken}\n\nIf you did not request a password reset, please ignore this email.`,
  };

  return await sendEmail(message);
}

export async function sendWelcomeEmail(userEmail: string, resetToken: string) {
  const message = {
    from_email: "welcome@point-topic.com",
    to: [{email: userEmail}],
    subject: "Welcome to the Point Topic Research App",
    text: `Welcome to the Point Topic Research App! Please click on the link below to set your password and get started:\n\n${baseUrl}password?token=${resetToken}\n\nIf you do not know what this is about, please ignore this email.`,
  };

  return await sendEmail(message);
}

export async function sendEmailAlert(text: string) {
  const message = {
    from_email: "alert@point-topic.com",
    to: [{email: "peter.donaghey@point-topic.com"}],
    subject: "Research App Alert",
    text,
  };
  return await sendEmail(message);
}
```