import { render } from "@react-email/render";
import { TRPCError } from "@trpc/server";
import AvvisoInterruzione from "emails/avviso-interruzione";
import ContattoAdminEmail from "emails/contatto";
import ContattoAnnuncioEmail from "emails/contatto_annuncio";
import EmailContattoInteressato from "emails/email-interessato";
import Generic from "emails/gereric-email";
import Interruzione from "emails/interruzione";
import Invito from "emails/invito";
import PagamentoConferma from "emails/pagamento-conferma";
import PagamentoErrore from "emails/pagamento-errore";
import PagamentoRicezione from "emails/pagamento-ricezione";
import PwResetLink from "emails/pw-reset-link";
import Recesso from "emails/recesso";
import RegistrazioneAvvenuta from "emails/registrazione-avvenuta";
import EmailSchedaContatto from "emails/scheda-annuncio";
import ServizioAttivato from "emails/servizio-attivato";
import VerificaEmail from "emails/VerificaEmail";
import { createTransport } from "nodemailer";
import type { Options } from "nodemailer/lib/mailer";
import { htmlToText } from "nodemailer-html-to-text";
import type { JSX } from "react";
import { env } from "~/env";
import type { UsersId } from "~/schemas/public/Users";
import { GetFlagValueHandler } from "~/server/controllers/flags.controller";
import { db } from "~/server/db";
import { storeEmail } from "~/server/services/email.service";

import {
	type MailsTemplates,
	Templates,
} from "~/server/services/mail-templates";

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

	const message: Options = {
		from: `"InfoAlloggi" <${env.ARUBA_USER}>`,
		...options,
	};
	smtpTransport.sendMail(message, (err, info) => {
		if (err) {
			throw new Error(err.message);
		}
		return info;
	});
};

export type NewMailProps = {
	template?: MailsTemplates;
	userId?: UsersId;
	mail: Options;
};

export const genMail = async ({ ...mail }: MailsTemplates) => {
	let mailComponent: JSX.Element | null = null;
	if (!Templates[mail.mailType]) {
		return { html: "", title: "Email non valido/modello obsoleto" };
	}
	const title = Templates[mail.mailType].title;
	switch (mail.mailType) {
		case "contattoAdminEmail":
			mailComponent = ContattoAdminEmail({
				...mail.props,
			});
			break;
		case "contattoAnnuncioEmail":
			mailComponent = ContattoAnnuncioEmail({
				...mail.props,
			});
			break;
		case "emailContattoInteressato":
			mailComponent = EmailContattoInteressato({
				...mail.props,
			});
			break;
		case "pagamentoConferma":
			mailComponent = PagamentoConferma();
			break;
		case "pagamentoErrore":
			mailComponent = PagamentoErrore();
			break;
		case "pagamentoRicezione":
			mailComponent = PagamentoRicezione();
			break;
		case "pwResetLink":
			mailComponent = PwResetLink({
				...mail.props,
			});
			break;
		case "recesso":
			mailComponent = Recesso();
			break;
		case "registrazioneAvvenuta":
			mailComponent = RegistrazioneAvvenuta();
			break;
		case "verificaEmail":
			mailComponent = VerificaEmail({
				...mail.props,
			});
			break;
		case "generic":
			mailComponent = Generic({
				...mail.props,
			});
			break;
		case "emailSchedaContatto":
			mailComponent = EmailSchedaContatto({
				...mail.props,
			});
			break;
		case "invito":
			mailComponent = Invito({
				...mail.props,
			});
			break;
		case "servizioAttivato":
			mailComponent = ServizioAttivato();
			break;
		case "avvisoInterruzione":
			mailComponent = AvvisoInterruzione();
			break;
		case "interruzione":
			mailComponent = Interruzione();
			break;
		default:
			console.error(`Tipo di email non valido: ${mail satisfies never}`);
			return { html: "", title: "Email non valido/modello obsoleto" };
	}

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

export const NewMail = async ({ template, userId, mail }: NewMailProps) => {
	const emailFlag = await GetFlagValueHandler({
		db: db,
		id: "EMAIL_ENABLED",
	});
	if (emailFlag) {
		try {
			if (template) {
				const { html } = await genMail({ ...template });
				if (!html || html.trim() === "") {
					throw new Error(
						`Il template per il tipo ${template.mailType} è obsoleto e non genera più l'html. Email non inviata.`,
					);
				}
				await mailer({
					html,
					...mail,
				});
			} else {
				await mailer({
					...mail,
				});
			}
		} catch (e) {
			throw new TRPCError({
				code: "INTERNAL_SERVER_ERROR",
				message: `Errore nell'invio dell'email: ${(e as Error).message}`,
			});
		}
	} else {
		console.warn(
			`Email sending is disabled to:${mail.to} subj:${mail.subject} msgType: ${template?.mailType}`,
		);
	}

	if (userId && template) {
		// Store the email in the database if userId is provided
		await storeEmail({ data: template, userId });
	}
};
