import bcrypt from "bcryptjs";
import { NextResponse } from "next/server";
import { randomUUID } from "crypto";
import { prisma } from "../../../lib/prisma";
import { isAdminEmail, isSuperAdminEmail } from "../../../lib/auth";
import { sendMail } from "../../../lib/mailer";
import { checkRateLimit, getRateLimitConfig } from "../../../lib/rate-limit";
import { getClientIp } from "../../../lib/request";

export async function POST(request: Request) {
  const registrationSetting = await prisma.setting.findUnique({
    where: { key: "registration_enabled" }
  });
  if (registrationSetting?.value === "false") {
    return NextResponse.json(
      { error: "Registrierung ist derzeit deaktiviert." },
      { status: 403 }
    );
  }

  const body = await request.json();
  const { email, name, password } = body || {};
  const normalizedEmail = String(email || "").trim().toLowerCase();

  if (!normalizedEmail || !password) {
    return NextResponse.json({ error: "Email und Passwort sind erforderlich." }, { status: 400 });
  }

  const ip = getClientIp(request);
  const rateKey = `register:${normalizedEmail}:${ip}`;
  const rateConfig = getRateLimitConfig("RATE_LIMIT_REGISTER", 5);
  const rate = await checkRateLimit({
    key: rateKey,
    limit: rateConfig.limit,
    windowMs: rateConfig.windowMs
  });
  if (!rate.ok) {
    return NextResponse.json(
      { error: "Zu viele Anfragen. Bitte später erneut versuchen." },
      { status: 429 }
    );
  }

  const existing = await prisma.user.findUnique({ where: { email: normalizedEmail } });
  if (existing) {
    return NextResponse.json({ error: "Account existiert bereits." }, { status: 409 });
  }

  const passwordHash = await bcrypt.hash(password, 10);
  const superAdmin = isSuperAdminEmail(normalizedEmail);
  const admin = isAdminEmail(normalizedEmail) || superAdmin;

  const user = await prisma.user.create({
    data: {
      email: normalizedEmail,
      name: name || null,
      passwordHash,
      role: superAdmin ? "SUPERADMIN" : admin ? "ADMIN" : "USER",
      status: admin ? "ACTIVE" : "PENDING",
      emailVerified: admin
    }
  });

  const categories = await prisma.category.findMany({
    select: { id: true }
  });

  const view = await prisma.userView.create({
    data: {
      name: "Meine Ansicht",
      token: randomUUID(),
      user: { connect: { id: user.id } }
    }
  });

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

  if (!admin) {
    const token = randomUUID();
    const expires = new Date(Date.now() + 24 * 60 * 60 * 1000);
    await prisma.verificationToken.create({
      data: {
        identifier: normalizedEmail,
        token,
        expires
      }
    });

    const baseUrl = process.env.NEXTAUTH_URL || "http://localhost:3000";
    const verifyUrl = `${baseUrl}/verify/confirm?token=${token}`;
    await sendMail({
      to: normalizedEmail,
      subject: "E-Mail verifizieren",
      text: `Bitte verifiziere deine E-Mail: ${verifyUrl}`
    });
  }

  return NextResponse.json({ id: user.id, email: user.email });
}
