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

const schema = z.object({
  message_id: z.string().uuid(),
  feedback: z.union([z.literal(1), z.literal(-1)]).optional(),
  // "Report this answer / ask for human review" — a trigger beyond 👎 (§5).
  report: z.boolean().optional(),
  reason: z.string().trim().max(60).optional().or(z.literal('')),
  comment: z.string().trim().max(1000).optional().or(z.literal('')),
})

/**
 * Thumbs-up / thumbs-down / report on an AI answer (participants only).
 * Negative feedback opens a REVIEW TICKET with full context — "feedback is
 * a review trigger, not truth": nothing auto-updates any knowledge; a human
 * moderator reviews it in the Moderator Dashboard.
 */
export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const requestId = tripAiRequestId(req)
  const { id: tripId } = await ctx.params
  await logTripAiEvent('feedback_received', { request_id: requestId, trip_id: tripId })
  const guard = await requireParticipant(tripId)
  if (!guard.ok) {
    await logTripAiEvent('feedback_denied', {
      request_id: requestId,
      trip_id: tripId,
      status: 'denied',
      http_status: guard.response.status,
    })
    return guard.response
  }
  const { user, participant } = guard

  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success || (parsed.data.feedback === undefined && !parsed.data.report)) {
    await logTripAiEvent('feedback_validation_failed', {
      request_id: requestId,
      trip_id: tripId,
      status: 'error',
    })
    return NextResponse.json({ error: 'Invalid feedback.' }, { status: 400 })
  }
  const input = parsed.data

  const admin = createAdminClient()

  if (input.feedback !== undefined) {
    const { error } = await admin
      .from('chat_messages')
      .update({ feedback: input.feedback })
      .eq('id', input.message_id)
      .eq('trip_id', tripId)
      .eq('is_ai', true)
    if (error) {
      await logTripAiEvent('feedback_save_failed', {
        request_id: requestId,
        trip_id: tripId,
        status: 'error',
        error_code: error.code,
      })
      return NextResponse.json({ error: 'Could not record feedback.' }, { status: 500 })
    }
  }

  // Thumbs down or report → review ticket with the answer's full context.
  if (input.feedback === -1 || input.report) {
    const { data: msg } = await admin
      .from('chat_messages')
      .select('*')
      .eq('id', input.message_id)
      .eq('trip_id', tripId)
      .eq('is_ai', true)
      .maybeSingle()
    if (msg) {
      await openReviewTicket({
        tripId,
        answer: msg,
        trigger: input.report ? 'reported' : 'thumbs_down',
        userId: user.id,
        userRole: participant.role,
        actorLabel: participant.name || user.email || 'participant',
        reason: input.reason || null,
        comment: input.comment || null,
      })
      await logTripAiEvent('feedback_review_ticket_requested', {
        request_id: requestId,
        trip_id: tripId,
        trigger: input.report ? 'reported' : 'thumbs_down',
      })
    }
  }

  await logTripAiEvent('feedback_completed', {
    request_id: requestId,
    trip_id: tripId,
    feedback: input.feedback,
    reported: input.report === true,
  })
  return NextResponse.json({ ok: true })
}
