require("@babel/register")({ presets: ["@babel/preset-react"] });

const path = require("path");
const fs = require("fs");
const React = require("react");
const { renderToStaticMarkup } = require("react-dom/server");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyWebpackPlugin = require("copy-webpack-plugin");
const BookIndex = require("./src/BookIndex.jsx").default;

function readPages(dir) {
  const pageNums = fs
    .readdirSync(dir)
    .map(f => { const m = f.match(/^(\d+)\.html$/); return m ? parseInt(m[1], 10) : null; })
    .filter(n => n !== null)
    .sort((a, b) => a - b);

  return pageNums.map(n => {
    let content = fs.readFileSync(path.join(dir, `${n}.html`), "utf8");
    content = content.replace(/[ \t]*<link[^>]+>\n?/g, "").trim();
    return { n, content };
  });
}

function bookTemplateContent(title, logoText, dir) {
  const pages = readPages(dir);
  return () =>
    "<!DOCTYPE html>" +
    renderToStaticMarkup(React.createElement(BookIndex, { title, logoText, pages }));
}

module.exports = (env, argv) => {
  const isProd = argv.mode === "production";

  return {
    entry: {
      sheet: "./fabula-ultima-sheet.js",
      // Imports the shared CSS so HtmlWebpackPlugin can inject it into the book page
      book: "./book.js",
    },
    output: {
      filename: isProd ? "[name].[contenthash].js" : "[name].js",
      path: path.resolve(__dirname, "dist"),
      clean: true,
      iife: false,
    },
    module: {
      rules: [
        {
          test: /\.css$/,
          use: [
            isProd ? MiniCssExtractPlugin.loader : "style-loader",
            "css-loader",
          ],
        },
      ],
    },
    plugins: [
      ...(isProd
        ? [new MiniCssExtractPlugin({ filename: "[name].[contenthash].css" })]
        : []),
      new HtmlWebpackPlugin({
        template: "./fabula-ultima-sheet.html",
        filename: "index.html",
        chunks: ["sheet"],
        scriptLoading: "blocking",
      }),
      new HtmlWebpackPlugin({
        templateContent: bookTemplateContent(
          "Fabula Ultima - Core Rulebook",
          "Core Rules",
          "./books/core"
        ),
        filename: "books/core/index.html",
        chunks: ["book"],
        scriptLoading: "blocking",
      }),
      new HtmlWebpackPlugin({
        templateContent: bookTemplateContent(
          "Fabula Ultima - Natural Fantasy Atlas",
          "Natural Fantasy Atlas",
          "./books/natural-fantasy-atlas"
        ),
        filename: "books/natural-fantasy-atlas/index.html",
        chunks: ["book"],
        scriptLoading: "blocking",
      }),
      // Copy book pages to dist/books/ (excluding index.html, managed by HtmlWebpackPlugin)
      new CopyWebpackPlugin({
        patterns: [
          {
            from: "books",
            to: "books",
            globOptions: { ignore: ["**/index.html"] },
          },
        ],
      }),
      // Copy static CSS
      new CopyWebpackPlugin({
        patterns: [
          {
            from: "css",
            to: "css",
            globOptions: { ignore: ["**/index.html"] },
          },
        ],
      }),
    ],
    optimization: {
      minimizer: ["...", new CssMinimizerPlugin()],
      splitChunks: {
        cacheGroups: {
          // Merge CSS from all entries into a single shared file
          styles: {
            name: "styles",
            type: "css/mini-extract",
            chunks: "all",
            enforce: true,
          },
        },
      },
    },
    devServer: {
      static: [
        { directory: path.resolve(__dirname, "dist") },
        { directory: path.resolve(__dirname, "books"), publicPath: "/books" },
        { directory: path.resolve(__dirname, "css"), publicPath: "/css" },
      ],
      port: 8080,
      open: true,
      historyApiFallback: {
        rewrites: [
          { from: /^\/book$/, to: "/book/index.html" },
        ],
      },
    },
  };
};
