import { S3Client, PutObjectCommand } from '@aws-sdk/client-s3'
import { NextRequest, NextResponse } from 'next/server'

const s3Client = new S3Client({
  region: 'ru-1',
  endpoint: 'https://s3.twcstorage.ru',
  credentials: {
    accessKeyId: 'I6XD2OR7YO2ZN6L6Z629',
    secretAccessKey: '9xCOoafisG0aB9lJNvdLO1UuK73fBvMcpHMdijrJ',
  },
  forcePathStyle: true,
})

const BUCKET_NAME = '617774af-sfera'

// Разрешенные типы файлов
const ALLOWED_IMAGE_TYPES = ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/gif']

const ALLOWED_FILE_TYPES = [
  'application/pdf',
  'application/msword',
  'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
  'application/vnd.ms-excel',
  'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
  'application/vnd.ms-powerpoint',
  'application/vnd.openxmlformats-officedocument.presentationml.presentation',
  'text/plain',
  'application/zip',
  'application/x-zip-compressed',
  'application/json',
]

export async function POST(request: NextRequest) {
  try {
    const formData = await request.formData()
    const file = formData.get('file') as File
    const userId = formData.get('userId') as string
    const messageType = formData.get('messageType') as string // 'IMAGE' или 'FILE'
    const type = formData.get('type') as string // Для товаров: 'product'

    // Проверяем параметры в зависимости от типа загрузки
    if (type === 'product') {
      // Для товаров нужен только файл
      if (!file) {
        return NextResponse.json({ error: 'File is required' }, { status: 400 })
      }
    } else {
      // Для мессенджера нужны все параметры
      if (!file || !userId || !messageType) {
        return NextResponse.json({ error: 'File, userId and messageType are required' }, { status: 400 })
      }
    }

    // Проверяем, что файл не пустой
    if (file.size === 0) {
      return NextResponse.json({ error: 'File is empty' }, { status: 400 })
    }

    // Проверяем имя файла
    if (!file.name || file.name.trim().length === 0) {
      return NextResponse.json({ error: 'Invalid file name' }, { status: 400 })
    }

    // Проверяем тип файла в зависимости от типа загрузки
    const isImage = type === 'product' || messageType === 'IMAGE'
    const allowedTypes = isImage ? ALLOWED_IMAGE_TYPES : [...ALLOWED_IMAGE_TYPES, ...ALLOWED_FILE_TYPES]

    if (!allowedTypes.includes(file.type)) {
      return NextResponse.json({ error: `File type ${file.type} is not allowed` }, { status: 400 })
    }

    // Ограничиваем размер файла
    const maxSize = isImage ? 10 * 1024 * 1024 : 50 * 1024 * 1024 // 10MB для изображений, 50MB для файлов
    if (file.size > maxSize) {
      const maxSizeMB = maxSize / (1024 * 1024)
      return NextResponse.json({ error: `File size must be less than ${maxSizeMB}MB` }, { status: 400 })
    }

    // Генерируем уникальное имя файла
    const timestamp = Date.now()
    // Более безопасная очистка имени файла
    const safeFileName = file.name
      .replace(/[^\w\s.-]/g, '_') // Заменяем недопустимые символы
      .replace(/\s+/g, '_') // Заменяем пробелы на подчеркивания
      .replace(/_{2,}/g, '_') // Убираем множественные подчеркивания
      .toLowerCase() // Приводим к нижнему регистру

    // Определяем папку и ключ в зависимости от типа загрузки
    let folder: string
    let key: string

    if (type === 'product') {
      folder = 'products'
      key = `${folder}/${timestamp}-${safeFileName}`
    } else {
      folder = isImage ? 'images' : 'files'
      key = `${folder}/${userId}/${timestamp}-${safeFileName}`
    }

    // Конвертируем файл в Buffer
    const buffer = Buffer.from(await file.arrayBuffer())

    // Очищаем метаданные от недопустимых символов
    const cleanOriginalName = file.name.replace(/[^\w\s.-]/g, '_')

    // Подготавливаем метаданные в зависимости от типа загрузки
    let metadata: Record<string, string>

    if (type === 'product') {
      metadata = {
        originalname: cleanOriginalName,
        uploadtype: 'product',
      }
    } else {
      const cleanUserId = userId.replace(/[^\w-]/g, '')
      const cleanMessageType = messageType.replace(/[^\w]/g, '')
      metadata = {
        originalname: cleanOriginalName,
        uploadedby: cleanUserId,
        messagetype: cleanMessageType,
      }
    }

    // Загружаем в S3
    const command = new PutObjectCommand({
      Bucket: BUCKET_NAME,
      Key: key,
      Body: buffer,
      ContentType: file.type,
      ACL: 'public-read',
      Metadata: metadata,
    })

    await s3Client.send(command)

    // Возвращаем URL файла и метаданные
    const url = `https://s3.twcstorage.ru/${BUCKET_NAME}/${key}`

    const response: Record<string, unknown> = {
      success: true,
      fileUrl: url, // Изменяем на fileUrl для совместимости с формой товаров
      url, // Оставляем для совместимости с мессенджером
      key,
      originalName: file.name,
      size: file.size,
      type: file.type,
    }

    // Добавляем messageType только для мессенджера
    if (messageType) {
      response.messageType = messageType
    }

    return NextResponse.json(response)
  } catch (error) {
    console.error('Error uploading file:', error)

    // Логируем детали ошибки
    if (error instanceof Error) {
      console.error('Error message:', error.message)
      console.error('Error stack:', error.stack)
    }

    let errorMessage = 'Failed to upload file'
    if (error instanceof Error) {
      // Проверяем специфичные ошибки
      if (error.message.includes('Invalid character in header')) {
        errorMessage = 'Invalid characters in file name or metadata'
      } else if (error.message.includes('AccessDenied')) {
        errorMessage = 'Access denied to storage'
      } else if (error.message.includes('NoSuchBucket')) {
        errorMessage = 'Storage bucket not found'
      } else {
        errorMessage = error.message
      }
    }

    return NextResponse.json({ error: errorMessage, success: false }, { status: 500 })
  }
}
