import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { z } from "zod";
import { eq } from "drizzle-orm";
import { db } from "@/db";
import { users } from "@/db/schema";
import { authConfig } from "./auth.config";
import { verifyPassword } from "@/lib/auth/password";
import { checkRateLimit, recordAttempt } from "@/lib/auth/rate-limit";

const credSchema = z.object({
  email: z.string().email(),
  password: z.string().min(1),
});

export const { handlers, auth, signIn, signOut } = NextAuth({
  ...authConfig,
  providers: [
    ...authConfig.providers,
    Credentials({
      credentials: { email: {}, password: {} },
      authorize: async (raw) => {
        const parsed = credSchema.safeParse(raw);
        if (!parsed.success) return null;
        const { email, password } = parsed.data;
        const key = `email:${email.toLowerCase()}`;
        // Rate-Limit greift für ALLE Credentials-Logins (default-deny).
        if (!(await checkRateLimit(key))) return null;
        const u = await db.query.users.findFirst({
          where: eq(users.email, email),
        });
        if (!u || !u.aktiv || u.authTyp !== "local" || !u.passwortHash) {
          await recordAttempt(key, "fail");
          return null;
        }
        if (!(await verifyPassword(u.passwortHash, password))) {
          await recordAttempt(key, "fail");
          return null;
        }
        await recordAttempt(key, "ok");
        return {
          id: u.id,
          email: u.email,
          name: u.name,
          role: u.rolle,
          brigadeId: u.brigadeId,
        };
      },
    }),
  ],
  callbacks: {
    ...authConfig.callbacks,
    // Authentik-Login-Gate: nur vorgemerkte, aktive authentik-Konten zulassen.
    async signIn({ user, account }) {
      if (account?.provider === "authentik") {
        const email = user.email;
        if (!email) return false;
        const u = await db.query.users.findFirst({
          where: eq(users.email, email),
        });
        if (!u || !u.aktiv || u.authTyp !== "authentik") return false;
        user.role = u.rolle;
        user.brigadeId = u.brigadeId ?? null;
      }
      return true;
    },
  },
});
