import { NextResponse } from 'next/server'
import { requireAdmin } from '@/lib/auth'
import { validateUpdatePackage, ensureDirectories } from '@/lib/update-system'
import { prisma } from '@/lib/db'
import fs from 'fs/promises'
import path from 'path'

// Store for update progress (in production, use Redis or similar)
const updateProgress = new Map<string, {
  phase: string
  progress: number
  message: string
  details?: string
  buffer?: Buffer
  manifest?: Record<string, unknown>
}>()

// Store update package temporarily
async function storeUpdatePackage(updateId: string, buffer: Buffer): Promise<void> {
  await ensureDirectories()
  const updatePath = path.join(process.cwd(), 'temp', `update-${updateId}.zip`)
  await fs.writeFile(updatePath, buffer)
}

export { updateProgress }

export async function POST(request: Request) {
  try {
    const adminCheck = await requireAdmin()
    if (adminCheck) return adminCheck

    const url = new URL(request.url)
    const updateId = url.searchParams.get('updateId')

    if (!updateId) {
      return NextResponse.json({ error: 'Update ID required' }, { status: 400 })
    }

    const formData = await request.formData()
    const file = formData.get('file') as File

    if (!file) {
      return NextResponse.json({ error: 'No file provided' }, { status: 400 })
    }

    // Initialize progress
    updateProgress.set(updateId, {
      phase: 'uploading',
      progress: 10,
      message: 'Receiving file...'
    })

    const arrayBuffer = await file.arrayBuffer()
    const buffer = Buffer.from(arrayBuffer)

    updateProgress.set(updateId, {
      phase: 'validating',
      progress: 20,
      message: 'Validating package...'
    })

    // Validate the package
    const validation = await validateUpdatePackage(buffer)

    if (!validation.valid) {
      const errorMessage = validation.errors.join(', ') || 'Invalid package'
      updateProgress.set(updateId, {
        phase: 'error',
        progress: 0,
        message: errorMessage
      })
      return NextResponse.json({ error: errorMessage }, { status: 400 })
    }

    // Check version compatibility
    const settings = await prisma.panelSettings.findFirst()
    const currentVersion = settings?.currentVersion || '1.0.0'

    if (validation.manifest?.minVersion) {
      const minParts = validation.manifest.minVersion.split('.').map(Number)
      const currentParts = currentVersion.split('.').map(Number)
      
      for (let i = 0; i < 3; i++) {
        if (currentParts[i] < minParts[i]) {
          updateProgress.set(updateId, {
            phase: 'error',
            progress: 0,
            message: `This update requires version ${validation.manifest.minVersion} or higher. Current version: ${currentVersion}`
          })
          return NextResponse.json(
            { error: `Requires version ${validation.manifest.minVersion}+` },
            { status: 400 }
          )
        }
        if (currentParts[i] > minParts[i]) break
      }
    }

    // Store the buffer and manifest for the apply step
    updateProgress.set(updateId, {
      phase: 'validating',
      progress: 30,
      message: 'Package validated successfully',
      buffer,
      manifest: validation.manifest
    })

    // Store the package temporarily
    await storeUpdatePackage(updateId, buffer)

    return NextResponse.json({ 
      success: true, 
      updateId,
      manifest: validation.manifest 
    })
  } catch (error) {
    console.error('Upload failed:', error)
    return NextResponse.json(
      { error: 'Upload failed' },
      { status: 500 }
    )
  }
}
