import path from 'node:path';
import type { NextConfig } from 'next';

// One .env at the repo root serves web, game server and Prisma.
try {
  process.loadEnvFile(path.resolve(import.meta.dirname, '../../.env'));
} catch {
  // optional: production hosts inject env vars directly
}

type HeaderRule = { source: string; headers: { key: string; value: string }[] };

/**
 * Security headers for every response. Rules are applied in order and a later rule replaces an
 * earlier one's value for the same header, so the strict defaults come first and the few routes
 * the /demo page embeds relax framing afterwards.
 *
 * - Nothing may be framed by other sites (clickjacking of /host and /admin, TV links shown in
 *   someone else's page). Only /tv, /join and /play may be framed, and only by our own origin:
 *   /demo embeds a live TV and a phone (which navigates from /join to /play inside its frame).
 * - The TV URL carries its display token in the query string, so /tv never sends a Referer.
 * - HSTS only in production: on http://localhost it would pin the dev host to https.
 * A script-src CSP (nonces via proxy.ts) is a separate, later step.
 */
export function securityHeaders(production: boolean): HeaderRule[] {
  const hardening = [
    "base-uri 'self'",
    "form-action 'self'",
    "object-src 'none'",
  ];
  return [
    {
      source: '/:path*',
      headers: [
        { key: 'X-Content-Type-Options', value: 'nosniff' },
        { key: 'Referrer-Policy', value: 'strict-origin-when-cross-origin' },
        { key: 'Permissions-Policy', value: 'camera=(), microphone=(), geolocation=(), payment=(), usb=()' },
        ...(production ? [{ key: 'Strict-Transport-Security', value: 'max-age=63072000; includeSubDomains' }] : []),
        { key: 'Content-Security-Policy', value: ["frame-ancestors 'none'", ...hardening].join('; ') },
        { key: 'X-Frame-Options', value: 'DENY' },
      ],
    },
    ...['/tv/:path*', '/join/:path*', '/play/:path*'].map((source) => ({
      source,
      headers: [
        { key: 'Content-Security-Policy', value: ["frame-ancestors 'self'", ...hardening].join('; ') },
        { key: 'X-Frame-Options', value: 'SAMEORIGIN' },
      ],
    })),
    { source: '/tv/:path*', headers: [{ key: 'Referrer-Policy', value: 'no-referrer' }] },
  ];
}

const nextConfig: NextConfig = {
  reactStrictMode: true,
  poweredByHeader: false,
  transpilePackages: ['@pintrush/engine', '@pintrush/protocol', '@pintrush/db'],
  serverExternalPackages: ['pg', 'embedded-postgres', 'nodemailer'],
  turbopack: { root: path.resolve(import.meta.dirname, '../..') },
  async headers() {
    return securityHeaders(process.env.NODE_ENV === 'production');
  },
};

export default nextConfig;
