/**
 * API endpoint para subir avatar del usuario
 * POST /api/avatar/upload
 *
 * Recibe una imagen, la guarda en /public/avatars/ y actualiza Authentik
 */
import { promises as fs } from 'fs'
import { join } from 'path'
import { createHash } from 'crypto'

const MAX_FILE_SIZE = 5 * 1024 * 1024 // 5MB
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'image/webp']
const AVATARS_DIR = 'public/avatars'

export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig()
  const headers = getRequestHeaders(event)

  // Verificar autenticación
  const username = headers['x-authentik-username']
  if (!username) {
    throw createError({
      statusCode: 401,
      message: 'Usuario no autenticado'
    })
  }

  try {
    // Leer el body como multipart/form-data
    const formData = await readMultipartFormData(event)

    if (!formData || formData.length === 0) {
      throw createError({
        statusCode: 400,
        message: 'No se recibió ningún archivo'
      })
    }

    // Buscar el campo 'avatar'
    const avatarFile = formData.find(field => field.name === 'avatar')

    if (!avatarFile) {
      throw createError({
        statusCode: 400,
        message: 'Campo "avatar" no encontrado'
      })
    }

    // Validar tipo de archivo
    const contentType = avatarFile.type || ''
    if (!ALLOWED_TYPES.includes(contentType)) {
      throw createError({
        statusCode: 400,
        message: `Tipo de archivo no permitido. Usa: ${ALLOWED_TYPES.join(', ')}`
      })
    }

    // Validar tamaño
    if (avatarFile.data.length > MAX_FILE_SIZE) {
      throw createError({
        statusCode: 400,
        message: `Archivo muy grande. Máximo: ${MAX_FILE_SIZE / (1024 * 1024)}MB`
      })
    }

    // Crear directorio de avatares si no existe
    const avatarsPath = join(process.cwd(), AVATARS_DIR)
    try {
      await fs.access(avatarsPath)
    } catch {
      await fs.mkdir(avatarsPath, { recursive: true })
    }

    // Generar nombre de archivo único basado en username
    const hash = createHash('md5').update(username).digest('hex').substring(0, 8)
    const timestamp = Date.now()
    const extension = contentType.split('/')[1]
    const filename = `${username}-${hash}-${timestamp}.${extension}`
    const filepath = join(avatarsPath, filename)

    // Guardar archivo
    await fs.writeFile(filepath, avatarFile.data)

    // URL pública del avatar
    const avatarUrl = `/avatars/${filename}`

    // Actualizar Authentik con la URL del avatar
    const authentikUrl = config.authentikApiUrl || config.public.authentikUrl
    const authentikToken = config.authentikApiToken

    if (!authentikToken) {
      console.warn('⚠️ Token de Authentik no configurado, no se puede actualizar metadatos')
    } else {
      try {
        // Obtener ID del usuario
        const usersResponse = await $fetch(`${authentikUrl}/api/v3/core/users/?username=${username}`, {
          headers: {
            'Authorization': `Bearer ${authentikToken}`,
            'Content-Type': 'application/json'
          }
        })

        const users = usersResponse as any
        if (users.results && users.results.length > 0) {
          const userId = users.results[0].pk

          // Actualizar atributos del usuario
          await $fetch(`${authentikUrl}/api/v3/core/users/${userId}/`, {
            method: 'PATCH',
            headers: {
              'Authorization': `Bearer ${authentikToken}`,
              'Content-Type': 'application/json'
            },
            body: {
              attributes: {
                ...users.results[0].attributes,
                avatar_url: avatarUrl
              }
            }
          })

          console.log(`✅ Avatar actualizado para usuario ${username}: ${avatarUrl}`)
        }
      } catch (err) {
        console.error('Error actualizando Authentik:', err)
        // No fallar si Authentik no se puede actualizar, el avatar ya está guardado
      }
    }

    // Limpiar avatares antiguos del usuario (opcional)
    try {
      const files = await fs.readdir(avatarsPath)
      const userFiles = files.filter(f =>
        f.startsWith(`${username}-`) &&
        f !== filename
      )

      for (const oldFile of userFiles) {
        await fs.unlink(join(avatarsPath, oldFile))
        console.log(`🗑️  Eliminado avatar antiguo: ${oldFile}`)
      }
    } catch (err) {
      console.error('Error limpiando avatares antiguos:', err)
    }

    return {
      success: true,
      avatarUrl,
      message: 'Avatar actualizado correctamente'
    }
  } catch (error: any) {
    console.error('Error en upload de avatar:', error)

    // Re-throw si ya es un error de createError
    if (error.statusCode) {
      throw error
    }

    throw createError({
      statusCode: 500,
      message: error.message || 'Error al subir avatar'
    })
  }
})
