import type { NextAuthConfig } from 'next-auth'
import type { UserRole } from '@prisma/client'

type ImpersonationInfo = {
  originalId: string
  originalRole: UserRole
  originalRoles: UserRole[]
  originalEmail: string
}

// Extend the built-in session types
declare module 'next-auth' {
  interface Session {
    user: {
      id: string
      email: string
      name?: string | null
      role: UserRole
      roles: UserRole[]
      mustSetPassword?: boolean
      impersonating?: ImpersonationInfo
    }
  }

  interface User {
    role?: UserRole
    roles?: UserRole[]
    mustSetPassword?: boolean
  }
}

declare module '@auth/core/jwt' {
  interface JWT {
    id: string
    role: UserRole
    roles?: UserRole[]
    mustSetPassword?: boolean
    impersonating?: ImpersonationInfo
  }
}

// Edge-compatible auth config (no Node.js-only modules)
// This is used by middleware and can be extended in auth.ts for full functionality
export const authConfig: NextAuthConfig = {
  providers: [], // Providers are added in auth.ts
  callbacks: {
    authorized({ auth, request: { nextUrl } }) {
      const isLoggedIn = !!auth?.user
      const { pathname } = nextUrl

      // Public paths that don't require authentication
      const publicPaths = [
        '/login',
        '/verify',
        '/verify-email',
        '/error',
        '/accept-invite',
        '/forgot-password',
        '/reset-password',
        '/apply',
        '/lunch/pick', // external attendees pick a dish via signed token (no account)
        '/api/auth',
        '/api/trpc', // tRPC handles its own auth via procedures
        '/api/cron', // cron endpoints self-guard via x-cron-secret (CRON_SECRET)
      ]

      // Check if it's a public path
      if (publicPaths.some((path) => pathname.startsWith(path))) {
        return true
      }

      // If not logged in, redirect to login
      if (!isLoggedIn) {
        return false // Will redirect to signIn page
      }

      // Check if user needs to set password (skip during impersonation)
      const mustSetPassword = auth?.user?.mustSetPassword
      const isImpersonating = !!(auth?.user as Record<string, unknown>)?.impersonating
      const passwordSetupAllowedPaths = [
        '/set-password',
        '/api/auth',
        '/api/trpc',
      ]

      if (mustSetPassword && !isImpersonating) {
        // Allow access to password setup related paths
        if (passwordSetupAllowedPaths.some((path) => pathname.startsWith(path))) {
          return true
        }
        // Redirect to set-password page
        return Response.redirect(new URL('/set-password', nextUrl))
      }

      return true
    },
  },
  pages: {
    signIn: '/login',
    verifyRequest: '/verify-email',
    error: '/error',
    newUser: '/set-password',
  },
  session: {
    strategy: 'jwt',
    maxAge: parseInt(process.env.SESSION_MAX_AGE || '86400'), // 24 hours
  },
}
