const path = require('path');
const webpack = require('webpack');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const MiniHtmlWebpackPlugin = require('mini-html-webpack-plugin');
const MiniHtmlWebpackTemplate = require('@vxna/mini-html-webpack-template');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const merge = require('webpack-merge');
const forEach = require('lodash/forEach');
const isFunction = require('lodash/isFunction');
const mergeWebpackConfig = require('./utils/mergeWebpackConfig');
const StyleguidistOptionsPlugin = require('./utils/StyleguidistOptionsPlugin');
const getWebpackVersion = require('./utils/getWebpackVersion');

const RENDERER_REGEXP = /Renderer$/;

const sourceDir = path.resolve(__dirname, '../lib');

module.exports = function(config, env) {
	process.env.NODE_ENV = process.env.NODE_ENV || env;

	const isProd = env === 'production';

	const template = isFunction(config.template) ? config.template : MiniHtmlWebpackTemplate;
	const templateContext = isFunction(config.template) ? {} : config.template;
	const htmlPluginOptions = {
		context: Object.assign({}, templateContext, {
			title: config.title,
			container: 'rsg-root',
			trimWhitespace: true,
		}),
		template,
	};

	let webpackConfig = {
		entry: config.require.concat([path.resolve(sourceDir, 'index')]),
		output: {
			path: config.styleguideDir,
			filename: 'build/[name].bundle.js',
			chunkFilename: 'build/[name].js',
		},
		resolve: {
			extensions: ['.js', '.jsx', '.json'],
			alias: {
				'rsg-codemirror-theme.css': `codemirror/theme/${config.editorConfig.theme}.${'css'}`,
				vue$: 'vue/dist/vue.esm.js',
				'@': path.resolve(__dirname, '../src'),
			},
		},
		plugins: [
			new StyleguidistOptionsPlugin(config),
			new MiniHtmlWebpackPlugin(htmlPluginOptions),
			new webpack.DefinePlugin({
				'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
				'process.env.STYLEGUIDIST_ENV': JSON.stringify(env),
			}),
		],
		performance: {
			hints: false,
		},
	};

	const uglifier = new UglifyJSPlugin({
		parallel: true,
		cache: true,
		uglifyOptions: {
			ie8: false,
			ecma: 5,
			compress: {
				keep_fnames: true,
				warnings: false,
			},
			mangle: {
				keep_fnames: true,
			},
		},
	});

	if (getWebpackVersion() >= 4) {
		webpackConfig.mode = env;
		webpackConfig.optimization = {
			minimizer: [uglifier],
		};
	} else {
		webpackConfig.plugins.unshift(uglifier);
	}

	if (isProd) {
		webpackConfig = merge(webpackConfig, {
			output: {
				filename: 'build/bundle.[chunkhash:8].js',
				chunkFilename: 'build/[name].[chunkhash:8].js',
				publicPath: config.styleguidePublicPath,
			},
			plugins: [
				new CleanWebpackPlugin(['build'], {
					root: config.styleguideDir,
					verbose: config.verbose === true,
				}),
				new CopyWebpackPlugin(
					config.assetsDir
						? [
								{
									from: config.assetsDir,
								},
						  ]
						: []
				),
			],
		});
	} else {
		webpackConfig = merge(webpackConfig, {
			entry: [require.resolve('react-dev-utils/webpackHotDevClient')],
			plugins: [new webpack.HotModuleReplacementPlugin()],
		});
	}

	if (config.webpackConfig) {
		webpackConfig = mergeWebpackConfig(webpackConfig, config.webpackConfig, env);
	}

	// Custom style guide components
	if (config.styleguideComponents) {
		forEach(config.styleguideComponents, (filepath, name) => {
			const fullName = name.match(RENDERER_REGEXP)
				? `${name.replace(RENDERER_REGEXP, '')}/${name}`
				: name;
			webpackConfig.resolve.alias[`rsg-components/${fullName}`] = filepath;
		});
	}

	// Add components folder alias at the end so users can override our components to customize the style guide
	// (their aliases should be before this one)
	webpackConfig.resolve.alias['rsg-components'] = path.resolve(sourceDir, 'rsg-components');

	if (config.dangerouslyUpdateWebpackConfig) {
		webpackConfig = config.dangerouslyUpdateWebpackConfig(webpackConfig, env);
	}

	return webpackConfig;
};

@@ -1667,41 +1667,8 @@
 %7D%60,%0A
-%09%09%09%09vue$: 'vue/dist/vue.esm.js',%0A
 %09%09%09%09
@@ -1722,277 +1722,8 @@
 %09%7D,%0A
-%09%09plugins: %5B%0A%09%09%09new StyleguidistOptionsPlugin(config),%0A%09%09%09new MiniHtmlWebpackPlugin(htmlPluginOptions),%0A%09%09%09new webpack.DefinePlugin(%7B%0A%09%09%09%09'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),%0A%09%09%09%09'process.env.STYLEGUIDIST_ENV': JSON.stringify(env),%0A%09%09%09%7D),%0A%09%09%5D,%0A
 %09%09pe
@@ -2929,32 +2929,39 @@
 geWebpackConfig(
+config.
 webpackConfig, c
@@ -2959,23 +2959,16 @@
 Config, 
-config.
 webpackC
@@ -2978,24 +2978,582 @@
 ig, env);%0A%09%7D
+%0A%0A%09webpackConfig = merge(webpackConfig, %7B%0A%09%09resolve: %7B%0A%09%09%09alias: %7B%0A%09%09%09%09// allows us to use the compiler%0A%09%09%09%09vue$: 'vue/dist/vue.esm.js',%0A%09%09%09%7D,%0A%09%09%7D,%0A%09%09plugins: %5B%0A%09%09%09// in order to avoid collision with the preload plugins%0A%09%09%09// that are loaded by the vue cli%0A%09%09%09// we have to load these plugins last%0A%09%09%09new StyleguidistOptionsPlugin(config),%0A%09%09%09new MiniHtmlWebpackPlugin(htmlPluginOptions),%0A%09%09%09new webpack.DefinePlugin(%7B%0A%09%09%09%09'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),%0A%09%09%09%09'process.env.STYLEGUIDIST_ENV': JSON.stringify(env),%0A%09%09%09%7D),%0A%09%09%5D,%0A%09%7D);
 %0A%0A%09// Custom

fix compatibility with vue cli 3 beta 10