// libs
const merge = require('webpack-merge');
const webpack = require('webpack');
const path = require('path');
const CopyPlugin = require('copy-webpack-plugin');
const WebpackBar = require('webpackbar');
const ImageminPlugin = require('imagemin-webpack-plugin').default;

const ManifestPlugin = require('webpack-manifest-plugin');
// Forces webpack-dev-server program to write bundle files to the file system.
const WriteFileWebpackPlugin = require('write-file-webpack-plugin');

// local
const parts = require('../parts');
const commonConfig = require('../common');
const paths = require('../../paths');

const createConfig = config => {
  const isProduction = config.mode === 'production';
  const isDevelopment = config.mode === 'development';

  return merge([
    // clean in prod
    {
      mode: config.mode,
      name: 'client',
      target: 'web',
      // Entries configuration
      entry: {
        // bundle is the name used for the files!
        bundle: [paths.main],
      },
      // Source mapping or not
      devtool: isProduction ? 'none' : 'eval-source-map',
    },
    // default
    parts.outputPath({
      path: path.join(paths.clientBuild, paths.publicPath),
      filename: isProduction ? '[name].[contenthash].js' : '[name].js',
    }),
    parts.loadJavaScript({
      prod: isProduction,
    }),
    parts.loadCSS({
      prod: isProduction,
    }),
    parts.setVariables({
      __LOCALE__: isDevelopment,
      __DEV__: config.dev || false,
      __STAGING__: config.staging || false,
      __BROWSER__: true,
      __SSR__: true,
      __TEST__: false,
    }),
    {
      plugins: [
        new CopyPlugin({
          patterns: [
            {
              from: path.join(paths.baseDir, config.staging ? 'static-staging' : 'static'),
              to: path.join(paths.clientBuild, paths.publicPath),
              noErrorOnMissing: true,
            },
          ],
        }),
        new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
        // create a manifest (needed)
        new ManifestPlugin({ fileName: 'manifest.json' }),
        new WebpackBar({
          name: 'client',
        }),
      ],
    },
    isProduction && parts.imageOptimization(),
    isDevelopment && {
      plugins: [
        // Forces webpack-dev-server program to write bundle files to the file system. (even if dev server launched programatically)
        new WriteFileWebpackPlugin(),
        new webpack.NamedModulesPlugin(),
        new webpack.HotModuleReplacementPlugin({
          // Options...
        }),
      ],
    },
    parts.optimize(),
  ]);
};

module.exports = env => {
  const config = createConfig({
    mode: env && env.prod ? 'production' : 'development',
    ...env,
  });
  // mode : Possible values for mode are: none, development or production(default).
  return merge(config, commonConfig);
};
