import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { authConfig } from "@/lib/auth/auth.config";
import { prisma } from "@/lib/prisma";
import { verifyPassword } from "@/lib/auth/password";
import { loadUserAuthData } from "@/lib/auth/permissions";
import { loginSchema } from "@/lib/validation/auth";

// Konstanter Dummy-Hash: wird verifiziert, wenn kein Nutzer existiert, um die
// Antwortzeit anzugleichen (Schutz vor User-Enumeration via Timing).
const DUMMY_HASH =
  "$argon2id$v=19$m=19456,t=2,p=1$C+ywDc5UKNbR9jBeFQo/lw$lRhNUjXvMkDx+NqK/RhC4p/Z1vreJsRRSPE+VcfUZgQ";

export const { handlers, auth, signIn, signOut } = NextAuth({
  ...authConfig,
  providers: [
    Credentials({
      credentials: {
        email: { label: "E-Mail", type: "email" },
        password: { label: "Passwort", type: "password" },
      },
      async authorize(raw) {
        const parsed = loginSchema.safeParse(raw);
        if (!parsed.success) return null;

        const { email, password } = parsed.data;
        const user = await prisma.user.findUnique({ where: { email } });

        // Kein Nutzer / kein Passwort gesetzt → trotzdem verifizieren (Timing).
        if (!user || !user.passwordHash) {
          await verifyPassword(DUMMY_HASH, password);
          return null;
        }

        // Gesperrte Konten dürfen sich nicht anmelden. INVITED (neu angelegt)
        // und ACTIVE dürfen sich anmelden; INVITED wird beim ersten Login aktiv.
        if (user.status === "SUSPENDED") {
          await verifyPassword(DUMMY_HASH, password);
          return null;
        }

        const ok = await verifyPassword(user.passwordHash, password);
        if (!ok) return null;

        const { roles, permissions } = await loadUserAuthData(user.id);

        // Beim ersten Login (INVITED) automatisch auf ACTIVE setzen.
        const nextStatus = user.status === "INVITED" ? "ACTIVE" : user.status;
        const now = new Date();

        // Login protokollieren (Audit + lastLoginAt + lastSeenAt + Statuswechsel).
        await prisma.$transaction([
          prisma.user.update({
            where: { id: user.id },
            data: { lastLoginAt: now, lastSeenAt: now, status: nextStatus },
          }),
          prisma.auditLog.create({
            data: { userId: user.id, action: "auth.login", entity: "User", entityId: user.id },
          }),
        ]);

        return {
          id: user.id,
          name: user.displayName ?? user.name,
          email: user.email,
          image: user.avatarUrl ?? null,
          roles,
          permissions,
          status: nextStatus,
        };
      },
    }),
  ],
});
