import { NextResponse } from "next/server";
import bcrypt from "bcryptjs";
import { prisma } from "../../../lib/prisma";
import {
  isAdminSession,
  isSuperAdminSession,
  requireSession
} from "../../../lib/auth-helpers";

export async function GET(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 status = searchParams.get("status");

  const users = await prisma.user.findMany({
    where: status ? { status } : undefined,
    orderBy: { createdAt: "desc" },
    select: {
      id: true,
      email: true,
      name: true,
      status: true,
      role: true,
      emailVerified: true,
      createdAt: true
    }
  });

  if (!isSuperAdminSession(session)) {
    return NextResponse.json(users);
  }

  const emails = users.map((user) => user.email).filter(Boolean);
  const attempts = emails.length
    ? await prisma.loginAttempt.findMany({
        where: { email: { in: emails } }
      })
    : [];

  const stats = attempts.reduce<Record<string, {
    attempts: number;
    lastAttempt: Date | null;
    lockedUntil: Date | null;
  }>>((acc, attempt) => {
    const current = acc[attempt.email] || {
      attempts: 0,
      lastAttempt: null,
      lockedUntil: null
    };
    current.attempts += attempt.attempts;
    if (!current.lastAttempt || attempt.lastAttempt > current.lastAttempt) {
      current.lastAttempt = attempt.lastAttempt;
    }
    if (!current.lockedUntil || (attempt.lockedUntil && attempt.lockedUntil > current.lockedUntil)) {
      current.lockedUntil = attempt.lockedUntil;
    }
    acc[attempt.email] = current;
    return acc;
  }, {});

  const enriched = users.map((user) => ({
    ...user,
    loginStats: stats[user.email] || {
      attempts: 0,
      lastAttempt: null,
      lockedUntil: null
    }
  }));

  return NextResponse.json(enriched);
}

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 {
    email,
    name,
    password,
    role,
    status,
    emailVerified
  } = body || {};

  if (!email || !password) {
    return NextResponse.json(
      { error: "E-Mail und Passwort sind erforderlich." },
      { status: 400 }
    );
  }

  const normalizedEmail = String(email).trim().toLowerCase();
  const allowedRoles = ["USER", "ADMIN", "SUPERADMIN"];
  const allowedStatuses = ["ACTIVE", "PENDING", "DISABLED"];
  const isSuperAdmin = isSuperAdminSession(session);
  const nextRole = isSuperAdmin && allowedRoles.includes(role) ? role : "USER";
  const nextStatus = allowedStatuses.includes(status) ? status : "PENDING";

  if (!normalizedEmail) {
    return NextResponse.json({ error: "Ungültige E-Mail." }, { status: 400 });
  }

  const passwordHash = await bcrypt.hash(String(password), 10);

  try {
    const user = await prisma.user.create({
      data: {
        email: normalizedEmail,
        name: name ? String(name).trim() : null,
        passwordHash,
        role: nextRole,
        status: nextStatus,
        emailVerified: Boolean(emailVerified)
      },
      select: {
        id: true,
        email: true,
        name: true,
        role: true,
        status: true,
        emailVerified: true,
        createdAt: true
      }
    });

    return NextResponse.json(user, { status: 201 });
  } catch (err) {
    return NextResponse.json(
      { error: "Benutzer konnte nicht angelegt werden." },
      { status: 400 }
    );
  }
}

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 {
    userId,
    status,
    role,
    name,
    email,
    password,
    emailVerified,
    resetLoginAttempts
  } = body || {};

  if (!userId) {
    return NextResponse.json({ error: "Ungültige Anfrage." }, { status: 400 });
  }

  const target = await prisma.user.findUnique({
    where: { id: userId },
    select: { role: true }
  });

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

  if (resetLoginAttempts) {
    if (!isSuperAdminSession(session)) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }
    const userRecord = await prisma.user.findUnique({
      where: { id: userId },
      select: { email: true }
    });
    if (userRecord?.email) {
      await prisma.loginAttempt.deleteMany({ where: { email: userRecord.email } });
    }
    return NextResponse.json({ ok: true });
  }

  if (target.role === "SUPERADMIN" && !isSuperAdminSession(session)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  const allowedStatuses = ["ACTIVE", "PENDING", "DISABLED"];
  const data: Record<string, any> = {};

  if (status) {
    if (!allowedStatuses.includes(status)) {
      return NextResponse.json({ error: "Ungültiger Status." }, { status: 400 });
    }
    data.status = status;
  }

  if (name !== undefined) {
    data.name = name ? String(name).trim() : null;
  }

  if (email) {
    data.email = String(email).trim().toLowerCase();
  }

  if (emailVerified !== undefined) {
    data.emailVerified = Boolean(emailVerified);
  }

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

  if (role) {
    if (!isSuperAdminSession(session)) {
      return NextResponse.json({ error: "Forbidden" }, { status: 403 });
    }
    if (!["USER", "ADMIN", "SUPERADMIN"].includes(role)) {
      return NextResponse.json({ error: "Ungültige Rolle." }, { status: 400 });
    }
    data.role = role;
  }

  const user = await prisma.user.update({
    where: { id: userId },
    data,
    select: {
      id: true,
      email: true,
      name: true,
      role: true,
      status: true,
      emailVerified: true,
      createdAt: true
    }
  });

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

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 userId = searchParams.get("id");

  if (!userId) {
    return NextResponse.json({ error: "Ungültige Anfrage." }, { status: 400 });
  }

  if (session.user?.id === userId) {
    return NextResponse.json(
      { error: "Eigenes Konto kann nicht gelöscht werden." },
      { status: 400 }
    );
  }

  const target = await prisma.user.findUnique({
    where: { id: userId },
    select: { role: true }
  });

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

  if (target.role !== "USER" && !isSuperAdminSession(session)) {
    return NextResponse.json({ error: "Forbidden" }, { status: 403 });
  }

  await prisma.session.deleteMany({ where: { userId } });
  await prisma.account.deleteMany({ where: { userId } });

  await prisma.user.update({
    where: { id: userId },
    data: { status: "DISABLED", emailVerified: false }
  });

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