const process = require("process");

const Dotenv = require("dotenv-webpack");
const { webpackConfig, merge } = require("shakapacker");
const webpack = require("webpack");

const customizeWebpackDefaultRules = require("./helpers/customize-default-rules");
const resolve = require("./resolve");
const rules = require("./rules");

const dotEnvFileSuffix =
  process.env.NODE_ENV === "production" ? "" : `.${process.env.NODE_ENV}`;

let devtool = "hidden-source-map",
  mode = "production";
if (process.env.RAILS_ENV === "test") {
  devtool = false;
  mode = "none";
} else if (process.env.RAILS_ENV === "development") {
  devtool = "eval-cheap-module-source-map";
  mode = "development";
}

const commonOptions = {
  mode,
  infrastructureLogging: { level: "warn" },
  devtool,
  resolve,
  optimization: {
    runtimeChunk: "single",
    splitChunks: {
      chunks: "all",
      maxInitialRequests: Infinity,
      minSize: 5000, // 5kb uncompressed
      cacheGroups: {
        bigBinary: {
          // Excluded neetoEditor to support async chunk load.
          test: /[\\/]node_modules[\\/](?:@bigbinary)[\\/](?!neeto-editor)/,
          priority: 5,
          name(module) {
            const matches = module.context.match(
              /[\\/]node_modules[\\/](?:@bigbinary)[\\/](.*?)([\\/]|$)/
            );
            const packageName = matches ? matches[1] : "bigbinary-main";

            return `bigbinary-${packageName.replace("@", "")}`;
          },
        },
        reactModules: {
          test: /[\\/]node_modules[\\/]react.*[\\/]/,
          name: "react-modules",
          priority: 10,
        },
        antd: {
          test: /[\\/]node_modules[\\/]antd[\\/]/,
          name: "antd",
          priority: 10,
        },
        recharts: {
          test: /[\\/]node_modules[\\/]recharts[\\/]/,
          name: "recharts",
          priority: 10,
        },
        emojiMart: {
          test: /[\\/]node_modules[\\/]emoji-mart[\\/]/,
          name: "emoji-mart",
          priority: 10,
        },
        npmCommon: {
          test: /[\\/]node_modules[\\/](zustand|ramda|formik|dayjs|axios|classnames|dompurify|popper.js|yup|qs|zustand|framer-motion|lowlight|tippy.js)[\\/]/,
          name: "npm-common",
          priority: 10,
        },
        npmRest: {
          test: /[\\/]node_modules[\\/](?!@bigbinary[\\/]neeto-editor)/, // Excludes neetoEditor
          name: "npm-rest",
        },
      },
    },
  },
  module: { rules },
  plugins: [
    new webpack.ProvidePlugin({ process: "process/browser" }),
    new Dotenv({
      path: `./.env${dotEnvFileSuffix}`,
      systemvars: true,
      silent: true,
    }),
  ],
  ignoreWarnings: [/Failed to parse source map/],
  snapshot: { managedPaths: [/^(node_modules\/@bigbinary\/.+)/] },
};

// This rule is causing issues to react-svg-loader
const defaultRules = {
  "asset/resource": {
    test: /\.(bmp|gif|jpe?g|png|tiff|ico|avif|webp|eot|otf|ttf|woff|woff2)$/,
  },
};

const customWebpackConfig = customizeWebpackDefaultRules(
  webpackConfig,
  defaultRules
);

module.exports = merge(customWebpackConfig, commonOptions);
