import { Injectable, InternalServerErrorException, Logger } from "@nestjs/common"; import { MailerService } from "@nestjs-modules/mailer"; import { SentMessageInfo } from "nodemailer"; import { dateFormat, numberFormat } from "./international.utils"; import { EmailMessage } from "../../../common/enums/message.enum"; import { IAnnouncementNotificationData, IInvoiceNotificationData, IPaymentNotificationData, ITicketNotificationData, IWalletNotificationData, } from "../../notifications/interfaces/ISendNotificationData"; import { IBaseNotificationData } from "../../notifications/interfaces/ISendNotificationData"; @Injectable() export class EmailService { private readonly logger = new Logger(EmailService.name); constructor(private readonly mailerService: MailerService) { } async sendVerificationEmail(to: string, link: string, fullName: string): Promise { try { const emailInfo = await this.mailerService.sendMail({ to: to, subject: EmailMessage.EMAIL_VERIFICATION, template: "email-verify", context: { title: EmailMessage.EMAIL_VERIFICATION, link, fullName, }, }); console.log(emailInfo); return emailInfo; } catch (error) { this.logger.error("Email sending failed:", error); throw new InternalServerErrorException(EmailMessage.EMAIL_SENDING_FAILED); } } async sendLoginEmail(data: IBaseNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.LOGIN, template: "login", context: { date: dateFormat(new Date()), }, }); } catch (error) { this.logger.error("error in sending login email", error); } } async sendInvoiceEmail(data: IInvoiceNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.INVOICE, template: "invoice", context: { price: numberFormat(data.price), createDate: dateFormat(data.createDate), dueDate: dateFormat(data.dueDate), invoiceId: data.invoiceId, }, }); } catch (error) { this.logger.error("error in sending invoice email", error); } } async sendWalletEmail(data: IWalletNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.WALLET, template: "wallet", context: { amount: numberFormat(data.amount), balance: numberFormat(data.balance), date: dateFormat(data.date), reason: data.reason, }, }); } catch (error) { this.logger.error("error in sending wallet email", error); } } async sendTicketEmail(data: ITicketNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.TICKET, template: "ticket", context: { ticketId: data.ticketId, subject: data.subject, date: data.date ? dateFormat(data.date) : dateFormat(new Date()), user: data.user, }, }); } catch (error) { this.logger.error("error in sending ticket email", error); } } async sendAnnouncementEmail(data: IAnnouncementNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.ANNOUNCEMENT, template: "announcement", context: { title: data.title, description: data.description, date: dateFormat(data.date), }, }); } catch (error) { this.logger.error("error in sending announcement email", error); } } async sendPaymentReminderEmail(data: IPaymentNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.PAYMENT_REMINDER, template: "payment-reminder", context: { amount: numberFormat(data.amount), }, }); } catch (error) { this.logger.error("error in sending payment reminder email", error); } } async sendPaymentCancellationEmail(data: IPaymentNotificationData) { try { await this.mailerService.sendMail({ to: data.userEmail, subject: EmailMessage.PAYMENT_CANCELLATION, template: "payment-cancellation", context: { amount: numberFormat(data.amount), }, }); } catch (error) { this.logger.error("error in sending payment cancellation email", error); } } async sendAdminNotificationEmail(data: { userEmail: string; title: string; message: string; fullName?: string }) { const emailData = { to: data.userEmail, subject: data.title, template: "admin-notification", context: { title: data.title, message: data.message, fullName: data.fullName, }, }; try { await this.mailerService.sendMail(emailData); } catch (error) { this.logger.error("error in sending admin notification email", error); // throw new InternalServerErrorException("error in sending admin notification email"); } } async sendOtpEmail({ userEmail, otp }: { userEmail: string, otp: string }) { try { await this.mailerService.sendMail({ to: userEmail, subject: EmailMessage.VERIFY_OTP, template: "otp", context: { otp, }, }); } catch (error) { this.logger.error("error in sending otp email", error); } } }