import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { requireParticipant } from '@/lib/api-guard'
import { createAdminClient } from '@/lib/supabase/admin'
import { logTripEvent } from '@/lib/audit'
import { ensureParticipantContext, evaluateParticipantRules } from '@/lib/data/auto-participants'
import { contextLabel, findContext } from '@/lib/domain/modes'
import { tripRoleForRoleType } from '@/lib/domain/auto-participants'
import type { TripParticipant } from '@/types/db'

/**
 * Per-trip context (decision D13, 2026-09-30): which company and role does
 * the caller act with on this trip? GET lists the choices; POST stores one and
 * runs the Auto-Participant rules that were waiting for it.
 */
export async function GET(_req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const { id: tripId } = await ctx.params
  const guard = await requireParticipant(tripId)
  if (!guard.ok) return guard.response
  if (!guard.row) return NextResponse.json({ status: 'set', choices: [] })
  const res = await ensureParticipantContext(guard.row, { id: guard.user.id, originId: guard.user.originId, preview: guard.user.previewWorkspace, contextKey: guard.user.contextKey })
  return NextResponse.json({
    status: res.status,
    choices: (res.choices ?? []).map((c) => ({ key: c.key, label: contextLabel(c), role_type: c.roleType, company_id: c.companyId, company_name: c.companyName })),
  })
}

const schema = z.object({ context_key: z.string().min(1).max(200) })

export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const { id: tripId } = await ctx.params
  const guard = await requireParticipant(tripId)
  if (!guard.ok) return guard.response
  if (!guard.row) return NextResponse.json({ error: 'Admins act on trips without a participant context.' }, { status: 409 })
  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) return NextResponse.json({ error: 'Choose a workspace.' }, { status: 400 })
  const session = { id: guard.user.id, originId: guard.user.originId, preview: guard.user.previewWorkspace, contextKey: guard.user.contextKey }
  const res = await ensureParticipantContext(guard.row, session)
  if (res.status !== 'pending') return NextResponse.json({ ok: true, status: res.status })
  const chosen = findContext(res.choices ?? [], parsed.data.context_key)
  if (!chosen) return NextResponse.json({ error: 'That workspace is not one of your choices for this trip.' }, { status: 400 })

  const admin = createAdminClient()
  // A company-rule member choosing among roles at that company may switch the trip role (A11).
  const nextRole = tripRoleForRoleType(chosen.roleType)
  const patch: Partial<TripParticipant> = { context_company_id: chosen.companyId, context_role_type: chosen.roleType }
  if (nextRole && nextRole !== guard.row.role && guard.row.context_company_id) patch.role = nextRole
  const { data, error } = await admin.from('trip_participants').update(patch).eq('id', guard.row.id).select('*').maybeSingle()
  if (error) return NextResponse.json({ error: 'Could not save your choice.' }, { status: 500 })
  await logTripEvent({ tripId, actorId: guard.user.id, actorLabel: guard.user.name || guard.user.email, action: 'participant_context_chosen', detail: { context_key: chosen.key, role_type: chosen.roleType, company_id: chosen.companyId } })
  const row = (data as TripParticipant | null) ?? { ...guard.row, ...patch }
  await evaluateParticipantRules({ tripId, participant: row, trigger: 'context_chosen', session })
  return NextResponse.json({ ok: true, status: 'set', role: row.role })
}
