import NextAuth, { NextAuthOptions } from 'next-auth'
import CredentialsProvider from 'next-auth/providers/credentials'
import GitHubProvider from 'next-auth/providers/github'
import GoogleProvider from 'next-auth/providers/google'
import bcrypt from 'bcryptjs'
import { UserRole } from '@/lib/auth/types'

// In-memory user store for MVP (will be replaced with Prisma in Agent 2)
// This simulates database operations
interface StoredUser {
  id: string
  email: string
  name: string | null
  passwordHash: string | null
  role: UserRole
  emailVerified: Date | null
  image: string | null
  createdAt: Date
}

// Temporary in-memory store (will be replaced with database)
const users: Map<string, StoredUser> = new Map()

// Helper to find user by email
function findUserByEmail(email: string): StoredUser | undefined {
  for (const user of users.values()) {
    if (user.email.toLowerCase() === email.toLowerCase()) {
      return user
    }
  }
  return undefined
}

// Helper to create user
export function createUser(data: {
  email: string
  name?: string
  passwordHash?: string
  role?: UserRole
}): StoredUser {
  const id = `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
  const user: StoredUser = {
    id,
    email: data.email.toLowerCase(),
    name: data.name || null,
    passwordHash: data.passwordHash || null,
    role: data.role || UserRole.USER,
    emailVerified: null,
    image: null,
    createdAt: new Date(),
  }
  users.set(id, user)
  return user
}

// Helper to get user by ID
export function getUserById(id: string): StoredUser | undefined {
  return users.get(id)
}

// Helper to verify password
async function verifyPassword(password: string, hash: string): Promise<boolean> {
  return bcrypt.compare(password, hash)
}

export const authOptions: NextAuthOptions = {
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        email: { label: 'Email', type: 'email', placeholder: 'your@email.com' },
        password: { label: 'Password', type: 'password' },
      },
      async authorize(credentials) {
        if (!credentials?.email || !credentials?.password) {
          throw new Error('Email and password are required')
        }

        const user = findUserByEmail(credentials.email)

        if (!user) {
          throw new Error('No user found with this email')
        }

        if (!user.passwordHash) {
          throw new Error('Please sign in with your OAuth provider')
        }

        const isValid = await verifyPassword(credentials.password, user.passwordHash)

        if (!isValid) {
          throw new Error('Invalid password')
        }

        return {
          id: user.id,
          email: user.email,
          name: user.name,
          role: user.role,
          emailVerified: user.emailVerified,
          image: user.image,
        }
      },
    }),
    ...(process.env.GITHUB_ID && process.env.GITHUB_SECRET
      ? [
          GitHubProvider({
            clientId: process.env.GITHUB_ID,
            clientSecret: process.env.GITHUB_SECRET,
          }),
        ]
      : []),
    ...(process.env.GOOGLE_CLIENT_ID && process.env.GOOGLE_CLIENT_SECRET
      ? [
          GoogleProvider({
            clientId: process.env.GOOGLE_CLIENT_ID,
            clientSecret: process.env.GOOGLE_CLIENT_SECRET,
          }),
        ]
      : []),
  ],
  session: {
    strategy: 'jwt',
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  jwt: {
    maxAge: 30 * 24 * 60 * 60, // 30 days
  },
  pages: {
    signIn: '/auth/signin',
    signOut: '/auth/signout',
    error: '/auth/error',
    verifyRequest: '/auth/verify-request',
    newUser: '/auth/new-user',
  },
  callbacks: {
    async signIn({ user, account }) {
      // Handle OAuth sign-in
      if (account?.provider !== 'credentials') {
        const existingUser = findUserByEmail(user.email!)
        if (!existingUser) {
          // Create new user for OAuth sign-in
          createUser({
            email: user.email!,
            name: user.name || undefined,
            role: UserRole.USER,
          })
        }
      }
      return true
    },
    async jwt({ token, user, trigger, session }) {
      // Initial sign-in
      if (user) {
        token.id = user.id
        token.role = user.role || UserRole.USER
        token.emailVerified = user.emailVerified
      }

      // Handle session update
      if (trigger === 'update' && session) {
        token.name = session.name
        token.role = session.role
      }

      return token
    },
    async session({ session, token }) {
      if (session.user) {
        session.user.id = token.id
        session.user.role = token.role
        session.user.emailVerified = token.emailVerified
      }
      return session
    },
  },
  events: {
    async signIn({ user, isNewUser }) {
      console.log(`User signed in: ${user.email}, isNewUser: ${isNewUser}`)
    },
    async signOut({ token }) {
      console.log(`User signed out: ${token.email}`)
    },
  },
  debug: process.env.NODE_ENV === 'development',
}

export default NextAuth(authOptions)

// Export helper for use in registration API
export { findUserByEmail, verifyPassword }
