import fs from 'fs/promises'
import path from 'path'
import sharp from 'sharp'
import { getUserFromToken, verifyToken } from '../../utils/auth.js'

// Handle both dev and production paths
// nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
// filename is always a hardcoded constant (e.g., 'galerie-metadata.json'), never user input
const getDataPath = (filename) => {
  const cwd = process.cwd()
  if (cwd.endsWith('.output')) {
    // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
    return path.join(cwd, '../server/data', filename)
  }
  // nosemgrep: javascript.lang.security.audit.path-traversal.path-join-resolve-traversal.path-join-resolve-traversal
  return path.join(cwd, 'server/data', filename)
}

const GALERIE_DIR = getDataPath('galerie')
const GALERIE_METADATA = getDataPath('galerie-metadata.json')

async function readGalerieMetadata() {
  try {
    const data = await fs.readFile(GALERIE_METADATA, 'utf-8')
    return JSON.parse(data)
  } catch (error) {
    if (error.code === 'ENOENT') {
      return []
    }
    throw error
  }
}

export default defineEventHandler(async (event) => {
  try {
    const imageId = getRouterParam(event, 'id')
    const query = getQuery(event)
    const isPreview = query.preview === 'true'

    if (!imageId) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Bild-ID erforderlich'
      })
    }

    // Prüfe ob Benutzer eingeloggt ist
    let isLoggedIn = false
    const token = getCookie(event, 'auth_token') || getHeader(event, 'authorization')?.replace('Bearer ', '')
    
    if (token) {
      const decoded = verifyToken(token)
      if (decoded) {
        const user = await getUserFromToken(token)
        if (user && user.active) {
          isLoggedIn = true
        }
      }
    }

    const metadata = await readGalerieMetadata()
    const image = metadata.find(img => img.id === imageId)

    if (!image) {
      throw createError({
        statusCode: 404,
        statusMessage: 'Bild nicht gefunden'
      })
    }

    // Prüfe Zugriffsberechtigung
    if (!image.isPublic && !isLoggedIn) {
      throw createError({
        statusCode: 403,
        statusMessage: 'Keine Berechtigung zum Anzeigen dieses Bildes'
      })
    }

    // Bestimme Dateipfad
    const filename = isPreview ? image.previewFilename : image.filename
    
    // Validiere Dateiname gegen Path-Traversal
    if (!filename || typeof filename !== 'string') {
      throw createError({
        statusCode: 400,
        statusMessage: 'Ungültiger Dateiname'
      })
    }
    
    // Sanitize filename
    const sanitizedFilename = path.basename(path.normalize(filename))
    if (sanitizedFilename.includes('..') || sanitizedFilename.startsWith('/') || sanitizedFilename.startsWith('\\')) {
      throw createError({
        statusCode: 400,
        statusMessage: 'Ungültiger Dateiname'
      })
    }
    
    const subdir = isPreview ? 'previews' : 'originals'
    const filePath = path.join(GALERIE_DIR, subdir, sanitizedFilename)

    // Prüfe ob Datei existiert
    try {
      await fs.access(filePath)
    } catch {
      throw createError({
        statusCode: 404,
        statusMessage: 'Bilddatei nicht gefunden'
      })
    }

    // Bestimme MIME-Type
    const ext = path.extname(filename).toLowerCase()
    const mimeTypes = {
      '.jpg': 'image/jpeg',
      '.jpeg': 'image/jpeg',
      '.png': 'image/png',
      '.gif': 'image/gif',
      '.webp': 'image/webp'
    }
    const contentType = mimeTypes[ext] || 'application/octet-stream'

    // Datei lesen und EXIF-Orientierung korrigieren
    const imageBuffer = await fs.readFile(filePath)
    const correctedBuffer = await sharp(imageBuffer)
      .rotate() // Korrigiert automatisch EXIF-Orientierung
      .toBuffer()
    
    setHeader(event, 'Content-Type', contentType)
    setHeader(event, 'Cache-Control', 'public, max-age=31536000')
    
    return correctedBuffer

  } catch (error) {
    console.error('Fehler beim Laden des Bildes:', error)
    
    if (error.statusCode) {
      throw error
    }
    
    throw createError({
      statusCode: 500,
      statusMessage: 'Fehler beim Laden des Bildes'
    })
  }
})

