import { render } from "@react-email/render";
import { TRPCError } from "@trpc/server";
import ContattoAdminEmail, {
  type ContattoAdmin_NewMail,
} from "emails/contatto";
import EmailContattoInteressato, {
  type ContattoInteressato_NewMail,
} from "emails/email-interessato";
import type { PagamentoConferma_NewMail } from "emails/pagamento-conferma";
import PagamentoConferma from "emails/pagamento-conferma";
import type { PagamentoErrore_NewMail } from "emails/pagamento-errore";
import PagamentoErrore from "emails/pagamento-errore";
import type { PagamentoRicezione_NewMail } from "emails/pagamento-ricezione";
import PagamentoRicezione from "emails/pagamento-ricezione";
import type { PwResetLink_NewMail } from "emails/pw-reset-link";
import PwResetLink from "emails/pw-reset-link";
import type { Recesso_NewMail } from "emails/recesso";
import Recesso from "emails/recesso";
import type { RegistrazioneAvvenuta_NewMail } from "emails/registrazione-avvenuta";
import RegistrazioneAvvenuta from "emails/registrazione-avvenuta";
import { createTransport } from "nodemailer";
import { htmlToText } from "nodemailer-html-to-text";
import { env } from "~/env.mjs";
import type { JSX } from "react";
import VerificaEmail, {
  type VerificaEmail_NewMail,
} from "emails/VerificaEmail";
import OnboardingServizio, {
  type OnboardingServizio_NewMail,
} from "emails/onboarding-servizio";
import type { ContattoAnnuncio_NewMail } from "emails/contatto_annuncio";
import ContattoAnnuncioEmail from "emails/contatto_annuncio";
import type { UsersId } from "~/schemas/public/Users";
import { StoreEmail } from "~/server/services/email.service";
import type { Generic_NewMail } from "emails/gereric-email";
import Generic from "emails/gereric-email";
import { GetFlagValueHandler } from "~/server/controllers/flags.controller";
import { db } from "~/server/db";

type MailerProps = {
  to: string;
  subject: string;
  html: string;
};
const mailer = async ({ to, subject, html }: MailerProps) => {
  const smtpTransport = createTransport({
    host: "smtps.aruba.it",
    logger: false,
    debug: false,
    secure: true,
    port: 465,
    auth: {
      user: env.ARUBA_USER,
      pass: env.ARUBA_PASS,
    },
    tls: {
      minVersion: "TLSv1",
      ciphers: "HIGH:MEDIUM:!aNULL:!eNULL:@STRENGTH:!DH:!kEDH",
    },
  });
  smtpTransport.use("compile", htmlToText());

  const message = {
    from: env.ARUBA_USER,
    to: to,
    subject: subject,
    html: html,
  };
  smtpTransport.sendMail(message, (err, info) => {
    if (err) {
      throw new Error(err.message);
    }
    return info;
  });
};

type base_NewMailProps = {
  userId?: UsersId;
  to: string;
  subject: string;
};

export type NewMailProps = base_NewMailProps & MailsTemplates;
export type MailsTemplates =
  | ContattoAdmin_NewMail
  | ContattoAnnuncio_NewMail
  | ContattoInteressato_NewMail
  | PagamentoConferma_NewMail
  | PagamentoErrore_NewMail
  | PagamentoRicezione_NewMail
  | PwResetLink_NewMail
  | Recesso_NewMail
  | RegistrazioneAvvenuta_NewMail
  | VerificaEmail_NewMail
  | OnboardingServizio_NewMail
  | Generic_NewMail;

export const genMail = async ({ ...mail }: MailsTemplates) => {
  let mailComponent: JSX.Element | null = null;
  let title = "";

  switch (mail.mailType) {
    case "contattoAdminEmail":
      mailComponent = ContattoAdminEmail({
        ...mail.props,
      });
      title = "Contatto amministratore";
      break;
    case "contattoAnnuncioEmail":
      mailComponent = ContattoAnnuncioEmail({
        ...mail.props,
      });
      title = "Contatto annuncio";
      break;

    case "emailContattoInteressato":
      mailComponent = EmailContattoInteressato({
        ...mail.props,
      });
      title = "Contatto interessato";
      break;

    case "pagamentoConferma":
      mailComponent = PagamentoConferma({
        ...mail.props,
      });
      title = "Conferma pagamento";
      break;

    case "pagamentoErrore":
      mailComponent = PagamentoErrore();
      title = "Errore pagamento";
      break;

    case "pagamentoRicezione":
      mailComponent = PagamentoRicezione();
      title = "Ricezione pagamento";
      break;

    case "pwResetLink":
      mailComponent = PwResetLink({
        ...mail.props,
      });
      title = "Reset password";
      break;

    case "recesso":
      mailComponent = Recesso();
      title = "Recesso";
      break;

    case "registrazioneAvvenuta":
      mailComponent = RegistrazioneAvvenuta();
      title = "Registrazione avvenuta";
      break;

    case "verificaEmail":
      mailComponent = VerificaEmail({
        ...mail.props,
      });
      title = "Verifica email";
      break;

    case "onboardingServizio":
      mailComponent = OnboardingServizio({
        ...mail.props,
      });
      title = "Onboarding Servizio";
      break;
    case "generic":
      mailComponent = Generic({
        ...mail.props,
      });
      title = mail.props.title || "Email Generica";
      break;
  }
  if (mailComponent === null) {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Errore nella creazione dell'email",
    });
  }

  return { html: await render(mailComponent), title };
};

export const NewMail = async ({
  userId,
  to,
  subject,
  ...mail
}: NewMailProps) => {
  const emailFlag = await GetFlagValueHandler({
    db: db,
    id: "EMAIL_OFF",
  });
  if (emailFlag === "true") {
    console.warn("Email sending is disabled");
    return { success: true, message: "Email sending is disabled" };
  }
  try {
    const { html } = await genMail({ ...mail });
    await mailer({
      to: to,
      subject: subject,
      html,
    });

    if (userId) {
      // Store the email in the database if userId is provided
      await StoreEmail({ userId, data: mail });
    }
  } catch (e) {
    throw new TRPCError({
      code: "INTERNAL_SERVER_ERROR",
      message: "Errore nell'invio dell'email: " + (e as Error).message,
    });
  }
};
