const Vue = require('vue');
const VueI18n = require('vue-i18n');
const renderer = require('vue-server-renderer').createRenderer();
Vue.use(VueI18n);

const fs = require('fs');
const yaml = require('js-yaml');
const juice = require('juice');
const path = require('path');
const config = require('./config');

class Component {
    constructor(name) {
        this.name = name;
    }

    get path() {
        return `./components/${this.name}`;
    }

    get template() {
        const templatePath = `${this.path}/${this.name}.html`;
        const fullPath = path.resolve(__dirname, templatePath);

        return fs.readFileSync(fullPath, 'utf8');
    }

    get locale() {
        if (!this._locale)
            this.getLocale();

        return this._locale;
    }

    getLocale() {
        const mergedLocale = {messages: {}};
        const localePath = path.resolve(__dirname, `${this.path}/locale`);

        if (!fs.existsSync(localePath))
            return mergedLocale;

        const localeDir = fs.readdirSync(localePath);
        localeDir.forEach(locale => {
            const fullPath = path.join(localePath, '/', locale);
            const yamlLocale = fs.readFileSync(fullPath, 'utf8');
            const jsonLocale = yaml.safeLoad(yamlLocale);
            const localeName = locale.replace('.yml', '');

            mergedLocale.messages[localeName] = jsonLocale;
        });

        this._locale = mergedLocale;
    }

    get stylesheet() {
        let mergedStyles = '';
        const stylePath = path.resolve(__dirname, `${this.path}/assets/css`);

        if (!fs.existsSync(stylePath))
            return mergedStyles;

        return require(`${stylePath}/import`);
    }

    get attachments() {
        const attachmentsPath = `${this.path}/attachments.json`;
        const fullPath = path.resolve(__dirname, attachmentsPath);

        if (!fs.existsSync(fullPath))
            return [];

        return require(fullPath);
    }

    build() {
        const fullPath = path.resolve(__dirname, this.path);
        if (!fs.existsSync(fullPath))
            throw new Error(`Sample "${this.name}" not found`);

        const component = require(`${this.path}/${this.name}`);
        component.i18n = this.locale;
        component.attachments = this.attachments;
        component.template = juice.inlineContent(this.template, this.stylesheet, {
            inlinePseudoElements: true
        });

        return component;
    }

    async render() {
        const component = this.build();
        const i18n = new VueI18n(config.i18n);
        const app = new Vue({
            i18n: i18n,
            render: h => h(component, {
                props: this.args
            })
        });

        return renderer.renderToString(app);
    }
}

module.exports = Component;