import NextAuth from "next-auth";
import Credentials from "next-auth/providers/credentials";
import { PrismaAdapter } from "@auth/prisma-adapter";
import bcrypt from "bcryptjs";
import { prisma } from "@/lib/db";

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: PrismaAdapter(prisma),
  session: { strategy: "jwt" },
  trustHost: true,
  pages: {
    signIn: "/login",
  },
  providers: [
    Credentials({
      name: "credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" },
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) return null;

        const email = credentials.email as string;
        const password = credentials.password as string;

        const user = await prisma.user.findUnique({ where: { email } });
        if (!user?.hashedPassword) return null;

        const valid = await bcrypt.compare(password, user.hashedPassword);
        if (!valid) return null;

        return {
          id: user.id,
          email: user.email,
          name: user.displayName || user.username,
          image: user.avatarUrl || undefined,
        };
      },
    }),
    // Authentik OIDC — enabled when env vars are set
    ...(process.env.AUTHENTIK_ISSUER
      ? [
          {
            id: "authentik",
            name: "SSO",
            type: "oidc" as const,
            issuer: process.env.AUTHENTIK_ISSUER,
            clientId: process.env.AUTHENTIK_CLIENT_ID!,
            clientSecret: process.env.AUTHENTIK_CLIENT_SECRET!,
          },
        ]
      : []),
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id;
      }

      if (token.id) {
        const dbUser = await prisma.user.findUnique({
          where: { id: token.id as string },
          include: {
            memberships: {
              include: {
                organization: {
                  select: { id: true, name: true, onboardingComplete: true },
                },
              },
            },
          },
        });

        if (dbUser) {
          token.role = dbUser.role;
          token.displayName = dbUser.displayName ?? undefined;
          token.avatarUrl = dbUser.avatarUrl ?? undefined;
          token.isEmailVerified = !!dbUser.emailVerified;

          const memberships = dbUser.memberships;
          let activeMembership = memberships.find(
            (m) => m.organizationId === dbUser.activeOrgId
          );
          if (!activeMembership && memberships.length > 0) {
            activeMembership = memberships[0];
          }

          if (activeMembership) {
            token.orgId = activeMembership.organizationId;
            token.orgName = activeMembership.organization.name;
            token.orgRole = activeMembership.role;
            token.onboardingComplete =
              activeMembership.organization.onboardingComplete ?? false;
          } else {
            token.orgId = undefined;
            token.orgName = undefined;
            token.orgRole = undefined;
            token.onboardingComplete = false;
          }
          token.hasOrg = memberships.length > 0;
        }
      }

      return token;
    },
    async session({ session, token }) {
      if (session.user) {
        session.user.id = token.id as string;
        session.user.role = (token.orgRole || token.role || "viewer") as string;
        session.user.orgId = token.orgId as string | undefined;
        session.user.orgName = token.orgName as string | undefined;
        session.user.displayName = token.displayName as string | undefined;
        session.user.avatarUrl = token.avatarUrl as string | undefined;
        session.user.isEmailVerified = token.isEmailVerified ?? false;
        session.user.onboardingComplete = token.onboardingComplete ?? false;
        session.user.hasOrg = (token.hasOrg as boolean) ?? false;
      }
      return session;
    },
  },
});
