import { NextRequest, NextResponse } from 'next/server'
import { readFile, stat } from 'fs/promises'
import { join } from 'path'
import { existsSync } from 'fs'
import { verifyToken } from '@/lib/auth'

const PUBLIC_DIR = join(process.cwd(), 'public')

const MIME_TYPES: Record<string, string> = {
  '.jpg': 'image/jpeg',
  '.jpeg': 'image/jpeg',
  '.png': 'image/png',
  '.gif': 'image/gif',
  '.webp': 'image/webp',
  '.svg': 'image/svg+xml',
}

export async function GET(
  request: NextRequest,
  { params }: { params: Promise<{ path: string[] }> }
) {
  try {
    // Require authentication to access uploaded files
    // Support both Authorization header and token query parameter (for <img> tags)
    const authHeader = request.headers.get('Authorization')
    const queryToken = request.nextUrl.searchParams.get('token')
    let isAuthenticated = false

    if (authHeader?.startsWith('Bearer ')) {
      const token = authHeader.substring(7)
      const payload = await verifyToken(token)
      if (payload) isAuthenticated = true
    } else if (queryToken) {
      const payload = await verifyToken(queryToken)
      if (payload) isAuthenticated = true
    }

    if (!isAuthenticated) {
      return NextResponse.json({ error: 'No autorizado' }, { status: 401 })
    }

    const { path: pathSegments } = await params

    // Security: prevent directory traversal
    const safePath = pathSegments
      .map(segment => segment.replace(/\.\./g, '').replace(/\\/g, ''))
      .filter(Boolean)
      .join('/')

    if (!safePath) {
      return NextResponse.json({ error: 'Ruta inválida' }, { status: 400 })
    }

    const filePath = join(PUBLIC_DIR, safePath)

    // Security: ensure the resolved path is still within PUBLIC_DIR
    if (!filePath.startsWith(PUBLIC_DIR)) {
      return NextResponse.json({ error: 'Acceso denegado' }, { status: 403 })
    }

    if (!existsSync(filePath)) {
      return NextResponse.json({ error: 'Archivo no encontrado' }, { status: 404 })
    }

    const fileStat = await stat(filePath)

    // Don't serve directories
    if (!fileStat.isFile()) {
      return NextResponse.json({ error: 'No es un archivo' }, { status: 400 })
    }

    const fileBuffer = await readFile(filePath)

    // Determine content type from extension
    const ext = safePath.toLowerCase().match(/\.[^.]+$/)?.[0] || ''
    const contentType = MIME_TYPES[ext] || 'application/octet-stream'

    return new NextResponse(fileBuffer, {
      status: 200,
      headers: {
        'Content-Type': contentType,
        'Content-Length': fileStat.size.toString(),
        'Cache-Control': 'public, max-age=31536000, immutable',
      },
    })
  } catch (error) {
    console.error('Error al servir archivo:', error)
    return NextResponse.json(
      { error: 'Error interno del servidor' },
      { status: 500 }
    )
  }
}
