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

export async function GET(request: Request) {
  const session = await getServerSession(authOptions);
  if (session?.user?.status && session.user.status !== "ACTIVE") {
    return NextResponse.json(
      { error: "Account nicht freigeschaltet." },
      { status: 403 }
    );
  }
  if (session?.user?.emailVerified === false) {
    return NextResponse.json(
      { error: "E-Mail nicht verifiziert." },
      { status: 403 }
    );
  }
  const { searchParams } = new URL(request.url);
  const status = searchParams.get("status");
  const isAdmin = isAdminSession(session);
  const { publicAccessEnabled } = await getAccessSettings();

  if (!session?.user?.email) {
    if (!publicAccessEnabled) {
      return NextResponse.json(
        { error: "Öffentlicher Zugriff ist deaktiviert." },
        { status: 403 }
      );
    }
    const events = await prisma.event.findMany({
      where: {
        status: "APPROVED",
        OR: [
          { publicOverride: true },
          { publicOverride: null, category: { isPublic: true } }
        ]
      },
      orderBy: { startAt: "asc" },
      select: {
        id: true,
        title: true,
        location: true,
        locationPlaceId: true,
        locationLat: true,
        locationLng: true,
        startAt: true,
        endAt: true,
        status: true,
        category: {
          select: {
            id: true,
            name: true
          }
        }
      }
    });

    return NextResponse.json(events);
  }

  const where = isAdmin
    ? status
      ? { status }
      : {}
    : {
        OR: [
          { status: "APPROVED" },
          { createdBy: { email: session.user?.email || "" } }
        ]
      };

  const events = await prisma.event.findMany({
    where,
    orderBy: { startAt: "asc" },
    include: isAdmin
      ? { category: true, createdBy: { select: { name: true, email: true } } }
      : { category: true }
  });

  return NextResponse.json(events);
}

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

  const body = await request.json();
  const {
    title,
    description,
    location,
    locationPlaceId,
    locationLat,
    locationLng,
    startAt,
    endAt,
    categoryId
  } = body || {};

  if (!title || !startAt) {
    return NextResponse.json(
      { error: "Titel und Start sind erforderlich." },
      { status: 400 }
    );
  }

  if (!categoryId) {
    return NextResponse.json(
      { error: "Kategorie ist erforderlich." },
      { status: 400 }
    );
  }

  const startDate = new Date(startAt);
  const endDate = endAt
    ? new Date(endAt)
    : new Date(startDate.getTime() + 3 * 60 * 60 * 1000);
  const creatorEmail = session.user?.email || "";

  const existing = await prisma.event.findFirst({
    where: {
      title,
      startAt: startDate,
      location: location || null,
      categoryId,
      createdBy: { email: creatorEmail }
    }
  });

  if (existing) {
    return NextResponse.json(
      { error: "Ein identischer Termin existiert bereits." },
      { status: 409 }
    );
  }

  const event = await prisma.event.create({
    data: {
      title,
      description: description || null,
      location: location || null,
      locationPlaceId: locationPlaceId || null,
      locationLat: locationLat ? Number(locationLat) : null,
      locationLng: locationLng ? Number(locationLng) : null,
      startAt: startDate,
      endAt: endDate,
      status: isAdminSession(session) ? "APPROVED" : "PENDING",
      createdBy: { connect: { email: creatorEmail } },
      category: { connect: { id: categoryId } }
    }
  });

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