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

// Proxy c3nav API calls
// URL pattern: /api/c3nav/{event}?endpoint=map/locations
// Proxies to: https://{event}.c3nav.de/api/v2/{endpoint}

interface RouteParams {
  params: {
    event: string;
  };
}

// Valid c3nav events
const VALID_EVENTS = ['39c3', '38c3', '37c3', 'eh22', 'eh2025', 'camp2023'];

// Allowed API endpoints (whitelist for security)
const ALLOWED_ENDPOINTS = [
  'map/settings',
  'map/bounds',
  'map/locations',
  'map/locations/full',
  'map/projection',
];

// Cache for session cookies per event
const sessionCache = new Map<string, { cookie: string; expires: number }>();

// Get a valid session cookie for an event
async function getSessionCookie(event: string): Promise<string | null> {
  const cached = sessionCache.get(event);
  if (cached && cached.expires > Date.now()) {
    return cached.cookie;
  }

  try {
    // Get session by visiting the main page
    const response = await fetch(`https://${event}.c3nav.de/`, {
      redirect: 'follow',
    });

    const setCookie = response.headers.get('set-cookie');
    if (setCookie) {
      // Extract tile_access cookie
      const match = setCookie.match(/c3nav_tile_access="([^"]+)"/);
      if (match) {
        const cookie = `c3nav_tile_access="${match[1]}"`;
        // Cache for 50 seconds (cookie lasts 60s)
        sessionCache.set(event, {
          cookie,
          expires: Date.now() + 50000
        });
        return cookie;
      }
    }
  } catch (e) {
    console.error('Failed to get c3nav session:', e);
  }

  return null;
}

export async function GET(request: NextRequest, { params }: RouteParams) {
  const { event } = params;
  const { searchParams } = new URL(request.url);
  const endpoint = searchParams.get('endpoint') || 'map/bounds';

  // Validate event
  if (!VALID_EVENTS.includes(event)) {
    return NextResponse.json(
      { error: 'Invalid event' },
      { status: 400 }
    );
  }

  // Check if endpoint is allowed (basic path check)
  const isAllowed = ALLOWED_ENDPOINTS.some(
    (allowed) => endpoint === allowed || endpoint.startsWith(allowed + '/')
  );

  if (!isAllowed && !endpoint.startsWith('map/locations/')) {
    return NextResponse.json(
      { error: 'Endpoint not allowed' },
      { status: 403 }
    );
  }

  // Build c3nav API URL (trailing slash required to avoid redirect)
  const apiUrl = `https://${event}.c3nav.de/api/v2/${endpoint}/`;

  try {
    // Get session cookie
    const sessionCookie = await getSessionCookie(event);

    const headers: HeadersInit = {
      'X-API-Key': 'anonymous',
      'Accept': 'application/json',
      'User-Agent': 'rMaps.online/1.0',
    };

    if (sessionCookie) {
      headers['Cookie'] = sessionCookie;
    }

    // Create AbortController for timeout
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 15000);

    const response = await fetch(apiUrl, {
      headers,
      redirect: 'follow',
      signal: controller.signal,
    });

    clearTimeout(timeoutId);

    if (!response.ok) {
      const errorData = await response.json().catch(() => ({ detail: 'Unknown error' }));
      return NextResponse.json(errorData, {
        status: response.status,
        headers: {
          'Access-Control-Allow-Origin': '*',
        },
      });
    }

    const data = await response.json();

    return NextResponse.json(data, {
      status: 200,
      headers: {
        'Cache-Control': 'public, max-age=3600, stale-while-revalidate=86400', // Cache 1 hour, stale 24h
        'Access-Control-Allow-Origin': '*',
      },
    });
  } catch (error) {
    console.error('c3nav API proxy error:', error);
    return NextResponse.json(
      { error: 'Failed to fetch from c3nav' },
      { status: 500 }
    );
  }
}

export async function OPTIONS() {
  return new NextResponse(null, {
    status: 200,
    headers: {
      'Access-Control-Allow-Origin': '*',
      'Access-Control-Allow-Methods': 'GET, OPTIONS',
      'Access-Control-Allow-Headers': 'Content-Type',
    },
  });
}
