import { NextResponse } from "next/server";
import { getCurrentUser } from "@/lib/auth";
import { can } from "@/lib/permissions";
import { db } from "@/lib/db";
import { audit } from "@/lib/audit";
import { sameOrigin, forbidden } from "@/lib/security";
import { ALLOWED_MEDIA, MAX_IMAGE_BYTES, MAX_VIDEO_BYTES, imageSize, newKey, sniffType, storage } from "@/lib/storage";

export async function GET(req: Request) {
  const user = await getCurrentUser();
  if (!user || !(can(user.role, "media.manage") || can(user.role, "products.edit") || can(user.role, "content.edit"))) return new NextResponse("Forbidden", { status: 403 });
  const q = new URL(req.url).searchParams.get("q") ?? "";
  const items = await db.media.findMany({ where: q ? { OR: [{ filename: { contains: q } }, { alt: { contains: q } }, { folder: { contains: q } }] } : {}, orderBy: { createdAt: "desc" }, take: 120 });
  return NextResponse.json({ items: items.map((m) => ({ id: m.id, url: m.url, alt: m.alt, filename: m.filename, mime: m.mime, folder: m.folder })) });
}

export async function POST(req: Request) {
  if (!sameOrigin(req)) return forbidden();
  const user = await getCurrentUser();
  if (!user || !can(user.role, "media.manage")) return NextResponse.json({ error: "You don't have permission to upload." }, { status: 403 });
  const form = await req.formData().catch(() => null);
  const file = form?.get("file");
  if (!(file instanceof File)) return NextResponse.json({ error: "Choose a file to upload." }, { status: 400 });
  const buf = Buffer.from(await file.arrayBuffer());
  const mime = sniffType(buf);
  if (!mime || !ALLOWED_MEDIA[mime]) return NextResponse.json({ error: "Only JPG, PNG, WebP, AVIF, MP4 and WebM files are allowed." }, { status: 415 });
  const limit = mime.startsWith("video/") ? MAX_VIDEO_BYTES : MAX_IMAGE_BYTES;
  if (buf.length > limit) return NextResponse.json({ error: `That file is too large. The limit is ${Math.round(limit / 1048576)} MB.` }, { status: 413 });
  const folder = String(form?.get("folder") ?? "general");
  const key = newKey(folder, ALLOWED_MEDIA[mime]);
  const stored = await storage().put(key, buf, mime);
  const dim = mime.startsWith("image/") ? imageSize(buf) : null;
  const safeName = file.name.replace(/[^\w.\- ]+/g, "").slice(0, 120) || "upload";
  const m = await db.media.create({ data: { url: stored.url, storageKey: stored.key, filename: safeName, mime, size: buf.length, width: dim?.width ?? null, height: dim?.height ?? null, folder: folder.replace(/[^a-z0-9-]/gi, "").toLowerCase() || "general", alt: String(form?.get("alt") ?? "").slice(0, 200) } });
  await audit(user.id, "media.upload", "Media", m.id, { filename: safeName });
  return NextResponse.json({ item: { id: m.id, url: m.url, alt: m.alt, filename: m.filename, mime: m.mime, folder: m.folder } });
}
