import { NextFunction, Request, Response } from "express";
import multer from "multer";

const ALLOWED_MIME_TYPES = new Set([
  "image/jpeg",
  "image/png",
  "image/webp",
  "image/gif",
  "image/heic",
  "image/heif",
  // SVGs can embed <script>/event-handler content — fine for icons an admin
  // uploads intentionally (this endpoint is requireAdmin-gated), but don't
  // widen this allowlist to any public-facing upload without sanitizing.
  "image/svg+xml",
]);

const MAX_FILE_SIZE_BYTES = 10 * 1024 * 1024; // 10MB per file

// Shared multer config for every endpoint that accepts product/store
// images. Without a fileFilter + limits, multer happily accepts any file
// type or size straight through to S3 — this restricts uploads to actual
// images and caps size so the bucket can't be used to host arbitrary
// files or be hit with oversized uploads.
export const imageUpload = multer({
  storage: multer.memoryStorage(),
  limits: { fileSize: MAX_FILE_SIZE_BYTES },
  fileFilter: (_req, file, cb) => {
    if (!ALLOWED_MIME_TYPES.has(file.mimetype)) {
      cb(new Error("Only image files (JPEG, PNG, WEBP, GIF, HEIC) are allowed"));
      return;
    }
    cb(null, true);
  },
});

// Without this, a rejected file (wrong type / too large) crashes through to
// Express's default HTML error page instead of a clean JSON response.
export function handleUploadErrors(
  err: unknown,
  _req: Request,
  res: Response,
  next: NextFunction,
) {
  if (err instanceof multer.MulterError) {
    const message =
      err.code === "LIMIT_FILE_SIZE"
        ? "File is too large. Maximum size is 10MB."
        : err.message;
    return res.status(400).json({ message });
  }
  if (err instanceof Error) {
    return res.status(400).json({ message: err.message });
  }
  next(err);
}
