import { d as defineEventHandler, r as requireAuth, bT as requirePermission, g as getHeader, c as createError, eF as readMultipartFormData, bo as getStorageProvider, G as createContentManager, bN as dbQueryOne, as as config, eX as emitMediaUpload } from '../../nitro/nitro.mjs';
import { p as parseNullablePositiveInt } from '../../_/ids.mjs';
import { a as isProcessableImage, n as normalizeImage, c as getImageMetadata, g as generateMediaVariants } from '../../_/media-variants.mjs';
import { e as enrichMediaDeliveryRecord } from '../../_/media-delivery.mjs';
import { g as getAuditActorFromEvent } from '../../_/audit-log-actor.mjs';
import { d as detectUploadMimeType, a as assertUploadFileAccepted } from '../../_/media-upload-validation.mjs';
import 'node:crypto';
import 'jsonwebtoken';
import 'node:fs';
import 'node:module';
import 'node:path';
import 'node:url';
import 'node:http';
import 'node:https';
import 'node:events';
import 'node:buffer';
import 'pino';
import 'drizzle-orm/better-sqlite3';
import 'drizzle-orm/node-postgres';
import 'drizzle-orm/mysql2';
import 'better-sqlite3';
import 'pg';
import 'mysql2/promise';
import 'drizzle-orm';
import 'fs';
import 'path';
import 'prom-client';
import 'bcryptjs';
import '@node-rs/argon2';
import 'node:async_hooks';
import 'crypto';
import 'node:dns';
import 'node:util';
import 'node:net';
import 'fs/promises';
import 'url';
import 'semver';
import 'sharp';

