import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { requireParticipant } from '@/lib/api-guard'
import { createAdminClient } from '@/lib/supabase/admin'
import { logTripAiEvent, tripAiRequestId } from '@/lib/observability/trip-ai-log'

const schema = z.object({
  role: z.enum(['user', 'assistant']),
  content: z.string().trim().min(1).max(10_000),
  answer_to_message_id: z.string().uuid().nullable().optional(),
})

export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const requestId = tripAiRequestId(req)
  const startedAt = Date.now()
  const { id: tripId } = await ctx.params
  await logTripAiEvent('voice_message_received', { request_id: requestId, trip_id: tripId })
  const guard = await requireParticipant(tripId)
  if (!guard.ok) {
    await logTripAiEvent('voice_message_denied', {
      request_id: requestId,
      trip_id: tripId,
      status: 'denied',
      http_status: guard.response.status,
    })
    return guard.response
  }

  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) {
    await logTripAiEvent('voice_message_validation_failed', {
      request_id: requestId,
      trip_id: tripId,
      status: 'error',
    })
    return NextResponse.json({ error: 'Invalid voice transcript.' }, { status: 400 })
  }

  const { role, content } = parsed.data
  const admin = createAdminClient()
  let answerTo: string | null = null
  if (role === 'assistant' && parsed.data.answer_to_message_id) {
    const { data: question } = await admin
      .from('chat_messages')
      .select('id')
      .eq('id', parsed.data.answer_to_message_id)
      .eq('trip_id', tripId)
      .eq('is_ai', false)
      .maybeSingle()
    answerTo = question?.id ?? null
  }

  const isPrivate = guard.participant.share_chat === false
  const privacy = isPrivate
    ? { is_private: true, private_for_user_id: guard.user.id }
    : {}
  const isAi = role === 'assistant'
  const { data: message, error } = await admin
    .from('chat_messages')
    .insert({
      trip_id: tripId,
      user_id: isAi ? null : guard.user.id,
      author_label: isAi
        ? 'HeavyHaul Agent'
        : guard.participant.name || guard.user.email || 'participant',
      author_role: isAi ? 'ai' : guard.participant.role,
      is_ai: isAi,
      content,
      state_code: null,
      permit_id: null,
      answer_to_message_id: isAi ? answerTo : null,
      ...privacy,
    })
    .select()
    .single()

  if (error || !message) {
    await logTripAiEvent('voice_message_save_failed', {
      request_id: requestId,
      trip_id: tripId,
      status: 'error',
      role,
      error_code: error?.code,
    })
    return NextResponse.json({ error: 'Could not save voice transcript.' }, { status: 500 })
  }
  await logTripAiEvent('voice_message_saved', {
    request_id: requestId,
    trip_id: tripId,
    message_id: message.id,
    role,
    transcript_chars: content.length,
    is_private: isPrivate,
    answer_linked: Boolean(answerTo),
    duration_ms: Date.now() - startedAt,
  })
  return NextResponse.json({ message })
}
