const path = require("path");
const glob = require("glob");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const RemoveEmptyScriptsPlugin = require("webpack-remove-empty-scripts");

/*
  Webpack build for the Wingsuit theme.

  What this file does:
  - JavaScript behaviors build: finds all JS files under `behaviors/`, bundles them (no minification),
    and writes the compiled outputs to `./js/[name].js`. Accepts `--env.path=...` and resolves it
    relative to this webpack file so you can point at another theme directory if needed.
  - SCSS core build: finds all SCSS files matching `./core/*.core.scss`, compiles each to CSS, and
    writes the output to `./[name].css` (dropping the trailing `.core` from the name). During CSS
    emission we remove comments and lightly tidy whitespace (no minification). For example,
    `./core/main.core.scss` -> `./main.css`.
  - Targeted builds: pass `--env.target=js` to build only JS, `--env.target=css` (or `scss`) to build
    only styles, or omit to build both. This is used by yarn/npm scripts for split build/watch.
*/

module.exports = (env = {}, argv = {}) => {
  // Directory containing this webpack.config.js
  const configDir = __dirname;

  // Optional incoming path (absolute or relative) provided by the user
  const incomingPath = env.path ? String(env.path) : configDir;

  // Convert provided path to a path relative to this webpack file, then resolve it
  const relativeToConfig = path.relative(configDir, path.resolve(incomingPath));
  const baseDir = path.resolve(configDir, relativeToConfig);

  // ----- JavaScript behaviors: compile and copy to ./js/[name].js -----
  // Explanation: We scan the `behaviors` folder for .js files, bundle each with Webpack so imports
  // from node_modules (e.g., `import Carousel from 'bootstrap/js/dist/carousel'`) resolve properly,
  // then place the outputs under a `js` subdirectory keeping the same base names.
  const behaviorsDir = path.resolve(baseDir, "behaviors");
  const jsEntries = glob.sync(path.join(behaviorsDir, "*.js")).reduce((acc, filePath) => {
    const name = path.basename(filePath, path.extname(filePath));
    acc[name] = filePath; // absolute path
    return acc;
  }, {});

  // ----- SCSS core: compile ./core/*.core.scss to ./[name].css (drop trailing .core) -----
  // Explanation: We look for files named like `something.core.scss` inside `core/`. Each is compiled
  // to plain CSS and written next to the theme root (same baseDir) with the `.core` suffix removed.
  // Example: core/main.core.scss -> main.css
  const coreDir = path.resolve(baseDir, "core");
  const scssEntries = glob.sync(path.join(coreDir, "*.core.scss")).reduce((acc, filePath) => {
    const base = path.basename(filePath, ".scss"); // e.g., 'main.core'
    const outName = base.replace(/\.core$/, ""); // 'main'
    acc[outName] = filePath;
    return acc;
  }, {});

  // Target selection: env.target can be 'js', 'css' (or 'scss'), or 'all' (default)
  const targetRaw = (env.target || "all").toString().toLowerCase();
  const buildJS = targetRaw === "all" || targetRaw === "js" || targetRaw === "javascript";
  const buildCSS = targetRaw === "all" || targetRaw === "css" || targetRaw === "scss" || targetRaw === "styles";

  const entries = {};
  if (buildJS) Object.assign(entries, jsEntries);
  if (buildCSS) Object.assign(entries, scssEntries);

  return {
    mode: "production",
    entry: entries,
    output: {
      // Put JS assets under ./js; CSS file locations are governed by MiniCssExtractPlugin below
      path: baseDir,
      filename: "js/[name].js",
      clean: false,
    },
    module: {
      rules: [
        {
          test: /\.js$/i,
          exclude: /node_modules/,
          use: {
            loader: "babel-loader",
            options: {
              cacheDirectory: true,
            },
          },
        },
        {
          test: /\.s?css$/i,
          use: [
            MiniCssExtractPlugin.loader,
            {
              loader: "css-loader",
              options: { sourceMap: true },
            },
            {
              loader: "postcss-loader",
              options: {
                sourceMap: true,
                postcssOptions: {
                  plugins: [
                    [
                      "postcss-discard-comments",
                      { removeAll: true }
                    ]
                  ]
                }
              }
            },
            {
              loader: "sass-loader",
              options: { sourceMap: true },
            },
          ],
        },
      ],
    },
    plugins: [
      new RemoveEmptyScriptsPlugin(),
      new MiniCssExtractPlugin({
        // For SCSS entries we already computed the logical name without `.core`.
        // Emitting to baseDir with `[name].css` matches the required `./[name].css` placement.
        filename: "[name].css",
      }),
    ],
    devtool: "source-map",
    optimization: {
      // Keep JS unminified as requested
      minimize: false,
    },
    // Keep the infrastructure/logging quiet
    stats: "minimal",
  };
};
