import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { widgetLibBundlePlugin } from "./scripts/vite-widget-lib-bundle";

const host = process.env.TAURI_DEV_HOST;

const manualChunkGroups: Record<string, string[]> = {
  react: ["react", "react-dom", "react/jsx-runtime"],
  i18n: ["i18next", "react-i18next"],
  icons: ["lucide-react"],
  xterm: [
    "@xterm/xterm",
    "@xterm/addon-fit",
    "@xterm/addon-search",
    "@xterm/addon-web-links",
    "@xterm/addon-webgl",
  ],
  markdown: [
    "@codemirror/autocomplete",
    "@codemirror/commands",
    "@codemirror/lang-markdown",
    "@codemirror/language",
    "@codemirror/search",
    "@codemirror/state",
    "@codemirror/theme-one-dark",
    "@codemirror/view",
    "@lezer/markdown",
    "marked",
    "dompurify",
  ],
  tauri: [
    "@tauri-apps/api",
    "@tauri-apps/plugin-dialog",
    "@tauri-apps/plugin-fs",
    "@tauri-apps/plugin-opener",
  ],
};

function manualChunks(id: string): string | undefined {
  for (const [chunkName, packageIds] of Object.entries(manualChunkGroups)) {
    if (packageIds.some((packageId) => id.includes(`/node_modules/${packageId}/`))) {
      return chunkName;
    }
  }
  return undefined;
}

// https://vite.dev/config/
export default defineConfig(async () => ({
  base: "./",
  plugins: [widgetLibBundlePlugin(), react(), tailwindcss()],

  // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build`
  //
  // 1. prevent Vite from obscuring rust errors
  clearScreen: false,
  // 2. tauri expects a fixed port, fail if that port is not available
  server: {
    port: 1420,
    strictPort: true,
    host: host || false,
    hmr: host
      ? {
          protocol: "ws",
          host,
          port: 1421,
        }
      : undefined,
    watch: {
      // 3. tell Vite to ignore non-frontend build and scratch trees
      ignored: ["**/src-tauri/**", "**/.tmp/**"],
    },
  },
  build: {
    // Dashboard widget libraries are optional, lazy-loaded sandbox sources.
    // Keep this below "anything goes" so unexpectedly-large chunks still
    // surface during release builds.
    chunkSizeWarningLimit: 3500,
    rollupOptions: {
      output: {
        manualChunks,
      },
    },
  },
}));
