import { NextRequest, NextResponse } from 'next/server'
import { 
  storeProjectContent, 
  updateProjectContent,
  projectExists,
  generateProjectSlug,
  generateApiKey,
  storeProjectApiKey,
  validateApiKey,
  getProjectApiKey,
  type ProjectFile 
} from '@/lib/storage/blob'
import { getProjectUrl, isValidSlug } from '@/lib/multi-tenant/context'

/**
 * Deploy API - receives content from CLI and stores in Vercel Blob
 * 
 * POST /api/deploy
 * Headers:
 *   Authorization: Bearer <api_key>  // Required for updates
 * Body: {
 *   name: string,           // Project name from docs.json
 *   slug?: string,          // Optional: existing slug for updates
 *   docsJson: object,       // The docs.json configuration
 *   files: Array<{          // MDX and other content files
 *     path: string,
 *     content: string
 *   }>
 * }
 */
export async function POST(request: NextRequest) {
  try {
    const body = await request.json()
    
    // Validate request body
    const { name, slug: existingSlug, docsJson, files } = body
    
    if (!name || typeof name !== 'string') {
      return NextResponse.json(
        { error: 'Missing or invalid project name' },
        { status: 400 }
      )
    }
    
    if (!docsJson || typeof docsJson !== 'object') {
      return NextResponse.json(
        { error: 'Missing or invalid docs.json configuration' },
        { status: 400 }
      )
    }
    
    if (!files || !Array.isArray(files)) {
      return NextResponse.json(
        { error: 'Missing or invalid files array' },
        { status: 400 }
      )
    }
    
    // Validate files structure
    const validFiles: ProjectFile[] = []
    for (const file of files) {
      if (!file.path || typeof file.path !== 'string') {
        return NextResponse.json(
          { error: `Invalid file entry: missing path` },
          { status: 400 }
        )
      }
      if (typeof file.content !== 'string') {
        return NextResponse.json(
          { error: `Invalid file entry for ${file.path}: content must be a string` },
          { status: 400 }
        )
      }
      validFiles.push({
        path: file.path,
        content: file.content,
      })
    }
    
    let slug: string
    let isUpdate = false
    let apiKey: string | null = null
    
    // Check if this is an update to an existing project
    if (existingSlug) {
      if (!isValidSlug(existingSlug)) {
        return NextResponse.json(
          { error: 'Invalid project slug format' },
          { status: 400 }
        )
      }
      
      const exists = await projectExists(existingSlug)
      if (!exists) {
        return NextResponse.json(
          { error: `Project with slug "${existingSlug}" not found` },
          { status: 404 }
        )
      }
      
      // For updates, validate API key
      const authHeader = request.headers.get('Authorization')
      const providedKey = authHeader?.replace('Bearer ', '') || body.apiKey
      
      if (!providedKey) {
        return NextResponse.json(
          { error: 'API key required for project updates. Provide via Authorization header or apiKey field.' },
          { status: 401 }
        )
      }
      
      const validatedSlug = await validateApiKey(providedKey)
      if (validatedSlug !== existingSlug) {
        return NextResponse.json(
          { error: 'Invalid API key for this project' },
          { status: 403 }
        )
      }
      
      slug = existingSlug
      isUpdate = true
    } else {
      // Generate a new unique slug
      slug = generateProjectSlug(name)
      
      // Ensure it doesn't already exist (very unlikely but possible)
      let attempts = 0
      while (await projectExists(slug) && attempts < 5) {
        slug = generateProjectSlug(name)
        attempts++
      }
      
      if (attempts >= 5) {
        return NextResponse.json(
          { error: 'Failed to generate unique project slug' },
          { status: 500 }
        )
      }
      
      // Generate API key for new project
      apiKey = generateApiKey()
    }
    
    // Store or update content
    let result
    if (isUpdate) {
      result = await updateProjectContent(slug, docsJson, validFiles)
    } else {
      result = await storeProjectContent(slug, name, docsJson, validFiles)
      // Store the API key for new projects
      if (apiKey) {
        await storeProjectApiKey(slug, apiKey)
      }
    }
    
    // Build response
    const projectUrl = getProjectUrl(slug)
    
    // For new projects, include the API key in response
    const response: {
      success: boolean
      slug: string
      url: string
      blobUrl: string
      isUpdate: boolean
      filesCount: number
      apiKey?: string
    } = {
      success: true,
      slug,
      url: projectUrl,
      blobUrl: result.url,
      isUpdate,
      filesCount: validFiles.length,
    }
    
    if (apiKey) {
      response.apiKey = apiKey
    }
    
    return NextResponse.json(response)
    
  } catch (error) {
    console.error('[Deploy API] Error:', error)
    const message = error instanceof Error ? error.message : String(error)
    
    // Provide clearer error messages for common issues
    let userMessage = 'Deployment failed'
    if (message.includes('blob already exists')) {
      userMessage = 'Storage conflict - please try again'
    } else if (message.includes('network') || message.includes('fetch')) {
      userMessage = 'Network error connecting to storage'
    } else if (message.includes('unauthorized') || message.includes('401')) {
      userMessage = 'Authentication failed'
    }
    
    return NextResponse.json(
      { error: userMessage, details: message },
      { status: 500 }
    )
  }
}

/**
 * GET /api/deploy - Check deployment status or get project info
 */
export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url)
  const slug = searchParams.get('slug')
  
  if (!slug) {
    return NextResponse.json(
      { error: 'Missing slug parameter' },
      { status: 400 }
    )
  }
  
  const exists = await projectExists(slug)
  
  if (!exists) {
    return NextResponse.json(
      { exists: false, slug },
      { status: 404 }
    )
  }
  
  const projectUrl = getProjectUrl(slug)
  
  return NextResponse.json({
    exists: true,
    slug,
    url: projectUrl,
  })
}
