/**
 * Analytics Middleware for Next.js
 *
 * Tracks page requests at the edge before they reach your application.
 * This provides accurate page view counts even for cached pages.
 */

import { NextResponse, type NextRequest } from 'next/server';

// ─────────────────────────────────────────────────────────────────────────────
// Configuration
// ─────────────────────────────────────────────────────────────────────────────

const COLLECTOR_URL = process.env.ANALYTICS_COLLECTOR_URL || 'http://localhost:4001';
const APP_NAME = process.env.ANALYTICS_APP_NAME || 'nextjs-app';
const ENABLED = process.env.NODE_ENV !== 'test';

// ─────────────────────────────────────────────────────────────────────────────
// Middleware
// ─────────────────────────────────────────────────────────────────────────────

export async function middleware(request: NextRequest): Promise<NextResponse> {
  const response = NextResponse.next();

  if (!ENABLED) return response;

  // Generate or extract session ID
  const existingSessionId = request.cookies.get('analytics_session')?.value;
  const sessionId =
    existingSessionId || `edge_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;

  // Set session cookie if new
  if (!existingSessionId) {
    response.cookies.set('analytics_session', sessionId, {
      httpOnly: true,
      secure: process.env.NODE_ENV === 'production',
      sameSite: 'lax',
      maxAge: 30 * 60, // 30 minutes
    });
  }

  // Track asynchronously (don't block the response)
  trackEdgePageView(request, sessionId).catch(() => {
    // Silent failure
  });

  // Add session ID header for downstream use
  response.headers.set('x-session-id', sessionId);

  return response;
}

// ─────────────────────────────────────────────────────────────────────────────
// Tracking
// ─────────────────────────────────────────────────────────────────────────────

async function trackEdgePageView(request: NextRequest, sessionId: string): Promise<void> {
  const payload = {
    sessionId,
    type: 'navigation',
    action: 'edge_page_view',
    timestamp: new Date().toISOString(),
    metadata: {
      path: request.nextUrl.pathname,
      search: request.nextUrl.search,
      referrer: request.headers.get('referer'),
      userAgent: request.headers.get('user-agent'),
      ip:
        request.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ||
        request.headers.get('x-real-ip') ||
        request.ip,
      country: request.geo?.country,
      region: request.geo?.region,
      city: request.geo?.city,
      _edge: true,
    },
    source: {
      app: APP_NAME,
      environment: process.env.NODE_ENV || 'development',
    },
  };

  await fetch(`${COLLECTOR_URL}/collect/engagement`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(payload),
  });
}

// ─────────────────────────────────────────────────────────────────────────────
// Route Matcher
// ─────────────────────────────────────────────────────────────────────────────

/**
 * Configure which routes the middleware runs on.
 *
 * Excludes:
 * - API routes (tracked separately)
 * - Static files
 * - Next.js internals
 */
export const config = {
  matcher: [
    /*
     * Match all request paths except:
     * - api routes (they have their own tracking)
     * - _next (Next.js internals)
     * - static files (images, fonts, etc.)
     */
    '/((?!api|_next/static|_next/image|favicon.ico|robots.txt|sitemap.xml).*)',
  ],
};
