const Vue = require('vue');
const VueI18n = require('vue-i18n');
const renderer = require('vue-server-renderer').createRenderer();
const fs = require('fs-extra');
const pdf = require('phantom-html2pdf');
const juice = require('juice');

Vue.use(VueI18n);

if (!process.env.OPENSSL_CONF)
    process.env.OPENSSL_CONF = '/etc/ssl/';

module.exports = {

    path: `${appPath}/reports`,

    /**
     * Renders a report component
     *
     * @param {String} name - Report name
     * @param {Object} ctx - Request context
     */
    async render(name, ctx) {
        const component = require(`${this.path}/${name}`);

        await this.preFetch(component, ctx);

        const i18n = new VueI18n({
            locale: 'es',
        });
        const app = new Vue({
            i18n,
            render: h => h(component),
        });

        return renderer.renderToString(app);
    },

    /**
     * Prefetch all component data from asyncData method
     *
     * @param {Object} component - Component object
     * @param {Object} ctx - Request context
     */
    async preFetch(component, ctx) {
        let data = {};

        await this.attachAssets(component);

        if (component.hasOwnProperty('data'))
            data = component.data();

        if (component.hasOwnProperty('asyncData')) {
            const fetch = await component.asyncData(ctx, ctx.body);
            const mergedData = {...data, ...fetch};

            component.data = function data() {
                return mergedData;
            };
        }

        if (component.components) {
            const components = component.components;
            const promises = [];

            Object.keys(components).forEach(component => {
                promises.push(this.preFetch(components[component], ctx));
            });

            return Promise.all(promises);
        }
    },

    async attachAssets(component) {
        const localePath = `${this.path}/${component.name}/locale.js`;
        const templatePath = `${this.path}/${component.name}/index.html`;
        const stylePath = `${this.path}/${component.name}/assets/css/style.css`;

        const template = await fs.readFile(templatePath, 'utf8');
        const css = await fs.readFile(stylePath, 'utf8');

        component.i18n = require(localePath);
        component.template = juice.inlineContent(template, css);
    },

    async toPdf(name, ctx) {
        const options = {
            html: await this.render(name, ctx),
        };
        const result = await pdf.convert(options);
        const stream = await result.toStream();

        return stream;
    },
};