// tdd-guard:skip — Next.js route handler; pure helpers (generateRecoveryLink,
// canManageUser) are unit-tested separately. Behaviour: return a fresh single-use
// login link for the admin to relay manually.
//
// KAR-772 interim: there is no email-delivery worker yet, so invites cannot be
// emailed. This route generates a fresh /auth/confirm link and returns it to the
// authorized admin, who sends it via their own channel. The link is NOT stored
// anywhere (unlike the email_queue path) — KAR-771-safe.
import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { getUserSession, canManageUser, type RoleCode } from '@/lib/auth/permissions'
import { checkCsrf } from '@/lib/security'
import { createClient } from '@/lib/supabase/server'
import { generateRecoveryLink } from '@/lib/auth/recovery-link'
import { routeError } from '@/lib/api/error'

const InviteLinkBodySchema = z.object({
  userId: z.string().uuid(),
})

export async function POST(request: NextRequest) {
  const csrf = checkCsrf(request); if (csrf) return csrf
  const session = await getUserSession()
  if (!session) {
    return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
  }
  if (session.role !== 'admin' && session.role !== 'masteradmin') {
    return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
  }

  const parsed = InviteLinkBodySchema.safeParse(await request.json().catch(() => ({})))
  if (!parsed.success) {
    return NextResponse.json({ error: 'Invalid body', issues: parsed.error.issues }, { status: 400 })
  }
  const { userId } = parsed.data

  const supabase = await createClient()

  const { data: profile } = await supabase
    .from('user_profiles')
    .select('email, roles ( code )')
    .eq('id', userId)
    .single()

  if (!profile) {
    return NextResponse.json({ error: 'User not found' }, { status: 404 })
  }

  // Backend privilege check — an admin must not generate a link for a user they
  // cannot manage (e.g. an admin for a masteradmin). Mirrors the invite route.
  const targetRoleCode = ((Array.isArray(profile.roles) ? (profile.roles as { code: string }[])[0] : (profile.roles as { code: string } | null))?.code ?? 'readonly') as RoleCode
  if (!canManageUser(session, targetRoleCode)) {
    return NextResponse.json({ error: 'Insufficient privileges' }, { status: 403 })
  }

  const email = profile.email as string

  const { origin } = new URL(request.url)
  const link = await generateRecoveryLink(email, origin, '/auth/change-password')
  if (!link) {
    return routeError('Einladungs-Link konnte nicht erzeugt werden.', null)
  }

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

  // Returned to the requesting admin only; never persisted.
  return NextResponse.json({ ok: true, email, link })
}
