import type { NextConfig } from 'next';
import path from 'path';
import withSerwistInit from '@serwist/next';
// PERF-3 (Session 7d): bundle analyzer wired but inert unless ANALYZE=true.
// Run with: cd web && ANALYZE=true npm run build
import withBundleAnalyzer from '@next/bundle-analyzer';

// Content-Security-Policy: scoped to what the app actually loads.
// - 'unsafe-eval' / 'unsafe-inline' on script-src: Next.js dev runtime and
//   the inline bootstrap script require these. They can be tightened later
//   with a nonce-based approach if needed.
// - js.stripe.com: Stripe.js (loaded on checkout)
// - PostHog assets/connect: web/src/components/PostHogProvider.tsx
// - Google Fonts: layout.tsx <link> tags
// - Supabase wss: AuthContext realtime + push subscriptions
const CSP = [
  "default-src 'self'",
  "script-src 'self' 'unsafe-eval' 'unsafe-inline' https://js.stripe.com https://us-assets.i.posthog.com https://browser.sentry-cdn.com",
  "style-src 'self' 'unsafe-inline' https://fonts.googleapis.com",
  "font-src 'self' https://fonts.gstatic.com",
  // Session 19 — broadened img-src for player headshots:
  // cdn.wnba.com + img.mlbstatic.com are the league CDNs PrizePicks
  // and Sleeper use; we use the same so coverage matches theirs.
  "img-src 'self' data: blob: https://*.supabase.co https://cdn.nba.com https://cdn.wnba.com https://img.mlbstatic.com https://a.espncdn.com",
  // Session 16 — Sentry browser client posts events to *.sentry.io
  // (and *.ingest.sentry.io for the ingestion endpoints). Adding
  // both forms so the @sentry/nextjs init in SentryInit.tsx can
  // actually report errors out of the browser bundle.
  "connect-src 'self' https://*.supabase.co wss://*.supabase.co https://api.stripe.com https://us.i.posthog.com https://us-assets.i.posthog.com https://*.sentry.io https://*.ingest.sentry.io",
  "frame-src https://js.stripe.com https://hooks.stripe.com",
  "worker-src 'self' blob:",
  "manifest-src 'self'",
  "object-src 'none'",
  "base-uri 'self'",
  "form-action 'self'",
].join('; ');

const nextConfig: NextConfig = {
  output: 'standalone',
  turbopack: {
    root: path.join(__dirname),
  },
  images: {
    remotePatterns: [],
  },
  poweredByHeader: false,
  reactStrictMode: true,
  async redirects() {
    return [
      // Truth-Everywhere Part 2 (item 8) — the backdated 2026-03-22
      // "line-movement-guide" orphan is retired. Any inbound link 301s to the
      // real blog index (the 5 committed articles).
      { source: '/blog/line-movement-guide', destination: '/blog', permanent: true },
    ];
  },
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          { key: 'Content-Security-Policy', value: CSP },
          { key: 'X-Frame-Options', value: 'DENY' },
          { key: 'X-Content-Type-Options', value: 'nosniff' },
          { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
          { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=()' },
          { key: 'X-DNS-Prefetch-Control', value: 'on' },
          { key: 'Strict-Transport-Security', value: 'max-age=31536000; includeSubDomains' },
        ],
      },
      // The service worker must be served with no-cache or browsers will pin
      // an outdated SW for days. Override the global Cache-Control here.
      {
        source: '/sw.js',
        headers: [
          { key: 'Cache-Control', value: 'no-cache, no-store, must-revalidate' },
          { key: 'Service-Worker-Allowed', value: '/' },
        ],
      },
    ];
  },
};

const withSerwist = withSerwistInit({
  swSrc: 'src/sw.ts',
  swDest: 'public/sw.js',
  // Serwist only ships in production builds — dev requests bypass the SW so
  // hot-reload and source maps work normally.
  disable: process.env.NODE_ENV === 'development',
});

// Compose: Serwist wraps first, then bundle-analyzer wraps the result.
// Analyzer only emits the HTML report when ANALYZE=true; otherwise it's
// a no-op pass-through.
const bundleAnalyzer = withBundleAnalyzer({
  enabled: process.env.ANALYZE === 'true',
  openAnalyzer: false,
});

export default bundleAnalyzer(withSerwist(nextConfig));
