// ST-1006: POST /api/auth/pair/claim — desktop ruilt zijn pre-auth cookie
// (s4m_pair) in voor een echte iron-session na een succesvolle approve op de
// mobiele kant.
//
// Auth: alleen via de HttpOnly s4m_pair-cookie. Geen body-secret nodig — het
// cookie-token is het bewijs. Body bevat alleen pairingId.
//
// Atomicity: één UPDATE met WHERE-clausule die status én token-hash én niet-
// verlopen tegelijk eist. Concurrent dubbele claims: PostgreSQL row-locking
// zorgt dat exact één caller count=1 ziet, de rest count=0 → 410.

import { getIronSession } from 'iron-session'
import { cookies } from 'next/headers'
import { prisma } from '@/lib/prisma'
import { SessionData, sessionOptions } from '@/lib/session'
import { hashToken } from '@/lib/auth/pairing'
import { readPairCookie, clearPairCookie } from '@/lib/auth/pair-cookie'

export const runtime = 'nodejs'

const PAIRED_TTL_MS = 8 * 60 * 60 * 1000 // 8 uur — kortere TTL voor publieke desktops

interface ClaimBody {
  pairingId?: unknown
}

export async function POST(request: Request) {
  const desktopToken = await readPairCookie()
  if (!desktopToken) {
    return Response.json({ error: 'Geen pairing-cookie' }, { status: 401 })
  }

  let body: ClaimBody
  try {
    body = (await request.json()) as ClaimBody
  } catch {
    return Response.json({ error: 'Ongeldige JSON' }, { status: 400 })
  }
  const pairingId = typeof body?.pairingId === 'string' ? body.pairingId : null
  if (!pairingId) {
    return Response.json({ error: 'pairingId vereist' }, { status: 400 })
  }

  const desktopTokenHash = hashToken(desktopToken)

  // Atomic state-transitie: alleen rij die approved is + token-hash matcht +
  // niet verlopen wordt geconsumeerd.
  const updated = await prisma.loginPairing.updateMany({
    where: {
      id: pairingId,
      status: 'approved',
      desktop_token_hash: desktopTokenHash,
      expires_at: { gt: new Date() },
    },
    data: { status: 'consumed', consumed_at: new Date() },
  })

  if (updated.count !== 1) {
    // Disambigueer: bestaat de pairing wel met deze cookie? Zo ja → al consumed
    // of cancelled (410). Zo nee → cookie matcht geen pairing (401).
    const exists = await prisma.loginPairing.findFirst({
      where: { id: pairingId, desktop_token_hash: desktopTokenHash },
      select: { status: true },
    })
    await clearPairCookie()
    if (!exists) return Response.json({ error: 'Ongeldig' }, { status: 401 })
    return Response.json(
      { error: `Pairing al ${exists.status}` },
      { status: 410 },
    )
  }

  // Haal user-info op voor de iron-session payload.
  const pairing = await prisma.loginPairing.findUnique({
    where: { id: pairingId },
    select: { user_id: true, user: { select: { is_demo: true } } },
  })
  if (!pairing?.user_id) {
    await clearPairCookie()
    return Response.json({ error: 'Pairing zonder user' }, { status: 500 })
  }

  if (pairing.user?.is_demo) {
    await clearPairCookie()
    return Response.json({ error: 'Niet beschikbaar in demo-modus' }, { status: 403 })
  }

  const session = await getIronSession<SessionData>(await cookies(), sessionOptions)
  session.userId = pairing.user_id
  session.isDemo = pairing.user?.is_demo ?? false
  session.paired = true
  session.pairedExpiresAt = Date.now() + PAIRED_TTL_MS
  await session.save()

  await clearPairCookie()

  if (process.env.NODE_ENV !== 'production') {
    console.log(`[pair/claim] consumed pairingId=${pairingId}`)
  }

  return Response.json({ ok: true })
}
