import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { createAdminClient } from '@/lib/supabase/admin'
import { requireParticipant } from '@/lib/api-guard'
import { logTripEvent } from '@/lib/audit'
import { canManagePilotAccess, PILOT_REMOVED_ACTION } from '@/lib/domain/pilot'
import type { TripParticipant } from '@/types/db'

/**
 * Remove a pilot from the trip (Nash, 2026-09-17).
 *
 * "If I invited the pilot and he is not accepting it, and then I decide that
 * I need to terminate him… the person that initiated the invite should be
 * the one that has the power to cancel him. Even if you already shared the
 * permit and everything, he has the full power to remove the relation."
 *
 * Who: the person who invited THAT pilot, or an admin — `canManagePilotAccess`,
 * the same relation that governs sharing permits and requesting paperwork.
 *
 * What it does, in one place so nothing is half-removed:
 *   1. participant status → `removed` — every read path already filters it
 *      out, so the pilot vanishes from My Pilot, the dashboards' badges and
 *      the driver's state cards at once, and loses trip access.
 *   2. their open invitation is expired (`expires_at = now`) so the link in
 *      their inbox is dead — the accept route also refuses a removed row.
 *   3. `pilot_removed` is written to the trip history with who did it.
 */

const schema = z.object({ participant_id: z.string().uuid() })

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
  const { user, participant } = guard

  const parsed = schema.safeParse(await req.json().catch(() => ({})))
  if (!parsed.success) return NextResponse.json({ error: 'Invalid request.' }, { status: 400 })

  const admin = createAdminClient()
  const { data: pilotRow } = await admin
    .from('trip_participants')
    .select('*')
    .eq('id', parsed.data.participant_id)
    .eq('trip_id', tripId)
    .maybeSingle()
  const pilot = pilotRow as TripParticipant | null
  if (!pilot) return NextResponse.json({ error: 'That pilot is not on this trip.' }, { status: 404 })
  if (pilot.role !== 'pilot') return NextResponse.json({ error: 'Only a pilot can be removed here.' }, { status: 400 })
  if (pilot.status === 'removed') return NextResponse.json({ ok: true, already: true })

  if (!canManagePilotAccess({ pilotInvitedBy: pilot.invited_by, viewerUserId: user.id, viewerIsAdmin: user.role === 'admin' })) {
    return NextResponse.json({ error: 'Only the person who invited this pilot can remove them from the trip.' }, { status: 403 })
  }

  const now = new Date().toISOString()
  const { error } = await admin.from('trip_participants').update({ status: 'removed' }).eq('id', pilot.id)
  if (error) return NextResponse.json({ error: 'Could not remove the pilot.' }, { status: 500 })

  // Dead link: an unaccepted invitation for this row expires this instant.
  await admin
    .from('trip_invitations')
    .update({ expires_at: now })
    .eq('participant_id', pilot.id)
    .is('accepted_at', null)

  await logTripEvent({
    tripId,
    actorId: user.id,
    actorLabel: participant.name || user.name || user.email,
    action: PILOT_REMOVED_ACTION,
    detail: {
      email: pilot.email,
      name: pilot.name,
      participant_id: pilot.id,
      was_status: pilot.status,
      removed_by_role: participant.role,
    },
  })

  return NextResponse.json({ ok: true })
}
