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

const BACKEND_URL = process.env.BACKEND_URL || 'http://backend:8000';

async function proxyRequest(request: NextRequest, internalPath?: string) {
    const url = new URL(request.url);
    const targetPath = internalPath ? `${internalPath}${url.search}` : `${url.pathname}${url.search}`;

    try {
        const authHeader = request.headers.get('authorization');
        const cookieHeader = request.headers.get('cookie');
        const contentType = request.headers.get('content-type');

        // For POST/PUT/PATCH requests, get the body
        let body: string | undefined;
        if (request.method !== 'GET' && request.method !== 'HEAD') {
            body = await request.text();
            console.log(`[Proxy] ${request.method} ${targetPath} - Body length: ${body?.length || 0}`);
        }

        const headers = new Headers();
        if (contentType) {
            headers.set('Content-Type', contentType);
        } else if (body) {
            headers.set('Content-Type', 'application/json');
        }
        if (authHeader) {
            headers.set('Authorization', authHeader);
        }
        if (cookieHeader) {
            headers.set('Cookie', cookieHeader);
        }

        const fetchOptions: RequestInit = {
            method: request.method,
            headers,
            ...(body && { body }),
        };

        console.log(`[Proxy] Fetching: ${BACKEND_URL}${targetPath}`);
        const response = await fetch(`${BACKEND_URL}${targetPath}`, fetchOptions);
        console.log(`[Proxy] Response status: ${response.status}, has set-cookie: ${response.headers.has('set-cookie')}`);

        // Read body as buffer to avoid streaming issues
        // Handle 204 No Content specially - don't try to read body
        let proxyResponse: NextResponse;
        if (response.status === 204) {
            proxyResponse = new NextResponse(null, { status: 204 });
        } else {
            const responseBody = await response.arrayBuffer();
            proxyResponse = new NextResponse(responseBody, { status: response.status });
        }

        // Copy headers (preserve set-cookie, skip encoding headers since fetch() auto-decompresses)
        const skipHeaders = new Set(['set-cookie', 'content-encoding', 'content-length', 'transfer-encoding']);
        response.headers.forEach((value, key) => {
            if (!skipHeaders.has(key.toLowerCase())) {
                proxyResponse.headers.set(key, value);
            }
        });

        // Forward set-cookie headers individually (must not be joined)
        const setCookies = (response.headers as any).getSetCookie?.();
        if (setCookies && setCookies.length > 0) {
            setCookies.forEach((cookie: string) => proxyResponse.headers.append('set-cookie', cookie));
        } else {
            // Fallback: parse joined set-cookie header back into individual cookies
            const setCookie = response.headers.get('set-cookie');
            if (setCookie) {
                // Split on comma followed by a cookie name (word=), avoiding splitting on expires date commas
                const cookies = setCookie.split(/,\s*(?=[a-zA-Z_]+=)/);
                cookies.forEach((cookie: string) => proxyResponse.headers.append('set-cookie', cookie.trim()));
            }
        }

        return proxyResponse;
    } catch (error) {
        console.error(`[Proxy] Error for ${targetPath}:`, error);
        return NextResponse.json(
            { detail: 'Backend connection failed' },
            { status: 503 }
        );
    }
}

export { proxyRequest, BACKEND_URL };
