import fs from "node:fs";
import path from "path";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";

// [nexus] Dev-only middleware that serves onnxruntime-web's wasm files at
// /ort-wasm-simd-threaded.{mjs,wasm}. @ricky0123/vad-react sets
// `onnxWASMBasePath: "/"`, which makes onnxruntime-web issue dynamic imports
// against the site root at runtime. Putting the files in ui/public/ works
// at runtime but trips vite's dep optimizer ("files in /public should not
// be imported from source code") because it scans onnxruntime-web's dynamic
// import and resolves the string to the public asset. This plugin bypasses
// public/ entirely — the files never enter vite's module graph, and the URL
// is served straight from node_modules.
function serveOnnxRuntimeWasm(): import("vite").Plugin {
  // onnxruntime-web is a transitive dep of @ricky0123/vad-web and not hoisted
  // to top-level node_modules under pnpm. Scan .pnpm/ for the version dir.
  const pnpmRoot = path.resolve(__dirname, "../node_modules/.pnpm");
  const ortEntry = fs
    .readdirSync(pnpmRoot)
    .find((name) => name.startsWith("onnxruntime-web@"));
  const distDir = ortEntry
    ? path.join(pnpmRoot, ortEntry, "node_modules/onnxruntime-web/dist")
    : null;

  return {
    name: "nexus-serve-onnxruntime-wasm",
    configureServer(server) {
      if (!distDir) {
        server.config.logger.warn(
          "[nexus-serve-onnxruntime-wasm] onnxruntime-web not found in .pnpm store — VAD voice input will 404",
        );
        return;
      }
      server.middlewares.use((req, res, next) => {
        const url = (req.url ?? "").split("?")[0];
        const match = url.match(/^\/ort-wasm-simd-threaded\.(mjs|wasm)$/);
        if (!match) return next();
        const filePath = path.join(distDir, `ort-wasm-simd-threaded.${match[1]}`);
        fs.readFile(filePath, (err, content) => {
          if (err) {
            next(err);
            return;
          }
          res.setHeader(
            "Content-Type",
            match[1] === "mjs" ? "text/javascript" : "application/wasm",
          );
          res.end(content);
        });
      });
    },
  };
}

// [nexus] Redirect OnboardingWizard → NexusOnboardingWizard at resolve time.
// A Vite plugin is used instead of resolve.alias because alias matches against
// the raw import specifier ("./components/OnboardingWizard") — not the resolved
// absolute path — so an absolute-path alias key never fires.
function nexusOnboardingRedirect(): import("vite").Plugin {
  const target = path.resolve(__dirname, "./src/components/NexusOnboardingWizard.tsx");
  return {
    name: "nexus-onboarding-redirect",
    enforce: "pre",
    resolveId(source) {
      if (source.endsWith("/components/OnboardingWizard") && !source.includes("Nexus")) {
        return target;
      }
    },
  };
}

export default defineConfig({
  plugins: [nexusOnboardingRedirect(), serveOnnxRuntimeWasm(), react(), tailwindcss()],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
      lexical: path.resolve(__dirname, "./node_modules/lexical/Lexical.mjs"),
    },
  },
  build: {
    rollupOptions: {
      output: {
        manualChunks: {
          // Note: react/react-dom cannot be split via manualChunks — @vitejs/plugin-react
          // injects the JSX runtime before Rollup processes chunks, so they stay in the entry.
          // The 37 lazy-loaded page chunks are the primary performance lever.
          "vendor-router": ["react-router-dom"],
          "vendor-query": ["@tanstack/react-query"],
          "vendor-markdown": ["react-markdown", "remark-gfm"],
        },
      },
    },
  },
  server: {
    port: 5173,
    // COOP/COEP headers are only respected over HTTPS or localhost.
    // Omitted so LAN access (plain HTTP + non-localhost IP) doesn't trigger
    // browser warnings. Re-enable when serving behind TLS.
    // headers: {
    //   "Cross-Origin-Opener-Policy": "same-origin",
    //   "Cross-Origin-Embedder-Policy": "require-corp",
    // },
    proxy: {
      "/api": {
        target: "http://localhost:6100",
        ws: true,
      },
    },
  },
});
