import nodemailer from 'nodemailer';
import { createSSRApp, h } from 'vue';
import { renderToString } from 'vue/server-renderer';

import base from '../components/mail/base.vue';
import Registration from '../components/mail/registration.vue';
import ResetPassword from '../components/mail/reset-password.vue';

const config = useRuntimeConfig();
const [domain, selector, dkim] = config.mail.dkim.split(":");

export const templates: Record<string, { component: any, subject: string }> = {
    "registration": { component: Registration, subject: 'Bienvenue sur d[any] 😎' },
    "reset-password": { component: ResetPassword, subject: 'Réinitialisation de votre mot de passe' },
};

import type Mail from 'nodemailer/lib/mailer';
interface MailPayload
{
    type: 'mail'
    to: string[]
    template: string
    data: Record<string, any>
}

const transport = nodemailer.createTransport({
    //@ts-ignore
    pool: true,
    host: config.mail.host,
    port: config.mail.port,
    secure: true,
    auth: {
        user: config.mail.user,
        pass: config.mail.passwd,
    },
    requireTLS: true,
    dkim: {
        domainName: domain,
        keySelector: selector,
        privateKey: dkim,
    },
});

export default defineTask({
    meta: {
        name: 'mail',
        description: 'Send email',
    },
    async run(e) {
        try {
            if(e.payload.type !== 'mail')
            {
                throw new Error(`Données inconnues`);
            }

            const payload = e.payload as MailPayload;
            const template = templates[payload.template];

            if(!template)
            {
                throw new Error(`Modèle de mail ${payload.template} inconnu`);
            }

            console.time('Generating HTML');
            const mail: Mail.Options = {
                from: 'd[any] - Ne pas répondre <no-reply@peaceultime.com>',
                to: payload.to,
                html: await render(template.component, payload.data),
                subject: template.subject,
                textEncoding: 'quoted-printable',
            };
            console.timeEnd('Generating HTML');

            if(mail.html === '')
                return { result: false, error: new Error("Invalid content") };

            console.time('Sending Mail');
            const status = await transport.sendMail(mail);
            console.timeEnd('Sending Mail');

            if(status.rejected.length > 0)
            {
                return { result: false, error: status.response, details: status.rejectedErrors };
            }
            
            return { result: true };
        }
        catch(e)
        {
            return { result: false, error: e };
        }
    },
})

async function render(component: any, data: Record<string, any>): Promise<string>
{
    const app = createSSRApp({
        render(){
            return h(base, null, { default: () => h(component, data, { default: () => null }) });
        }
    });

    const html = await renderToString(app);

    return (`<html><body><div>${html}</div></body></html>`);
}