import nodemailer, { type Transporter } from "nodemailer";

interface SendMailOptions {
    to: string | string[];
    subject: string;
    html: string;
    text?: string;
}

class MailService {
    private transporter: Transporter | null = null;
    private from: string = "";
    private fromName: string = "";

    private getTransporter(): Transporter {
        if (this.transporter) return this.transporter;

        const {
            MAIL_HOST,
            MAIL_PORT,
            MAIL_ENCRYPTION,
            MAIL_USERNAME,
            MAIL_PASSWORD,
            MAIL_FROM_ADDRESS,
            MAIL_FROM_NAME,
        } = process.env;

        if (!MAIL_HOST) throw new Error("MAIL_HOST is missing.");
        if (!MAIL_PORT) throw new Error("MAIL_PORT is missing.");
        if (!MAIL_USERNAME) throw new Error("MAIL_USERNAME is missing.");
        if (!MAIL_PASSWORD) throw new Error("MAIL_PASSWORD is missing.");
        if (!MAIL_FROM_ADDRESS) throw new Error("MAIL_FROM_ADDRESS is missing.");

        this.from = MAIL_FROM_ADDRESS;
        this.fromName = MAIL_FROM_NAME || "My App";

        const port = Number(MAIL_PORT);
        const secure =
            MAIL_ENCRYPTION?.toLowerCase() === "ssl" || port === 465;

        this.transporter = nodemailer.createTransport({
            host: MAIL_HOST,
            port,
            secure,
            auth: {
                user: MAIL_USERNAME,
                pass: MAIL_PASSWORD,
            },
        });

        return this.transporter;
    }

    async verify(): Promise<void> {
        await this.getTransporter().verify();
        console.log("✅ SMTP server connected.");
    }

    async send({
        to,
        subject,
        html,
        text,
    }: SendMailOptions) {
        if (!to) {
            return {
                success: false,
                error: "Recipient email is required.",
            };
        }

        if (!subject.trim()) {
            return {
                success: false,
                error: "Subject is required.",
            };
        }

        if (!html.trim()) {
            return {
                success: false,
                error: "Email body is required.",
            };
        }

        try {
            const transporter = this.getTransporter();
            const info = await transporter.sendMail({
                from: `"${this.fromName}" <${this.from}>`,
                to,
                subject,
                html,
                text,
            });

            return {
                success: true,
                messageId: info.messageId,
                accepted: info.accepted,
                rejected: info.rejected,
            };
        } catch (error: any) {
            console.error("Mail sending failed:", error);

            let errorMessage = "Failed to send email.";
            if (error?.code === "EENVELOPE" || error?.responseCode === 550) {
                errorMessage = `Recipient email address was rejected by the mail server (${Array.isArray(to) ? to.join(", ") : to}). Please check that the email address exists.`;
            } else if (error instanceof Error) {
                errorMessage = error.message;
            }

            return {
                success: false,
                error: errorMessage,
            };
        }
    }
}

export default new MailService();