import { NextRequest, NextResponse } from 'next/server';
import { tenantFromHost } from '@/features/tenancy/routing';

function applySecurityHeaders(response: NextResponse, csp: string, production: boolean) {
  response.headers.set('Content-Security-Policy', csp);
  response.headers.set('X-Content-Type-Options', 'nosniff');
  response.headers.set('Referrer-Policy', 'strict-origin-when-cross-origin');
  response.headers.set('Permissions-Policy', 'camera=(), microphone=(), geolocation=(), payment=(), usb=()');
  response.headers.set('X-Frame-Options', 'DENY');
  // Nonces must never be reused through shared/CDN HTML caching.
  response.headers.set('Cache-Control', 'private, no-store');
  if (production) {
    response.headers.set('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
  }
}

export function proxy(request: NextRequest) {
  const nonce = btoa(crypto.randomUUID());
  const production = process.env.NODE_ENV === 'production';
  const csp = `default-src 'self'; script-src 'self' 'nonce-${nonce}' 'strict-dynamic'${!production ? " 'unsafe-eval'" : ''}; style-src 'self' 'unsafe-inline'; img-src 'self' data: blob: https:; font-src 'self'; connect-src 'self'${!production ? ' ws: wss:' : ''}; media-src 'self'; worker-src 'self'; object-src 'none'; base-uri 'self'; form-action 'self'; frame-ancestors 'none';${production ? ' upgrade-insecure-requests;' : ''}`;
  const headers = new Headers(request.headers);
  headers.set('x-nonce', nonce);
  headers.set('x-pathname', request.nextUrl.pathname);
  headers.set('Content-Security-Policy', csp);
  // Never use X-Forwarded-Host for tenant resolution.
  const host = request.headers.get('host') ?? '';
  const root = process.env.ROOT_DOMAIN ?? 'localhost';
  const tenant = tenantFromHost(host, root);
  const mainHost = new URL(process.env.APP_URL ?? 'http://localhost:3000').host;
  const hostname = host.split(':')[0]?.toLowerCase() ?? '';
  // In development, allow localhost + LAN IPs so phones on the same Wi‑Fi can open the app.
  const isLoopback = hostname === 'localhost' || hostname === '127.0.0.1';
  const isLanIp = /^\d{1,3}(\.\d{1,3}){3}$/.test(hostname) && !hostname.startsWith('127.');
  const devLanOk = process.env.NODE_ENV !== 'production' && (isLoopback || isLanIp);
  let response: NextResponse;
  if (tenant) {
    // Tenant hosts only serve public storefront paths; no auth or private API surface.
    const publicApi = request.nextUrl.pathname.startsWith('/api/public/');
    if (publicApi && ['POST', 'GET', 'HEAD'].includes(request.method)) {
      response = NextResponse.next({ request: { headers } });
    } else if (!['GET', 'HEAD'].includes(request.method) || /^\/(api|dashboard|admin|super-admin|login|register|onboarding|store|forgot-password|reset-password)(\/|$)/.test(request.nextUrl.pathname)) {
      response = new NextResponse('Not found', { status: 404 });
    } else if (/^\/(manifest.webmanifest|sw.js|offline.html)$/.test(request.nextUrl.pathname)) {
      response = NextResponse.next({ request: { headers } });
    } else {
      const url = request.nextUrl.clone();
      url.pathname = `/store/${tenant}${url.pathname === '/' ? '' : url.pathname}`;
      response = NextResponse.rewrite(url, { request: { headers } });
    }
  } else if (host !== mainHost && !devLanOk) {
    response = new NextResponse('Invalid host', { status: 421 });
  } else response = NextResponse.next({ request: { headers } });

  applySecurityHeaders(response, csp, production);
  if (/^\/(dashboard|admin|super-admin|api|login|register|onboarding|forgot-password|reset-password)(\/|$)/.test(request.nextUrl.pathname) || request.nextUrl.pathname.includes('/offer/'))
    response.headers.set('X-Robots-Tag', 'noindex, nofollow');
  return response;
}
export const config = { matcher: ['/((?!_next/static|_next/image|favicon.ico|images/|media/|icons/|brand/|storefront/).*)'] };
