import type { NextConfig } from "next";
import path from "path";
import { fileURLToPath } from "url";
import { withSentryConfig } from "@sentry/nextjs";

// This app lives in vibn-frontend; a lockfile under $HOME can make Turbopack pick the wrong root
// and hydrate with a mismatched client bundle (e.g. different JustineNav markup).
const turbopackRoot = path.dirname(fileURLToPath(import.meta.url));

// Google OAuth on localhost: NextAuth must build the same callback URL Google expects.
// If NEXTAUTH_URL is unset in dev, default it (set explicitly if you use 127.0.0.1 or another port).
if (
  process.env.NODE_ENV === "development" &&
  !process.env.NEXTAUTH_URL?.trim()
) {
  process.env.NEXTAUTH_URL = "http://localhost:3000";
}

const nextConfig: NextConfig = {
  turbopack: {
    root: turbopackRoot,
  },
  output: "standalone",
  // ssh2 ships native .node binaries; turbopack can't bundle them
  // ("non-ecmascript placeable asset"). Externalize so they're loaded
  // at runtime via Node's require, the same way @prisma/client works.
  serverExternalPackages: [
    "@prisma/client",
    "prisma",
    "ssh2",
    "cpu-features",
    "pdf-parse",
    // Prevents Turbopack from bundling these packages and hitting the
    // import-in-the-middle version mismatch warning on every request.
    // Both ship a nested @opentelemetry/instrumentation@0.212 that wants
    // iitm@2.x, but the project root has iitm@3.x.
    "@fastify/otel",
    "@prisma/instrumentation",
  ],
  // react-markdown and its entire unified/remark/rehype ecosystem are
  // ESM-only (type:"module", no CJS fallback). Next.js webpack can't
  // resolve them without explicit transpilation — manifests as
  // "TypeError: Cannot read properties of undefined (reading 'z')" in
  // the minified production bundle.
  transpilePackages: [
    "react-markdown",
    "remark-gfm",
    "remark-parse",
    "remark-rehype",
    "unified",
    "vfile",
    "vfile-message",
    "mdast-util-from-markdown",
    "mdast-util-to-markdown",
    "mdast-util-gfm",
    "mdast-util-gfm-table",
    "mdast-util-gfm-task-list-item",
    "mdast-util-gfm-strikethrough",
    "mdast-util-gfm-autolink-literal",
    "mdast-util-gfm-footnote",
    "micromark",
    "micromark-core-commonmark",
    "micromark-extension-gfm",
    "micromark-util-combine-extensions",
    "micromark-util-character",
    "micromark-util-chunked",
    "micromark-util-classify-character",
    "micromark-util-decode-string",
    "micromark-util-encode",
    "micromark-util-html-tag-name",
    "micromark-util-normalize-identifier",
    "micromark-util-resolve-all",
    "micromark-util-sanitize-uri",
    "micromark-util-subtokenize",
    "micromark-util-types",
    "micromark-util-symbol",
    "micromark-util-decode-numeric-character-reference",
    "hast-util-to-jsx-runtime",
    "hast-util-whitespace",
    "hast-util-from-parse5",
    "property-information",
    "space-separated-tokens",
    "comma-separated-tokens",
    "decode-named-character-reference",
    "character-entities",
    "unist-util-position",
    "unist-util-stringify-position",
    "unist-util-visit",
    "unist-util-is",
  ],
  typescript: {
    ignoreBuildErrors: true,
  },
};

// Wrap with Sentry: uploads source maps on every Coolify build so the
// minified prod stack traces (TypeError: reading 'z' / 'j' / 'aa' etc.)
// arrive in the dashboard already de-minified. Auth token is set in
// Coolify env (SENTRY_AUTH_TOKEN); without it the wrapper still works
// at runtime but skips source map upload at build time.
export default withSentryConfig(nextConfig, {
  org: "vibnai",
  project: "vibn-ai",

  // Verbose during beta: we want to *see* "Bundles uploaded: N" in
  // Coolify's build log so we know source maps are flowing. Flip
  // back to `!process.env.CI` once we trust it.
  silent: false,

  // Upload source maps for every client chunk (incl. those in
  // unrelated dirs like node_modules); we want full coverage so
  // production stack traces are de-minified end to end. SDK v10
  // deletes the public source maps after upload by default, so
  // they're only readable inside Sentry.
  widenClientFileUpload: true,

  // Prevents ad-blockers from killing client error events. Routes
  // them through /monitoring on our domain instead of sentry.io.
  tunnelRoute: "/monitoring",

  // Disable telemetry pings from the build wrapper itself.
  telemetry: false,

  // Don't fail the build if source map upload fails (e.g. token
  // missing in a preview build); errors will still capture, they
  // just won't be de-minified.
  errorHandler: (err) => {
    console.warn("Sentry source map upload skipped:", err.message);
  },
});
