import bcrypt from "bcryptjs";
import crypto from "crypto";
import { NextResponse } from "next/server";
import { prisma } from "../../../lib/prisma";
import { requireSession } from "../../../lib/auth-helpers";
import { sendMail } from "../../../lib/mailer";

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

  const body = await request.json();
  const { currentPassword, newPassword, newEmail } = body || {};
  const normalizedEmail = newEmail ? String(newEmail).trim().toLowerCase() : "";

  if (!currentPassword) {
    return NextResponse.json(
      { error: "Aktuelles Passwort erforderlich." },
      { status: 400 }
    );
  }

  const user = await prisma.user.findUnique({
    where: { email: session.user?.email || "" }
  });

  if (!user) {
    return NextResponse.json({ error: "User nicht gefunden." }, { status: 404 });
  }

  const valid = await bcrypt.compare(currentPassword, user.passwordHash);
  if (!valid) {
    return NextResponse.json({ error: "Passwort ungültig." }, { status: 401 });
  }

  const data: { email?: string; passwordHash?: string; emailVerified?: boolean } = {};

  if (normalizedEmail && normalizedEmail !== user.email) {
    const existing = await prisma.user.findUnique({ where: { email: normalizedEmail } });
    if (existing) {
      return NextResponse.json(
        { error: "E-Mail bereits vergeben." },
        { status: 409 }
      );
    }
    data.email = normalizedEmail;
    data.emailVerified = false;
  }

  if (newPassword) {
    data.passwordHash = await bcrypt.hash(newPassword, 10);
  }

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

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

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

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

  return NextResponse.json({
    id: updated.id,
    email: updated.email,
    changedEmail: Boolean(data.email),
    changedPassword: Boolean(data.passwordHash)
  });
}
