// tdd-guard:skip — Next.js route handler; testable logic lives in lib/api/error.ts tests.
import { NextRequest, NextResponse } from 'next/server'
import { getUserSession, canManageUser, type RoleCode } from '@/lib/auth/permissions'
import { isAtLeastRole } from '@/lib/auth/permissions-shared'
import { apiError, routeError } from '@/lib/api/error'
import { UserIdBody } from '@/lib/api/schemas'
import { checkCsrf } from '@/lib/security'
import { createClient } from '@/lib/supabase/server'

export async function POST(request: NextRequest) {
  const csrf = checkCsrf(request); if (csrf) return csrf
  const session = await getUserSession()
  if (!session) return apiError.unauthorized()
  if (!isAtLeastRole(session, 'admin')) return apiError.forbidden()

  const parsed = UserIdBody.safeParse(await request.json().catch(() => ({})))
  if (!parsed.success) return apiError.invalidBody(parsed.error.issues)
  const { userId } = parsed.data

  const supabase = await createClient()

  // KAR-773: an admin must not unlock a user they cannot manage (e.g. a
  // masteradmin). Mirrors the invite/reset privilege gate.
  const { data: targetProfile } = await supabase
    .from('user_profiles')
    .select('roles ( code )')
    .eq('id', userId)
    .single()
  if (!targetProfile) {
    return NextResponse.json({ error: 'User not found' }, { status: 404 })
  }
  const targetRoleCode = ((Array.isArray(targetProfile.roles) ? (targetProfile.roles as { code: string }[])[0] : (targetProfile.roles as { code: string } | null))?.code ?? 'readonly') as RoleCode
  if (!canManageUser(session, targetRoleCode)) {
    return apiError.forbidden()
  }

  const { data: updated, error } = await supabase
    .from('user_profiles')
    .update({ account_status: 'active' })
    .eq('id', userId)
    .select()
    .single()

  if (error) {
    return routeError('Benutzer konnte nicht entsperrt werden.', error)
  }

  await supabase.from('user_audit_log').insert({
    actor_id:       session.authUserId,
    target_user_id: userId,
    action:         'user.unlocked',
    details:        {},
  })

  return NextResponse.json({ profile: updated })
}
