import 'server-only'

import { createAdminClient } from '@/lib/supabase/admin'
import { isMissingColumn } from '@/lib/db-compat'
import { classifyTicket } from '@/lib/domain/moderation'
import type { ChatMessage, ReviewTicket } from '@/types/db'

/**
 * Open a review ticket for an AI answer — the ONE place every trigger goes
 * through (§5): user thumbs-down, user report, and the AI-side signals
 * raised at answer time. Captures the full answer context (§6) and
 * auto-classifies priority + category (§10, §13). Feedback is a review
 * trigger, never truth: nothing here changes any knowledge.
 *
 * Tolerant of migration 0012 not being applied yet (falls back to the 0009
 * column set) so a thumbs-down never fails because of a missing column.
 */
export async function openReviewTicket(input: {
  tripId: string
  answer: Pick<
    ChatMessage,
    'id' | 'content' | 'state_code' | 'permit_id' | 'confidence' | 'sources' | 'created_at' | 'answer_to_message_id'
  >
  trigger: ReviewTicket['trigger']
  userId: string | null
  userRole: string | null
  actorLabel: string
  reason?: string | null
  comment?: string | null
}): Promise<{ ticketId: string | null }> {
  const admin = createAdminClient()

  // The question the answer responded to: the explicit link when present
  // (migration 0010), else the latest human message before the answer.
  let question: { id: string; content: string; created_at: string } | null = null
  if (input.answer.answer_to_message_id) {
    const { data } = await admin
      .from('chat_messages')
      .select('id, content, created_at')
      .eq('id', input.answer.answer_to_message_id)
      .maybeSingle()
    question = data
  }
  if (!question) {
    const { data } = await admin
      .from('chat_messages')
      .select('id, content, created_at')
      .eq('trip_id', input.tripId)
      .eq('is_ai', false)
      .lt('created_at', input.answer.created_at)
      .order('created_at', { ascending: false })
      .limit(1)
      .maybeSingle()
    question = data
  }

  // The asker's chat language (§11 "language used") — profile preference.
  let language: string | null = null
  if (input.userId) {
    const { data: profile } = await admin
      .from('profiles')
      .select('primary_language')
      .eq('id', input.userId)
      .maybeSingle()
    language = (profile?.primary_language as string | undefined) ?? null
  }

  const { category, priority } = classifyTicket(
    `${question?.content ?? ''} ${input.answer.content} ${input.reason ?? ''}`,
  )

  const base = {
    trip_id: input.tripId,
    message_id: input.answer.id,
    question_message_id: question?.id ?? null,
    user_id: input.userId,
    user_role: input.userRole,
    state_code: input.answer.state_code,
    permit_id: input.answer.permit_id,
    confidence: input.answer.confidence,
    trigger: input.trigger,
    feedback_reason: input.reason || null,
    user_comment: input.comment || null,
    category,
    priority,
    audience: input.userRole,
    sources: input.answer.sources,
  }
  const extras = {
    language,
    response_ms: question
      ? Math.max(
          0,
          new Date(input.answer.created_at).getTime() - new Date(question.created_at).getTime(),
        )
      : null,
  }

  let { data: ticket, error } = await admin
    .from('review_tickets')
    .insert({ ...base, ...extras })
    .select('id')
    .single()
  if (error && (isMissingColumn(error, 'language', 'response_ms') || /trigger/.test(error.message))) {
    // Migration 0012 not applied: drop the new columns; AI-side triggers can't
    // be stored under the old check constraint, so those are skipped.
    if (input.trigger !== 'thumbs_down' && input.trigger !== 'reported') return { ticketId: null }
    ;({ data: ticket, error } = await admin.from('review_tickets').insert(base).select('id').single())
  }
  if (error || !ticket) {
    console.warn('review ticket not created:', error?.message)
    return { ticketId: null }
  }

  await admin.from('ticket_events').insert({
    ticket_id: ticket.id,
    actor: input.actorLabel,
    action: 'ticket_created',
    detail: { trigger: input.trigger, reason: input.reason || null },
  })
  return { ticketId: ticket.id }
}
