import { readFileSync } from "node:fs";
import { resolve } from "node:path";
import { withSentryConfig } from "@sentry/nextjs";
import { MCP_CATALOG_API_BASE_URL } from "@shared";
import type { NextConfig } from "next";

const platformPkg = JSON.parse(
  readFileSync(resolve(import.meta.dirname, "../package.json"), "utf-8"),
) as { name: string; version: string };

const nextConfig: NextConfig = {
  allowedDevOrigins: getAllowedDevOrigins(),
  env: {
    NEXT_PUBLIC_APP_VERSION: platformPkg.version,
  },
  output: "standalone",
  // Version skew protection during rolling deployments.
  // https://nextjs.org/docs/app/api-reference/config/next-config-js/deploymentId
  // VERSION is set as a build arg by CI and baked into the
  // client bundle here. On client navigation, a mismatch between
  // the client's deployment id and the server's response header triggers a
  // hard reload, fetching fresh assets that match the server build.
  // Next.js restricts the id to [a-zA-Z0-9_-], so non-conforming characters
  // (e.g. the dots in `v1.2.41`) are replaced with hyphens.
  // https://nextjs.org/docs/messages/deploymentid-invalid-characters
  deploymentId: process.env.VERSION?.replace(/[^a-zA-Z0-9_-]/g, "-"),
  transpilePackages: ["@shared"],
  // Disable dev indicators so they don't show up in docs automated screenshots
  devIndicators: false,
  turbopack: {
    resolveAlias: {
      "@shared/access-control": "../shared/access-control.ts",
    },
  },
  logging: {
    fetches: {
      fullUrl: true,
      hmrRefreshes: true,
    },
    incomingRequests: true,
  },
  experimental: {
    proxyTimeout: 300000, // 5 minutes in milliseconds - prevents SSE stream timeout
  },
  httpAgentOptions: {
    keepAlive: true,
  },
  async redirects() {
    return [];
  },
  async rewrites() {
    const backendUrl =
      process.env.ARCHESTRA_INTERNAL_API_BASE_URL || "http://localhost:9000";
    return [
      {
        source: "/api/archestra-catalog/:path*",
        destination: `${MCP_CATALOG_API_BASE_URL}/:path*`,
      },
      // /api/auth/* is handled by the API route at app/api/auth/[...path]/route.ts
      // to properly forward the Origin header for SAML SSO callbacks.
      // API routes take precedence over rewrites in Next.js.
      {
        source: "/api/:path*",
        destination: `${backendUrl}/api/:path*`,
      },
      {
        source: "/v1/:path*",
        destination: `${backendUrl}/v1/:path*`,
      },
      {
        source: "/.well-known/:path*",
        destination: `${backendUrl}/.well-known/:path*`,
      },
      {
        source: "/health",
        destination: `${backendUrl}/health`,
      },
      {
        source: "/_sandbox/:path*",
        destination: `${backendUrl}/_sandbox/:path*`,
      },
      {
        source: "/ws",
        destination: `${backendUrl}/ws`,
      },
    ];
  },
};

function getAllowedDevOrigins(): string[] {
  return [
    process.env.ARCHESTRA_FRONTEND_URL,
    process.env.ARCHESTRA_NGROK_DOMAIN,
  ]
    .filter((value): value is string => !!value)
    .map((value) => {
      try {
        return new URL(value).host;
      } catch {
        return value;
      }
    });
}

export default withSentryConfig(nextConfig, {
  // For all available options, see:
  // https://www.npmjs.com/package/@sentry/webpack-plugin#options

  org: "archestra",

  project: "archestra-platform-frontend",

  // The archestra Sentry org is hosted in the EU region
  sentryUrl: "https://de.sentry.io/",

  // Only print logs for uploading source maps in CI
  silent: !process.env.CI,

  // For all available options, see:
  // https://docs.sentry.io/platforms/javascript/guides/nextjs/manual-setup/

  // Upload a larger set of source maps for prettier stack traces (increases build time)
  widenClientFileUpload: true,

  // Route browser requests to Sentry through a Next.js rewrite to circumvent ad-blockers.
  // This can increase your server load as well as your hosting bill.
  // Note: Check that the configured route will not match with your Next.js middleware, otherwise reporting of client-
  // side errors will fail.
  tunnelRoute: "/monitoring",

  // Automatically tree-shake Sentry logger statements to reduce bundle size
  disableLogger: true,

  // Enables automatic instrumentation of Vercel Cron Monitors. (Does not yet work with App Router route handlers.)
  // See the following for more information:
  // https://docs.sentry.io/product/crons/
  // https://vercel.com/docs/cron-jobs
  automaticVercelMonitors: true,
});
