import path from "node:path";
import { execSync } from "node:child_process";
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import tailwindcss from "@tailwindcss/vite";
import { TanStackRouterVite } from "@tanstack/router-plugin/vite";
import { sentryVitePlugin } from "@sentry/vite-plugin";

// Git sha local — utilisé en dev quand on n'a pas APP_VERSION du CI.
// En prod c'est le CI qui passe APP_VERSION=${{ github.sha }} en build-arg.
function resolveAppVersion(): string {
  if (process.env.APP_VERSION) return process.env.APP_VERSION;
  try {
    return execSync("git rev-parse --short HEAD").toString().trim();
  } catch {
    return "dev";
  }
}

// Sentry source map upload — actif uniquement si SENTRY_AUTH_TOKEN est défini
// (typiquement injecté par le CI Gitea, pas en local). Sans ça, les stack
// traces dans Sentry seraient illisibles (JS minifié).
//
// `filesToDeleteAfterUpload` est CRITIQUE : sans ça les .map sont copiés
// dans le dist/ → COPY-és dans l'image Docker → servis par nginx → leak
// du code source du SPA en prod. Avec ça, Sentry a les sourcemaps pour
// désobfusquer les stack traces, et nginx ne sert plus que les .js minifiés.
const sentryPlugin = process.env.SENTRY_AUTH_TOKEN
  ? sentryVitePlugin({
      org: process.env.SENTRY_ORG ?? "rubis",
      project: "rubis-web",
      authToken: process.env.SENTRY_AUTH_TOKEN,
      sourcemaps: {
        assets: ["./dist/**"],
        filesToDeleteAfterUpload: ["./dist/**/*.map"],
      },
      release: { name: process.env.APP_VERSION ?? "dev" },
    })
  : null;

const APP_VERSION = resolveAppVersion();

// https://vite.dev/config/
export default defineConfig({
  // Injecte VITE_APP_VERSION dans `import.meta.env` au build/dev sans avoir
  // à l'écrire dans .env (où on ne peut pas évaluer du shell). En CI, le
  // build-arg APP_VERSION est passé via process.env et override.
  define: {
    "import.meta.env.VITE_APP_VERSION": JSON.stringify(APP_VERSION),
  },
  plugins: [
    // Doit être déclaré AVANT react() (cf. doc TanStack Router).
    TanStackRouterVite({
      routesDirectory: "./src/routes",
      generatedRouteTree: "./src/routeTree.gen.ts",
      autoCodeSplitting: true,
    }),
    react(),
    tailwindcss(),
    // Sentry doit être en dernier pour ne uploader que les artefacts finaux.
    ...(sentryPlugin ? [sentryPlugin] : []),
  ],
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
  server: {
    port: 5173,
    strictPort: true,
  },
  build: {
    // Source maps requises pour que Sentry désobfusque les stack traces.
    // En prod, le sentryPlugin les supprime du dist/ après upload pour
    // qu'elles ne soient pas servies publiquement par nginx.
    sourcemap: true,
  },
});
