import { NextResponse } from "next/server";
import { prisma } from "../../../lib/prisma";
import { isAdminSession, requireSession } from "../../../lib/auth-helpers";
import { getAccessSettings } from "../../../lib/system-settings";

export async function GET() {
  const { session } = await requireSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  const categories = await prisma.category.findMany({
    orderBy: { name: "asc" }
  });

  return NextResponse.json(categories);
}

export async function POST(request: Request) {
  const { session } = await requireSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!isAdminSession(session)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const body = await request.json();
  const { name, isPublic } = body || {};

  if (!name) {
    return NextResponse.json({ error: "Name erforderlich." }, { status: 400 });
  }

  const existing = await prisma.category.findUnique({ where: { name } });
  if (existing) {
    return NextResponse.json({ error: "Kategorie existiert bereits." }, { status: 409 });
  }

  const { publicAccessEnabled } = await getAccessSettings();
  const category = await prisma.category.create({
    data: { name, isPublic: publicAccessEnabled && isPublic === true }
  });

  const views = await prisma.userView.findMany({
    select: { id: true }
  });

  if (views.length > 0) {
    await prisma.userViewCategory.createMany({
      data: views.map((view) => ({
        viewId: view.id,
        categoryId: category.id
      }))
    });
  }

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

export async function PATCH(request: Request) {
  const { session } = await requireSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!isAdminSession(session)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const body = await request.json();
  const { id, name, isPublic } = body || {};

  if (!id) {
    return NextResponse.json({ error: "ID erforderlich." }, { status: 400 });
  }

  const data: { name?: string; isPublic?: boolean } = {};

  if (name !== undefined) {
    const trimmed = String(name).trim();
    if (!trimmed) {
      return NextResponse.json({ error: "Name erforderlich." }, { status: 400 });
    }

    const existing = await prisma.category.findUnique({ where: { name: trimmed } });
    if (existing && existing.id !== id) {
      return NextResponse.json({ error: "Kategorie existiert bereits." }, { status: 409 });
    }
    data.name = trimmed;
  }

  const { publicAccessEnabled } = await getAccessSettings();
  if (publicAccessEnabled && typeof isPublic === "boolean") {
    data.isPublic = isPublic;
  }

  if (Object.keys(data).length === 0) {
    return NextResponse.json(
      { error: "Keine Änderungen angegeben." },
      { status: 400 }
    );
  }

  const category = await prisma.category.update({
    where: { id },
    data
  });

  return NextResponse.json(category);
}

export async function DELETE(request: Request) {
  const { session } = await requireSession();
  if (!session) {
    return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  }

  if (!isAdminSession(session)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const { searchParams } = new URL(request.url);
  const id = searchParams.get("id");

  if (!id) {
    return NextResponse.json({ error: "ID erforderlich." }, { status: 400 });
  }

  await prisma.event.updateMany({
    where: { categoryId: id },
    data: { categoryId: null }
  });

  await prisma.category.delete({ where: { id } });

  return NextResponse.json({ ok: true });
}
