import { type NextRequest } from 'next/server'
import { updateSession } from '@/lib/supabase/proxy'
import {
  buildCspHeader,
  buildReportingEndpointsHeader,
  ensureCsrfCookie,
  generateNonce,
} from '@/lib/security'

const CSP_NONCE_REQUEST_HEADER = 'x-nonce'

// tdd-guard:skip — Next.js middleware entrypoint. Behaviour (session refresh,
// CSP/nonce, CSRF cookie) is verified via edge/integration + E2E, not a unit
// sibling test. Renamed from the non-registered `proxy()` export so Next.js
// actually loads it (file must be `middleware.ts` with a `middleware` export).
export async function middleware(request: NextRequest) {
  const nonce = generateNonce()
  const isDev = process.env.NODE_ENV !== 'production'

  // Forward the nonce to SSR so `<Script>` consumers and Next.js's own
  // inline bootstrap scripts pick it up via `headers()`. Next.js detects
  // `x-nonce` on the request and nonces its framework scripts
  // automatically (App Router, since 13.4).
  const extraRequestHeaders = new Headers()
  extraRequestHeaders.set(CSP_NONCE_REQUEST_HEADER, nonce)

  const response = await updateSession(request, { extraRequestHeaders })

  const csp = buildCspHeader({ nonce, isDev })
  // Remove any CSP header inherited from `next.config.mjs` so the per-request
  // policy is the only one the client sees.
  response.headers.delete('Content-Security-Policy')
  response.headers.delete('Content-Security-Policy-Report-Only')
  response.headers.set(csp.name, csp.value)
  response.headers.set(CSP_NONCE_REQUEST_HEADER, nonce)

  // Declare the Reporting API group referenced by `report-to` in the CSP.
  // Browsers that do not understand `Reporting-Endpoints` fall back to the
  // `report-uri` directive, which points at the same route.
  const reportingEndpoints = buildReportingEndpointsHeader()
  response.headers.set(reportingEndpoints.name, reportingEndpoints.value)

  // Mint a CSRF cookie if missing (no-op when CSRF_ENABLED is unset).
  ensureCsrfCookie(request, response)

  return response
}

export const config = {
  matcher: [
    /*
     * Match all request paths except for the ones starting with:
     * - _next/static (static files)
     * - _next/image (image optimization files)
     * - favicon.ico (favicon file)
     * - manifest.json (PWA web-app manifest — must be served unauthenticated
     *   so the browser does not parse the /login HTML redirect as JSON)
     * - sw.js (service worker bootstrap — must load before auth)
     * - robots.txt (search-engine crawlers cannot send cookies)
     * - api/csp-report (public report sink; must accept unauthenticated
     *   POSTs from browsers before any session exists — routing it through
     *   the auth redirect would drop every report)
     */
    '/((?!_next/static|_next/image|favicon.ico|manifest.json|sw.js|robots.txt|api/csp-report|.*\\.(?:svg|png|jpg|jpeg|gif|webp)$).*)',
  ],
}
