import { NextResponse } from 'next/server'
import { getSession } from '@/lib/auth'
import { db } from '@/lib/db'
import { saveAudio } from '@/lib/media'

export const runtime = 'nodejs'

// Same floor as /api/captures: below this a file cannot be a recording.
const MIN_AUDIO_BYTES = 2048

// POST /api/quail/decisions/:id — Eric's answer, typed or spoken.
//
// He gives the GIST, not the reply: "yeah I've got those, they're friendly,
// tell them to text me about pickup." The loop writes the actual message in his
// voice with his number in it, because that is the typing he does not want to
// do. { dismiss: true } closes it without a reply.
export async function POST(req: Request, { params }: { params: Promise<{ id: string }> }) {
  const session = await getSession()
  if (!session) return NextResponse.json({ error: 'unauthorized' }, { status: 401 })

  const { id } = await params
  const row = await db.quailDecision.findUnique({ where: { id }, select: { id: true, state: true } })
  if (!row) return NextResponse.json({ error: 'not found' }, { status: 404 })

  let body: Record<string, unknown> = {}
  let audio: File | null = null
  if ((req.headers.get('content-type') || '').includes('multipart/form-data')) {
    const form = await req.formData()
    for (const [k, v] of form.entries()) if (typeof v === 'string') body[k] = v
    const a = form.get('audio')
    if (a instanceof File && a.size > MIN_AUDIO_BYTES) audio = a
  } else {
    body = await req.json().catch(() => ({}))
  }

  if (body.dismiss) {
    await db.quailDecision.update({ where: { id }, data: { state: 'DISMISSED', answeredAt: new Date() } })
    return NextResponse.json({ ok: true, state: 'DISMISSED' })
  }

  const answer = body.answer ? String(body.answer).trim().slice(0, 2000) : ''
  if (!answer && !audio) {
    return NextResponse.json({ error: 'say or type what to tell them' }, { status: 400 })
  }

  await db.quailDecision.update({
    where: { id },
    data: {
      // Spoken answers stay empty here and are filled in by the mini after
      // whisper reads them, so the card ends up showing his words either way.
      answer: answer || null,
      answerAudio: audio ? await saveAudio(Buffer.from(await audio.arrayBuffer()), audio.type || 'audio/webm') : null,
      answerMime: audio?.type || null,
      answeredAt: new Date(),
      state: 'ANSWERED',
    },
  })
  return NextResponse.json({ ok: true, state: 'ANSWERED' })
}
