import NextAuth from "next-auth"
import Credentials from "next-auth/providers/credentials"
import { prisma } from "./prisma"
import bcrypt from "bcryptjs"

const nextAuthSecret = process.env.NEXTAUTH_SECRET
if (!nextAuthSecret) {
  throw new Error("NEXTAUTH_SECRET is not set. Define it to enable authentication.")
}

export const { handlers, auth, signIn, signOut } = NextAuth({
  trustHost: true,
  debug: process.env.NODE_ENV !== "production",
  providers: [
    Credentials({
      name: "Credentials",
      credentials: {
        email: { label: "Email", type: "email" },
        password: { label: "Password", type: "password" }
      },
      async authorize(credentials) {
        try {
          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 || !user.passwordHash) {
            return null
          }

          const isValid = await bcrypt.compare(password, user.passwordHash)

          if (!isValid) {
            return null
          }

          return {
            id: user.id,
            email: user.email,
            name: user.name,
            role: user.role,
          }
        } catch (err) {
          console.error("Auth authorize error:", err)
          return null
        }
      }
    })
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.id = user.id
        token.role = (user as { role: string }).role
        token.email = user.email
        token.name = user.name
        console.log("JWT callback: user added to token", { userId: user.id, email: user.email })
      } else {
        console.log("JWT callback: no user, token exists", { 
          hasToken: !!token,
          tokenKeys: token ? Object.keys(token) : [],
          tokenId: token?.id,
          tokenEmail: token?.email,
          tokenName: token?.name,
          tokenRole: token?.role
        })
      }
      return token
    },
    async session({ session, token }) {
      console.log("Session callback: called", {
        hasToken: !!token,
        hasSession: !!session,
        tokenId: token?.id,
        tokenEmail: token?.email,
        stackTrace: new Error().stack?.split('\n').slice(1, 4).join('\n')
      })
      // Always ensure session.user exists when token exists
      if (token && (token.id || token.email)) {
        // Ensure session.user is always an object
        if (!session.user) {
          session.user = {} as any
        }
        session.user = {
          ...session.user,
          id: token.id as string,
          email: (token.email as string) || session.user?.email || "",
          name: (token.name as string) || session.user?.name || "",
          role: token.role as string,
        }
        console.log("Session callback: session created", { 
          userId: token.id, 
          email: token.email,
          hasUser: !!session.user,
          userKeys: session.user ? Object.keys(session.user) : [],
          userRole: token.role,
          sessionUser: session.user,
          sessionExpires: session.expires,
          fullSession: JSON.stringify(session, null, 2)
        })
      } else {
        console.warn("Session callback: token missing or invalid", { 
          hasToken: !!token,
          tokenKeys: token ? Object.keys(token) : [],
          hasSession: !!session,
          sessionKeys: session ? Object.keys(session) : [],
          sessionUser: session?.user,
          tokenId: token?.id,
          tokenEmail: token?.email
        })
        // Return null if no valid token - this will cause auth() to return null
        return null
      }
      // Explicitly return session to ensure it's returned
      return session
    }
  },
  pages: {
    signIn: "/login",
  },
  session: {
    strategy: "jwt",
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  cookies: {
    sessionToken: {
      name: `__Secure-authjs.session-token`,
      options: {
        httpOnly: true,
        sameSite: "lax",
        path: "/",
        secure: true, // Always secure in production (HTTPS required)
      },
    },
  },
  secret: nextAuthSecret,
})
