import react from "@vitejs/plugin-react";
import { playwright } from "@vitest/browser-playwright";
import path from "path";
import type { TestProjectConfiguration } from "vitest/config";
import { defineConfig } from "vitest/config";

export default defineConfig(() => {
  const apiBaseUrl = process.env.UI_API_BASE_URL ?? "http://localhost/api/v1";

  return {
    plugins: [react()],
    resolve: {
      alias: {
        "@": path.resolve(__dirname, "./"),
      },
    },
    test: {
      globals: true,
      restoreMocks: true,
      mockReset: true,
      unstubEnvs: true,
      unstubGlobals: true,
      coverage: {
        provider: "v8" as const,
        reporter: ["text", "json", "html"],
        exclude: [
          "node_modules",
          ".next",
          "tests/**/*",
          "**/*.test.{ts,tsx}",
          "**/*.browser.test.{ts,tsx}",
          "vitest.config.ts",
          "vitest.setup.ts",
          "vitest.browser.setup.ts",
          "__tests__/**/*",
        ],
      },
      projects: [
        {
          extends: true,
          test: {
            name: "unit",
            environment: "jsdom",
            setupFiles: ["./vitest.setup.ts"],
            include: ["**/*.test.{ts,tsx}"],
            exclude: [
              "node_modules",
              ".next",
              "tests/**/*",
              "**/*.browser.test.{ts,tsx}",
            ],
          },
        },
        {
          extends: true,
          test: {
            name: "browser",
            setupFiles: ["./vitest.browser.setup.ts"],
            include: ["**/*.browser.test.{ts,tsx}"],
            exclude: ["node_modules", ".next", "tests/**/*"],
            browser: {
              enabled: true,
              // Vitest's browser default viewport is 414×896 (phone-sized),
              // which collapses the responsive layout: the legend stacks
              // vertically and ends up overlapping the graph, so Playwright
              // can't click nodes. Use a standard desktop viewport.
              viewport: { width: 1280, height: 800 },
              provider: playwright(),
              headless: true,
              instances: [{ browser: "chromium" }],
            },
          },
        },
      ] as TestProjectConfiguration[],
    },
    define: {
      "process.env.UI_API_BASE_URL": JSON.stringify(apiBaseUrl),
      // `next/dist/server/web/spec-extension/user-agent.js` references
      // `__dirname` directly and is pulled in transitively via `next-auth`.
      // Vite serves it to the browser where that global doesn't exist, so we
      // replace it at bundle time. `optimizeDeps` alone doesn't help —
      // pre-bundling doesn't patch the identifier.
      __dirname: JSON.stringify("/"),
      __filename: JSON.stringify("/__browser_test__.js"),
    },
    optimizeDeps: {
      // Pre-bundle every dep that the attack-paths page transitively imports.
      // Without this, Vite optimizes them on demand at the first request and
      // reloads the page, killing the test run. Keep this list aligned with
      // imports through the page's render tree.
      include: [
        // Test stack
        "vitest-browser-react",
        "msw/browser",

        // Next runtime
        "next/navigation",
        "next/link",
        "next/image",
        "next/cache",
        "next/server",
        "next-auth",
        "next-auth/react",
        "next-auth/providers/credentials",
        "next-themes",

        // App component lib
        "@iconify/react",

        // Radix
        "@radix-ui/react-alert-dialog",
        "@radix-ui/react-avatar",
        "@radix-ui/react-checkbox",
        "@radix-ui/react-collapsible",
        "@radix-ui/react-dialog",
        "@radix-ui/react-dropdown-menu",
        "@radix-ui/react-icons",
        "@radix-ui/react-label",
        "@radix-ui/react-popover",
        "@radix-ui/react-radio-group",
        "@radix-ui/react-scroll-area",
        "@radix-ui/react-select",
        "@radix-ui/react-separator",
        "@radix-ui/react-switch",
        "@radix-ui/react-tabs",
        "@radix-ui/react-toast",
        "@radix-ui/react-tooltip",
        "@radix-ui/react-slot",

        // Graph
        "@xyflow/react",
        "@dagrejs/dagre",

        // Forms / state
        "react-hook-form",
        "@hookform/resolvers/zod",
        "zod",
        "zustand",
        "zustand/middleware",

        // Styling helpers
        "lucide-react",
        "clsx",
        "tailwind-merge",
        "class-variance-authority",

        // App-level deps the page (or its children) pull in
        "@tanstack/react-table",
        "@react-aria/ssr",
        "@react-aria/visually-hidden",
        "modern-screenshot",
        "framer-motion",
        "cmdk",
        "react-markdown",
        "jwt-decode",
        "date-fns",
        "js-yaml",
        "@codemirror/language",
        "@codemirror/state",
        "@lezer/highlight",
        "@uiw/react-codemirror",
        "@sentry/nextjs",
        "@extractus/feed-extractor",
      ],
    },
  };
});
