import { dirname, resolve } from "node:path";
import { defineConfig, type Plugin } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

// @ts-expect-error process is a nodejs global
const host = process.env.TAURI_DEV_HOST;

const liteparseRedirects = [
  { match: /\/engines\/pdf\/pdfium-renderer(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/pdfium-renderer.ts" },
  { match: /\/engines\/pdf\/pdfjsImporter(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/pdfjsImporter.ts" },
  { match: /\/engines\/ocr\/http-simple(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/http-simple.ts" },
  { match: /\/conversion\/convertToPdf(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/convertToPdf.ts" },
  { match: /\/processing\/gridDebugLogger(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/gridDebugLogger.ts" },
  { match: /\/processing\/gridVisualizer(\.js|\.ts)?$/, target: "src/lib/liteparseStubs/gridVisualizer.ts" },
];

function liteparseNodeRedirects(): Plugin {
  return {
    name: "liteparse-node-redirects",
    enforce: "pre",
    resolveId(source, importer) {
      if (!importer) return null;
      const abs = source.startsWith(".") ? resolve(dirname(importer), source) : source;
      for (const { match, target } of liteparseRedirects) {
        if (match.test(abs) || match.test(source)) {
          return resolve(target);
        }
      }
      return null;
    },
  };
}

// https://vite.dev/config/
export default defineConfig(async () => ({
  plugins: [liteparseNodeRedirects(), react(), tailwindcss()],
  optimizeDeps: { include: ["tesseract.js"] },
  resolve: {
    alias: [
      { find: "node:fs/promises", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "node:fs", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "node:url", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "node:path", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "node:os", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "node:child_process", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: /^fs$/, replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: /^path$/, replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: /^os$/, replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: /^child_process$/, replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "form-data", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "axios", replacement: resolve("src/lib/liteparseStubs/empty.ts") },
      { find: "file-type", replacement: resolve("src/lib/liteparseStubs/file-type.ts") },
      {
        find: "opentype.js/dist/opentype.module.js",
        replacement: resolve("node_modules/opentype.js/dist/opentype.mjs"),
      },
    ],
  },

  // 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 watching `src-tauri`
      ignored: ["**/src-tauri/**"],
    },
  },
  build: {
    chunkSizeWarningLimit: 400,
    rollupOptions: {
      output: {
        manualChunks(id) {
          if (!id.includes("node_modules")) {
            return undefined;
          }

          if (
            id.includes("react-markdown") ||
            id.includes("remark-gfm") ||
            id.includes("mdast") ||
            id.includes("micromark") ||
            id.includes("hast") ||
            id.includes("unist")
          ) {
            return "markdown";
          }

          if (id.includes("recharts") || id.includes("/d3-")) {
            return "charts";
          }

          if (
            id.includes("/react/") ||
            id.includes("react-dom") ||
            id.includes("scheduler")
          ) {
            return "react-vendor";
          }

          if (id.includes("@tauri-apps")) {
            return "tauri";
          }

          return undefined;
        },
      },
    },
  },
}));
