import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";
import { viteStaticCopy } from "vite-plugin-static-copy";
import { dirname, resolve } from "node:path";
import { fileURLToPath } from "node:url";

const __dirname = dirname(fileURLToPath(import.meta.url));

// One build pass per entry (LTT_ENTRY), driven by scripts/build.mjs:
// Vite/Rollup cannot emit IIFE for a code-splitting (multi-entry) build, and
// content scripts / MV3 service workers must be single self-contained files.
const entryNames = ["background", "content", "options", "popup", "relay"] as const;
type EntryName = (typeof entryNames)[number];

const entryPaths: Record<EntryName, string> = {
  background: resolve(__dirname, "src/background/index.ts"),
  content: resolve(__dirname, "src/content/index.ts"),
  options: resolve(__dirname, "src/options/options.html"),
  popup: resolve(__dirname, "src/popup/popup.html"),
  relay: resolve(__dirname, "src/relay.ts"),
};

// Build targets: --mode chrome | --mode firefox
export default defineConfig(({ mode }) => {
  const isFirefox = mode === "firefox";
  const outDir = resolve(__dirname, "dist", isFirefox ? "firefox" : "chrome");
  const only = (process.env.LTT_ENTRY ?? "") as EntryName;
  const entry: EntryName | null = entryNames.includes(only) ? only : null;
  const input = entry
    ? { [entry]: entryPaths[entry] }
    : Object.fromEntries(entryNames.map((name) => [name, entryPaths[name]]));

  return {
    plugins: [
      vue(),
      viteStaticCopy({
        targets: [
          // kit.css references /assets/fonts/... absolutely; the overlay rewrites
          // those to runtime.getURL('') + '/assets/...' at runtime
          { src: "../../node_modules/gnexus-ui-kit/dist/assets/*", dest: "assets" },
          { src: "src/icons/*.png", dest: "icons" },
        ],
      }),
    ],
    build: {
      outDir,
      // empty once per target, on the first pass
      emptyOutDir: entry === "background",
      target: "esnext",
      // keep all CSS in one extracted file (assets/content.css): IIFE builds
      // otherwise inline CSS into a <style> appended to the host page's head,
      // which leaks styles there and trips strict style-src CSP
      cssCodeSplit: false,
      sourcemap: mode.endsWith("-dev"),
      rollupOptions: {
        input,
        output: {
          // content scripts and MV3 backgrounds must be single self-contained
          // files (no ES module imports at runtime)
          format: "iife",
          inlineDynamicImports: Boolean(entry),
          entryFileNames: (chunk) =>
            chunk.name === "background" || chunk.name === "content" ? `${chunk.name}.js` : "assets/[name].js",
          chunkFileNames: "assets/[name].js",
          assetFileNames: () => {
            // cssCodeSplit:false funnels each pass's CSS into one file; give the
            // extension pages their own names so the content pass (which runs
            // last and owns assets/style.css for the overlay) cannot overwrite them
            if (only === "options") return "assets/options.css";
            if (only === "popup") return "assets/popup.css";
            return "assets/style.css";
          },
        },
      },
    },
  };
});