import { writeFile } from "node:fs/promises";
import path from "node:path";
import { NextResponse } from "next/server";
import { auth } from "@/auth";
import { prisma } from "@/lib/prisma";
import { getCloudScope, canWriteFolder } from "@/lib/cloud/access";
import { cloudDir, makeCloudName, MAX_CLOUD_BYTES } from "@/lib/cloud/storage";
import { cleanFileName } from "@/lib/cloud/format";

/** Datei-Upload in einen Ordner (oder in die persönliche Wurzel). */
export async function POST(req: Request) {
  const session = await auth();
  if (!session?.user) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }
  if (!session.user.permissions?.includes("cloud.manage")) {
    return NextResponse.json({ error: "Keine Berechtigung." }, { status: 403 });
  }

  const form = await req.formData();
  const file = form.get("file");
  const rawFolder = form.get("folderId");
  const folderId = typeof rawFolder === "string" && rawFolder ? rawFolder : null;

  if (!(file instanceof File)) {
    return NextResponse.json({ error: "Keine Datei." }, { status: 400 });
  }
  if (file.size === 0) {
    return NextResponse.json({ error: "Datei ist leer." }, { status: 400 });
  }
  if (file.size > MAX_CLOUD_BYTES) {
    return NextResponse.json(
      { error: `Datei zu groß (max. ${Math.round(MAX_CLOUD_BYTES / 1024 / 1024)} MB).` },
      { status: 413 },
    );
  }

  const scope = await getCloudScope(session.user.id);
  if (!canWriteFolder(scope, folderId)) {
    return NextResponse.json({ error: "Kein Schreibrecht in diesem Ordner." }, { status: 403 });
  }
  if (folderId) {
    const exists = await prisma.cloudFolder.findUnique({
      where: { id: folderId },
      select: { id: true },
    });
    if (!exists) {
      return NextResponse.json({ error: "Ordner nicht gefunden." }, { status: 404 });
    }
  }

  const storedName = makeCloudName();
  const dir = await cloudDir();
  await writeFile(path.join(dir, storedName), Buffer.from(await file.arrayBuffer()));

  const parseSize = (key: string): number | null => {
    const v = form.get(key);
    const n = typeof v === "string" ? Number(v) : NaN;
    return Number.isFinite(n) && n > 0 ? Math.round(n) : null;
  };

  const created = await prisma.cloudFile.create({
    data: {
      folderId,
      name: cleanFileName(file.name),
      storedName,
      mime: (file.type || "application/octet-stream").slice(0, 160),
      size: file.size,
      width: parseSize("width"),
      height: parseSize("height"),
      ownerId: session.user.id,
    },
    select: { id: true, name: true },
  });

  return NextResponse.json({ id: created.id, name: created.name });
}
