/* eslint-disable import/no-default-export */
import typescript from "@rollup/plugin-typescript";
import postcss from "rollup-plugin-postcss";
import commonjs from "@rollup/plugin-commonjs";
import copy from "rollup-plugin-copy";
import { nodeResolve } from "@rollup/plugin-node-resolve";
import postcssimport from "postcss-import";
import autoprefixer from "autoprefixer";
import tools from "@csstools/postcss-global-data";
import presetenv from "postcss-preset-env";
import multiInput from "rollup-plugin-multi-input";
import nodePolyfills from "rollup-plugin-polyfill-node";

const createMultiInput =
  typeof multiInput === "function" ? multiInput : multiInput.default;

/**
 * When PREBUILD_CSS is supplied, only build the main barrels.
 * This ensures postcss maintains consistent ordering of styles across builds.
 *
 * Using multiInput (input with globs) produces inconsistent ordering within styles.css
 * because files are loaded in a non-deterministic order, and postcss bundles them in
 * that order.
 *
 * The primitives barrel is included in addition to the main barrel so that styled
 * primitives (under `src/primitives/`) contribute their CSS module hashes to the
 * extracted styles.css. Without this, primitives' class hashes appear in the JS
 * bundle but not in the stylesheet, so consumers see no styles applied.
 */
const PREBUILD_CSS = process.env.PREBUILD_CSS === "true";
// Object form gives each entry a unique `[name]` for output filenames; both
// inputs share the basename `index.ts`, so the array form would collide.
const PREBUILD_CSS_INPUTS = {
  index: "src/index.ts",
  "primitives/index": "src/primitives/index.ts",
};

/**
 * PostCSS plugin to remove @charset declarations.
 *
 * The @charset rule (from react-datepicker) ends up in the middle of
 * the bundled CSS when imported via postcss-import. Since @charset must be
 * the first line of a CSS file to be valid, and it's unnecessary for
 * HTTP-served content (Content-Type header takes precedence), we remove it.
 */
const removeCharset = {
  postcssPlugin: "remove-charset",
  AtRule: {
    charset: atRule => {
      atRule.remove();
    },
  },
};

export default {
  onwarn(warning, warn) {
    if (
      warning.code === "MODULE_LEVEL_DIRECTIVE" &&
      warning.id?.includes("node_modules/@base-ui")
    ) {
      return;
    }

    warn(warning);
  },
  input: PREBUILD_CSS ? PREBUILD_CSS_INPUTS : `src/**/index.{ts,tsx}`,
  plugins: [
    nodePolyfills(),
    nodeResolve(),
    createMultiInput({ glob: { ignore: ["src/**/docs/**"] } }),
    typescript({
      tsconfig: "./tsconfig.rollup.json",
      declarationDir: "dist",
      noEmitOnError: true,
    }),
    postcss({
      extract: "styles.css",
      inject: false,
      modules: {
        generateScopedName: "[hash:base64]",
        globalModulePaths: [/node_modules/],
      },
      autoModules: false,
      plugins: [
        postcssimport,
        removeCharset,
        autoprefixer,
        tools({
          files: ["../design/dist/foundation.css"],
        }),
        presetenv({
          stage: 1,
          preserve: true,
        }),
      ],
    }),
    commonjs(),
    copy({
      targets: [
        { src: "src/Card/cardcolors.css.d.ts", dest: "dist/Card" },
        { src: "src/Content/Spacing.css.d.ts", dest: "dist/Content" },
        { src: "src/Gallery/Gallery.css.d.ts", dest: "dist/Gallery" },
        { src: "src/Grid/GridAlign.css.d.ts", dest: "dist/Grid" },
        { src: "src/Modal/ModalSizes.css.d.ts", dest: "dist/Modal" },
        {
          src: "src/ProgressBar/ProgressBarSizes.css.d.ts",
          dest: "dist/ProgressBar",
        },
        {
          src: "src/Typography/css/Emphasis.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/FontFamilies.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/FontSizes.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/FontWeights.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/TextAlignment.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/TextCases.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/TextColors.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/Truncate.css.d.ts",
          dest: "dist/Typography/css",
        },
        {
          src: "src/Typography/css/Typography.css.d.ts",
          dest: "dist/Typography/css",
        },
        { src: "src/Glimmer/style/Shape.css.d.ts", dest: "dist/Glimmer/style" },
        { src: "src/Glimmer/style/Sizes.css.d.ts", dest: "dist/Glimmer/style" },
        {
          src: "src/Glimmer/style/Timing.css.d.ts",
          dest: "dist/Glimmer/style",
        },
        {
          src: "src/Combobox/components/ComboboxContent/ComboboxContentList/ComboboxContent.css.d.ts",
          dest: "dist/Combobox/components/ComboboxContent/ComboboxContentList",
        },
        {
          src: "dist/index.d.ts",
          dest: "dist",
          rename: "index.d.mts",
        },
        { src: "src/utils/meta/meta.json", dest: "dist/utils/meta" },
      ],
      hook: "writeBundle",
    }),
  ],
  output: [
    {
      dir: "dist",
      entryFileNames: "[name].cjs",
      chunkFileNames: "[name]-[format].js",
      exports: "named",
      format: "cjs",
    },
    {
      dir: "dist",
      entryFileNames: "[name].mjs",
      chunkFileNames: "[name]-[format].js",
      format: "esm",
    },
  ],
  external: [
    "react",
    "react/jsx-runtime",
    "react-hook-form",
    "react-router-dom",
    "react-dom",
    "react-dom/client",
    "axios",
    "lodash",
    "filesize",
    "color",
    "framer-motion",
    "classnames",
    "@apollo/client",
    "@jobber/design",
    "@jobber/design/foundation",
    "@jobber/formatters",
    "@jobber/hooks",
    "@tanstack/react-table",
  ],
};
