import { createHash } from "node:crypto";
import { PutObjectCommand, S3Client } from "@aws-sdk/client-s3";

export const runtime = "nodejs";

const ALLOWED_TYPES = new Set(["image/jpeg", "image/png", "image/webp", "image/heic", "image/heif"]);
const MAX_FILE_SIZE = 10 * 1024 * 1024;

function readS3Env() {
  return {
    region: process.env.S3_REGION || "",
    bucket: process.env.S3_BUCKET || "",
    fileUrl: process.env.S3_FILE_URL || "",
    prefix: process.env.S3_PREFIX || "uploads/",
    accessKeyId: process.env.S3_ACCESS_KEY_ID || "",
    secretAccessKey: process.env.S3_SECRET_ACCESS_KEY || "",
  };
}

function sanitizeSegment(value: string) {
  return value
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .replace(/[^a-z0-9]+/g, "-")
    .replace(/^-+|-+$/g, "") || "file";
}

function joinUrl(base: string, path: string) {
  return `${base.replace(/\/+$/, "")}/${path.replace(/^\/+/, "")}`;
}

function getExtension(file: File) {
  const name = file.name || "";
  const fromName = name.includes(".") ? name.split(".").pop() || "" : "";
  if (fromName) return sanitizeSegment(fromName);

  if (file.type === "image/png") return "png";
  if (file.type === "image/webp") return "webp";
  if (file.type === "image/heic") return "heic";
  if (file.type === "image/heif") return "heif";
  return "jpg";
}

export async function POST(request: Request) {
  const s3Env = readS3Env();

  if (!s3Env.region || !s3Env.bucket || !s3Env.fileUrl || !s3Env.accessKeyId || !s3Env.secretAccessKey) {
    return Response.json({ ok: false, message: "S3 upload is not configured." }, { status: 500 });
  }

  const formData = await request.formData();
  const file = formData.get("file");
  const fieldKey = String(formData.get("fieldKey") || "").trim();
  const productHandle = String(formData.get("productHandle") || "").trim();

  if (!(file instanceof File)) {
    return Response.json({ ok: false, message: "No file provided." }, { status: 400 });
  }

  if (!ALLOWED_TYPES.has(file.type)) {
    return Response.json({ ok: false, message: "Unsupported file type." }, { status: 400 });
  }

  if (file.size > MAX_FILE_SIZE) {
    return Response.json({ ok: false, message: "File too large." }, { status: 400 });
  }

  const buffer = Buffer.from(await file.arrayBuffer());
  const digest = createHash("sha1").update(buffer).digest("hex");
  const extension = getExtension(file);
  const key = `${s3Env.prefix.replace(/\/?$/, "/")}personalization-uploads/${sanitizeSegment(productHandle)}/${sanitizeSegment(fieldKey)}/${digest}.${extension}`;

  const s3 = new S3Client({
    region: s3Env.region,
    credentials: {
      accessKeyId: s3Env.accessKeyId,
      secretAccessKey: s3Env.secretAccessKey,
    },
  });

  await s3.send(
    new PutObjectCommand({
      Bucket: s3Env.bucket,
      Key: key,
      Body: buffer,
      ContentType: file.type || "application/octet-stream",
    }),
  );

  return Response.json({
    ok: true,
    url: joinUrl(s3Env.fileUrl, key),
    name: file.name,
    type: file.type,
  });
}
