/**
 * API Proxy Route
 * 
 * Forwards requests to external APIs to bypass CORS restrictions
 * and ensure auth headers are sent properly.
 */

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

// Headers that should not be forwarded
const EXCLUDED_REQUEST_HEADERS = [
  'host',
  'connection',
  'content-length',
  'transfer-encoding',
  'keep-alive',
  'upgrade',
  'proxy-connection',
  'proxy-authorization',
]

const EXCLUDED_RESPONSE_HEADERS = [
  'transfer-encoding',
  'connection',
  'keep-alive',
  'content-encoding',
]

export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    
    const { url, method, headers, requestBody } = body as {
      url: string
      method: string
      headers: Record<string, string>
      requestBody?: string | null
    }

    if (!url) {
      return NextResponse.json(
        { error: 'URL is required' },
        { status: 400 }
      )
    }

    // Validate URL to prevent SSRF attacks
    const parsedUrl = new URL(url)
    const allowedProtocols = ['http:', 'https:']
    if (!allowedProtocols.includes(parsedUrl.protocol)) {
      return NextResponse.json(
        { error: 'Invalid URL protocol' },
        { status: 400 }
      )
    }

    // Build headers for the proxied request
    const proxyHeaders: Record<string, string> = {}
    for (const [key, value] of Object.entries(headers || {})) {
      if (!EXCLUDED_REQUEST_HEADERS.includes(key.toLowerCase())) {
        proxyHeaders[key] = value
      }
    }

    // Make the proxied request
    const startTime = Date.now()
    const response = await fetch(url, {
      method: method || 'GET',
      headers: proxyHeaders,
      body: requestBody || undefined,
    })
    const responseTime = Date.now() - startTime

    // Read response body
    const contentType = response.headers.get('content-type') || ''
    let responseBody: string | null = null
    
    if (contentType.includes('application/json') || contentType.includes('text/')) {
      responseBody = await response.text()
    } else {
      // For binary content, convert to base64
      const buffer = await response.arrayBuffer()
      responseBody = Buffer.from(buffer).toString('base64')
    }

    // Build response headers
    const responseHeaders: Record<string, string> = {}
    response.headers.forEach((value, key) => {
      if (!EXCLUDED_RESPONSE_HEADERS.includes(key.toLowerCase())) {
        responseHeaders[key] = value
      }
    })

    return NextResponse.json({
      status: response.status,
      statusText: response.statusText,
      headers: responseHeaders,
      body: responseBody,
      responseTime,
      size: responseBody ? new Blob([responseBody]).size : 0,
    })
  } catch (error) {
    return NextResponse.json({
      status: 0,
      statusText: 'Proxy Error',
      headers: {},
      body: null,
      responseTime: 0,
      size: 0,
      error: error instanceof Error ? error.message : 'Proxy request failed',
    })
  }
}

// Also support GET for simple requests
export async function GET(request: NextRequest) {
  const url = request.nextUrl.searchParams.get('url')
  
  if (!url) {
    return NextResponse.json(
      { error: 'URL query parameter is required' },
      { status: 400 }
    )
  }

  try {
    const parsedUrl = new URL(url)
    const allowedProtocols = ['http:', 'https:']
    if (!allowedProtocols.includes(parsedUrl.protocol)) {
      return NextResponse.json(
        { error: 'Invalid URL protocol' },
        { status: 400 }
      )
    }

    const response = await fetch(url)
    const body = await response.text()

    return NextResponse.json({
      status: response.status,
      statusText: response.statusText,
      body,
    })
  } catch (error) {
    return NextResponse.json({
      error: error instanceof Error ? error.message : 'Request failed',
    }, { status: 500 })
  }
}
