import type { NextConfig } from "next";

// eslint-disable-next-line @typescript-eslint/no-require-imports
const { withPayload } = require("@payloadcms/next/withPayload");

import env from "./env.config";

const INTERNAL_PACKAGES = [
  "@turbostarter/analytics-web",
  "@turbostarter/api",
  "@turbostarter/auth",
  "@turbostarter/billing",
  "@turbostarter/cms",
  "@turbostarter/email",
  "@turbostarter/db",
  "@turbostarter/i18n",
  "@turbostarter/monitoring-web",
  "@turbostarter/shared",
  "@turbostarter/storage",
  "@turbostarter/ui",
  "@turbostarter/ui-web",
];

// Security headers for production
const securityHeaders = [
  {
    key: "X-DNS-Prefetch-Control",
    value: "on",
  },
  {
    key: "Strict-Transport-Security",
    value: "max-age=63072000; includeSubDomains; preload",
  },
  {
    key: "X-Frame-Options",
    value: "SAMEORIGIN",
  },
  {
    key: "X-Content-Type-Options",
    value: "nosniff",
  },
  {
    key: "X-XSS-Protection",
    value: "1; mode=block",
  },
  {
    key: "Referrer-Policy",
    value: "strict-origin-when-cross-origin",
  },
  {
    key: "Permissions-Policy",
    value: "camera=(), microphone=(), geolocation=(), interest-cohort=()",
  },
  // Content-Security-Policy - configured for development flexibility
  // In production, tighten 'unsafe-inline' and 'unsafe-eval' as needed
  {
    key: "Content-Security-Policy",
    value: [
      "default-src 'self'",
      "script-src 'self' 'unsafe-inline' 'unsafe-eval' https://js.stripe.com https://challenges.cloudflare.com",
      "style-src 'self' 'unsafe-inline'",
      "img-src 'self' data: blob: https: http:",
      "font-src 'self' data:",
      "connect-src 'self' https://api.stripe.com https://*.sentry.io wss:",
      "frame-src 'self' https://js.stripe.com https://hooks.stripe.com https://challenges.cloudflare.com",
      "object-src 'none'",
      "base-uri 'self'",
      "form-action 'self'",
      "frame-ancestors 'self'",
      "upgrade-insecure-requests",
    ].join("; "),
  },
];

// build: 1776069543
const config: NextConfig = {
  reactStrictMode: true,
  output: "standalone",
  // TEMPORARY: Hono RPC + TanStack Query type inference whack-a-mole blocking production deploy.
  // Ship now, fix types post-launch as dedicated tech-debt sprint.
  typescript: {
    ignoreBuildErrors: true,
  },
  serverExternalPackages: [
    "better-sqlite3",
    "@mapbox/node-pre-gyp",
    "esbuild",
    "payload",
    "@payloadcms/db-postgres",
    "@payloadcms/db-sqlite",
    "@payloadcms/richtext-lexical",
    "@payloadcms/next",
    "@payloadcms/ui",
    "sharp",
    "libsodium-wrappers",
  ],
  turbopack: {
    rules: {
      "*.svg": {
        loaders: ["@svgr/webpack"],
        as: "*.js",
      },
    },
  },

  // Webpack SVG loader (used when TURBOPACK=0 for production builds).
  // Exclude app/ dir SVGs (icon.svg, opengraph-image) — Next.js metadata
  // loader handles those. Only process package SVGs (flags, logos).
  webpack(config) {
    const existingSvgRule = config.module.rules.find(
      (rule: { test?: RegExp }) => rule.test?.test?.(".svg"),
    );
    if (existingSvgRule) {
      existingSvgRule.exclude = /packages\/ui\/.*\.svg$/;
    }
    config.module.rules.push({
      test: /\.svg$/,
      include: /packages\/ui\//,
      use: ["@svgr/webpack"],
    });
    return config;
  },

  images: {
    remotePatterns: [
      {
        hostname: "images.unsplash.com",
      },
    ],
  },

  /** Enables hot reloading for local packages without a build step */
  transpilePackages: [...INTERNAL_PACKAGES, "react-image-crop"],
  experimental: {
    optimizePackageImports: INTERNAL_PACKAGES,
  },

  // Apply security headers only in production
  // CSP with upgrade-insecure-requests breaks Next.js client-side navigation in dev
  async headers() {
    if (process.env.NODE_ENV !== "production") {
      return [];
    }
    return [
      {
        // Apply to all routes
        source: "/:path*",
        headers: securityHeaders,
      },
    ];
  },
};

const withBundleAnalyzer = require("@next/bundle-analyzer")({
  enabled: env.ANALYZE,
});

export default withPayload(withBundleAnalyzer(config));
