import { NextRequest, NextResponse } from "next/server";
import { randomUUID } from "node:crypto";
import { mkdir, writeFile } from "node:fs/promises";
import path from "node:path";
import sharp from "sharp";
import { prisma } from "@/lib/prisma";

const MAX_SIZE = 20 * 1024 * 1024;

export async function GET() {
  const images = await prisma.galleryImage.findMany({
    orderBy: [{ order: "asc" }, { createdAt: "desc" }],
  });
  return NextResponse.json({ images });
}

export async function POST(request: NextRequest) {
  const formData = await request.formData().catch(() => null);
  const file = formData?.get("file");
  if (!(file instanceof File)) {
    return NextResponse.json({ error: "No file provided" }, { status: 400 });
  }
  if (!file.type.startsWith("image/")) {
    return NextResponse.json({ error: "File must be an image" }, { status: 400 });
  }
  if (file.size > MAX_SIZE) {
    return NextResponse.json({ error: "Image must be under 20MB" }, { status: 400 });
  }

  const inputBuffer = Buffer.from(await file.arrayBuffer());

  const processed = await sharp(inputBuffer)
    .rotate()
    .toBuffer({ resolveWithObject: true })
    .catch(() => null);
  if (!processed) {
    return NextResponse.json({ error: "Could not process image file" }, { status: 400 });
  }
  const { data, info } = processed;

  const ext = info.format === "jpeg" ? "jpg" : info.format;
  const filename = `${randomUUID()}.${ext}`;
  const uploadDir = path.join(process.cwd(), "public", "uploads", "gallery");
  await mkdir(uploadDir, { recursive: true });
  await writeFile(path.join(uploadDir, filename), data);

  const count = await prisma.galleryImage.count();
  const image = await prisma.galleryImage.create({
    data: {
      url: `/uploads/gallery/${filename}`,
      width: info.width,
      height: info.height,
      order: count,
    },
  });

  return NextResponse.json({ image }, { status: 201 });
}
