import { NextResponse } from 'next/server'
import { CacheUtils } from '@/lib/cache'

// Configuration - you can set these as environment variables
const BRAINFISH_API_BASE_URL = process.env.BRAINFISH_API_BASE_URL || 'https://api.brainfish.ai/api'
const BRAINFISH_CATALOG_ID = process.env.BRAINFISH_CATALOG_ID || 'your_catalog_id_here'
const BRAINFISH_JWT_TOKEN = process.env.BRAINFISH_JWT_TOKEN || 'your_jwt_token_here'

// Cache configuration
const CACHE_KEY = `openapi-spec-${BRAINFISH_CATALOG_ID}`
const CACHE_TTL = 60 * 5 // 5 minutes
const FALLBACK_CACHE_KEY = `${CACHE_KEY}-fallback`

interface OpenApiSpec {
  openapi: string;
  info: {
    title: string;
    version: string;
    description: string;
  };
  paths: Record<string, unknown>;
  servers: Array<{
    url: string;
    description: string;
  }>;
}

async function fetchOpenApiSpec(): Promise<OpenApiSpec> {
  // First, try to get from cache
  const cachedSpec = await CacheUtils.get<OpenApiSpec>(CACHE_KEY)
  if (cachedSpec) {
    return cachedSpec
  }

  // If not in cache, try to fetch from API
  try {
    // IMPORTANT: Use dots (.) not slashes (/) - e.g., catalogs.openapi-spec NOT catalogs/openapi-spec
    const url = `${BRAINFISH_API_BASE_URL}/catalogs.openapi-spec`
    
    console.log('[OpenAPI] Fetching from:', url)
    console.log('[OpenAPI] Request body:', { catalogId: BRAINFISH_CATALOG_ID })
    
    const response = await fetch(url, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${BRAINFISH_JWT_TOKEN}`,
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'User-Agent': 'Brainfish-API-Docs/1.0',
      },
      body: JSON.stringify({
        catalogId: BRAINFISH_CATALOG_ID
      }),
      // Ensure fetch doesn't cache
      cache: 'no-store',
    })

    console.log('[OpenAPI] Response status:', response.status, response.statusText)
    console.log('[OpenAPI] Response headers:', Object.fromEntries(response.headers.entries()))

    if (!response.ok) {
      // Try to get error details from response body
      let errorBody = ''
      try {
        errorBody = await response.text()
        console.log('[OpenAPI] Error response body:', errorBody)
      } catch {
        console.log('[OpenAPI] Could not read error response body')
      }
      
      throw new Error(`Failed to fetch OpenAPI spec: ${response.status} ${response.statusText}${errorBody ? ` - ${errorBody}` : ''}`)
    }

    const spec = await response.json() as OpenApiSpec
    
    // Cache the successful response
    await CacheUtils.set(CACHE_KEY, spec, CACHE_TTL)
    // Also store as fallback (with longer TTL)
    await CacheUtils.set(FALLBACK_CACHE_KEY, spec, 60 * 60 * 24 * 365)
    return spec
  } catch (error) {
    const errorMessage = error instanceof Error ? error.message : 'Unknown error'
    console.error('[OpenAPI] Error fetching spec:', errorMessage)
    
    // Try to get fallback from cache
    const fallbackSpec = await CacheUtils.get<OpenApiSpec>(FALLBACK_CACHE_KEY)
    if (fallbackSpec) {
      console.warn('[OpenAPI] Using fallback cache due to API error')
      return fallbackSpec
    }
    
    // If no fallback available, return basic spec
    console.warn('[OpenAPI] No fallback available, using basic spec')
    return {
      openapi: '3.0.0',
      info: {
        title: 'Brainfish API',
        version: '1.0.0',
        description: 'API temporarily unavailable. Please try again later.',
      },
      paths: {},
      servers: [
        {
          url: BRAINFISH_API_BASE_URL.replace('/api', ''),
          description: 'Brainfish API'
        }
      ]
    }
  }
}

export async function GET() {
  try {
    const spec = await fetchOpenApiSpec()
    
    return NextResponse.json(spec, {
      headers: {
        'Content-Type': 'application/json',
        'Cache-Control': 'no-cache, no-store, must-revalidate', // Disable browser caching
      },
    })
  } catch (error) {
    console.error('[OpenAPI] Unexpected error in endpoint:', error)
    
    // As a last resort, try the fallback cache
    const fallbackSpec = await CacheUtils.get<OpenApiSpec>(FALLBACK_CACHE_KEY)
    if (fallbackSpec) {
      console.warn('[OpenAPI] Using fallback cache in error handler')
      return NextResponse.json(fallbackSpec, {
        headers: {
          'Content-Type': 'application/json',
          'Cache-Control': 'no-cache, no-store, must-revalidate',
        },
      })
    }
    
    return NextResponse.json(
      { 
        error: 'OpenAPI specification temporarily unavailable',
        openapi: '3.0.0',
        info: {
          title: 'Brainfish API',
          version: '1.0.0',
          description: 'Service temporarily unavailable. Please try again later.',
        },
        paths: {},
      },
      { status: 503 } // Service Unavailable
    )
  }
}
