import { Request, Response, NextFunction } from 'express'
import { prisma } from '../lib/prisma'
import { AdminRole } from '@rentaldrivego/database'
import { getAuthToken, sendUnauthorized, sendForbidden } from './authHelpers'
import { verifyActorToken } from '../security/tokens'
import { getSessionCookieName } from '../security/sessionCookies'

const ROLE_RANK: Record<AdminRole, number> = {
  SUPER_ADMIN: 5,
  ADMIN:       4,
  SUPPORT:     3,
  FINANCE:     2,
  VIEWER:      1,
}

const ADMIN_2FA_ENROLLMENT_EXEMPT_PATHS = new Set([
  '/auth/me',
  '/auth/logout',
  '/auth/2fa/setup',
  '/auth/2fa/verify',
])

const FRESH_2FA_WINDOW_MS = Number(process.env.ADMIN_FRESH_2FA_WINDOW_MS ?? 10 * 60 * 1000)

function is2faEnrollmentExempt(req: Request) {
  return ADMIN_2FA_ENROLLMENT_EXEMPT_PATHS.has(req.path)
}

/**
 * Requires a valid admin session token.
 *
 * Guarantees on success:
 *   req.admin — the full AdminUser record
 */
export async function requireAdminAuth(req: Request, res: Response, next: NextFunction) {
  const token = getAuthToken(req, getSessionCookieName('admin'))

  if (!token) return sendUnauthorized(res, 'unauthenticated', 'Admin authentication required')

  let payload: { sub: string; type: string; last2faAt?: number }
  try {
    payload = verifyActorToken(token, 'admin')
  } catch {
    return sendUnauthorized(res, 'invalid_token', 'Invalid or expired admin token')
  }

  const admin = await prisma.adminUser.findUnique({ where: { id: payload.sub } })
  if (!admin || !admin.isActive) {
    return sendUnauthorized(res, 'unauthenticated', 'Admin account not found or deactivated')
  }

  if (!admin.totpEnabled && !is2faEnrollmentExempt(req)) {
    return sendForbidden(res, 'admin_2fa_required', 'Admin 2FA enrollment is required before using privileged admin routes')
  }

  req.admin = admin
  req.adminAuthLast2faAt = typeof payload.last2faAt === 'number' ? payload.last2faAt : undefined
  next()
}

/**
 * Requires the authenticated admin to have at least `minimumRole`.
 * Must be applied after `requireAdminAuth`.
 */
export function requireAdminRole(minimumRole: AdminRole) {
  return (req: Request, res: Response, next: NextFunction) => {
    const admin = req.admin
    if (!admin) return sendUnauthorized(res, 'unauthenticated', 'Admin authentication required')

    const rank     = ROLE_RANK[admin.role]   ?? 0
    const required = ROLE_RANK[minimumRole]  ?? 99

    if (rank < required) {
      return sendForbidden(res, 'forbidden', `This action requires the ${minimumRole} role or higher`)
    }

    next()
  }
}

export function requireFreshAdmin2FA(req: Request, res: Response, next: NextFunction) {
  const admin = req.admin
  if (!admin) return sendUnauthorized(res, 'unauthenticated', 'Admin authentication required')
  if (!admin.totpEnabled) {
    return sendForbidden(res, 'admin_2fa_required', 'Admin 2FA enrollment is required for this action')
  }

  const last2faAt = req.adminAuthLast2faAt
  if (!last2faAt || Date.now() - last2faAt > FRESH_2FA_WINDOW_MS) {
    return sendForbidden(res, 'fresh_2fa_required', 'Fresh admin 2FA verification is required for this action')
  }

  next()
}