const upload_post = defineEventHandler(async (event) => {
  var _a;
  try {
    await requireAuth(event);
    await requirePermission(
      event.context.user,
      "media",
      "create",
      event.context.adminUser,
      event.context.apiToken
    );
    const contentType = getHeader(event, "content-type") || "";
    const contentLength = getHeader(event, "content-length") || "0";
    console.log("[Upload] Request received:", {
      contentType,
      contentLength,
      method: event.method
    });
    if (!contentType.includes("multipart/form-data")) {
      console.error("[Upload] Invalid content-type:", contentType);
      throw createError({
        statusCode: 400,
        statusMessage: "Bad Request",
        message: `Invalid content-type. Expected multipart/form-data, got: ${contentType}`
      });
    }
    let formData = void 0;
    try {
      formData = await readMultipartFormData(event);
      console.log("[Upload] Form data parsed:", {
        hasData: !!formData,
        partsCount: (formData == null ? void 0 : formData.length) || 0,
        parts: formData == null ? void 0 : formData.map((p) => {
          var _a2;
          return {
            name: p.name,
            filename: p.filename,
            dataLength: (_a2 = p.data) == null ? void 0 : _a2.length
          };
        })
      });
    } catch (parseError) {
      console.error("[Upload] Failed to parse multipart:", parseError);
      throw createError({
        statusCode: 400,
        statusMessage: "Bad Request",
        message: `Failed to parse multipart data: ${parseError instanceof Error ? parseError.message : "Unknown error"}`
      });
    }
    if (!formData || formData.length === 0) {
      console.error(
        "[Upload] No form data received. Content-type:",
        contentType,
        "Content-length:",
        contentLength
      );
      throw createError({
        statusCode: 400,
        statusMessage: "Bad Request",
        message: `No files uploaded. Content-Type: ${contentType}, Content-Length: ${contentLength}`
      });
    }
    const uploadedFiles = [];
    const storage = getStorageProvider();
    const mediaManager = createContentManager("media");
    const actor = getAuditActorFromEvent(event);
    let folderId = null;
    for (const part of formData) {
      if (part.name === "folderId" && !part.filename && part.data) {
        const parsedFolderId = parseNullablePositiveInt(part.data.toString());
        if (!parsedFolderId.valid) {
          throw createError({
            statusCode: 400,
            statusMessage: "Bad Request",
            message: "Invalid folder ID"
          });
        }
        folderId = parsedFolderId.value;
      }
    }
    if (folderId !== null) {
      const folder = await dbQueryOne(`SELECT id FROM media_folders WHERE id = ?`, [folderId]);
      if (!folder) {
        throw createError({
          statusCode: 404,
          statusMessage: "Not Found",
          message: `Folder with ID ${folderId} not found`
        });
      }
    }
    const maxUploadSize = config.get("media.maxUploadSize", 10 * 1024 * 1024);
    const allowedFileTypes = config.get("media.allowedMimeTypes", []);
    const uploadParts = formData.flatMap((part) => {
      if (!part.filename || !part.data) {
        return [];
      }
      return [
        {
          data: part.data,
          filename: String(part.filename),
          mimeType: detectUploadMimeType(String(part.filename))
        }
      ];
    });
    if (uploadParts.length === 0) {
      throw createError({
        statusCode: 400,
        statusMessage: "Bad Request",
        message: "No valid files found in request"
      });
    }
    for (const part of uploadParts) {
      assertUploadFileAccepted({
        allowedMimeTypes: allowedFileTypes,
        filename: part.filename,
        maxUploadSize,
        mimeType: part.mimeType,
        size: part.data.length
      });
    }
    for (const part of uploadParts) {
      const { filename, mimeType } = part;
      let fileBuffer = part.data;
      if (isProcessableImage(mimeType)) {
        try {
          fileBuffer = await normalizeImage(part.data);
        } catch {
          fileBuffer = part.data;
        }
      }
      const uploadedFile = await storage.upload(fileBuffer, {
        filename,
        mimeType,
        allowedMimeTypes: allowedFileTypes,
        maxSize: maxUploadSize
      });
      const mediaData = {
        filename: uploadedFile.filename,
        originalName: uploadedFile.originalName,
        mimeType,
        size: uploadedFile.size,
        path: uploadedFile.path,
        url: uploadedFile.url,
        storageProvider: storage.getType()
      };
      if (folderId !== null) {
        mediaData.folder = folderId;
      }
      if (isProcessableImage(mimeType)) {
        try {
          const imageMeta = await getImageMetadata(fileBuffer);
          mediaData.width = imageMeta.width;
          mediaData.height = imageMeta.height;
        } catch {
        }
      }
      try {
        const formats = await generateMediaVariants(fileBuffer, uploadedFile.path, mimeType);
        if (formats) {
          mediaData.formats = formats;
        }
      } catch (variantError) {
        console.warn(
          `[Upload] Failed to generate variants for ${filename}:`,
          variantError instanceof Error ? variantError.message : variantError
        );
      }
      const createdMediaRecord = await mediaManager.create(mediaData, { actor });
      const mediaRecord = await enrichMediaDeliveryRecord(createdMediaRecord);
      if (mediaRecord.url !== createdMediaRecord.url) {
        await mediaManager.update(
          Number(createdMediaRecord.id),
          { url: mediaRecord.url },
          void 0,
          { actor }
        );
      }
      uploadedFiles.push(mediaRecord);
      await emitMediaUpload(
        mediaRecord,
        {
          filename,
          mimeType,
          size: uploadedFile.size,
          path: uploadedFile.path,
          url: String((_a = mediaRecord.url) != null ? _a : uploadedFile.url),
          storageProvider: storage.getType()
        },
        actor
      );
    }
    return {
      success: true,
      data: uploadedFiles
    };
  } catch (error) {
    if (error && typeof error === "object" && "statusCode" in error) {
      throw error;
    }
    if (error instanceof Error && error.message.includes("Authentication required")) {
      throw createError({
        statusCode: 401,
        statusMessage: "Unauthorized",
        message: error.message
      });
    }
    if (error instanceof Error && error.message.includes("Permission denied")) {
      throw createError({
        statusCode: 403,
        statusMessage: "Forbidden",
        message: error.message
      });
    }
    console.error("Upload error:", error);
    throw createError({
      statusCode: 500,
      statusMessage: "Internal Server Error",
      message: error instanceof Error ? error.message : "Failed to upload file"
    });
  }
});

export { upload_post as default };
//# sourceMappingURL=upload.post.mjs.map
