import 'server-only'

import { NextResponse } from 'next/server'
import { getSessionUser, type SessionUser } from '@/lib/auth'
import { requireParticipant } from '@/lib/api-guard'
import { canRequestServices } from '@/lib/domain/permissions'
import { createAdminClient } from '@/lib/supabase/admin'
import { loadPurchase, type PurchaseBundle } from '@/lib/data/purchases'
import type { Trip } from '@/types/db'

/**
 * Shared guards for the route-purchase API (task §8.2, §23).
 *
 *   requireCartAccess    — participant who may request services + the trip row.
 *   requirePurchaseOwner — signed-in owner of the purchase, or an admin.
 */

export type CartGuard =
  | { ok: true; user: SessionUser; trip: Trip; actorLabel: string }
  | { ok: false; response: NextResponse }

export function actorLabelFor(user: SessionUser): string {
  return user.name || user.email
}

export async function requireCartAccess(tripId: string): Promise<CartGuard> {
  const guard = await requireParticipant(tripId)
  if (!guard.ok) return guard
  if (!canRequestServices(guard.participant.role)) {
    return { ok: false, response: NextResponse.json({ error: 'You cannot purchase routes on this trip.' }, { status: 403 }) }
  }
  const trip = await loadTrip(tripId)
  if (!trip) return { ok: false, response: NextResponse.json({ error: 'Trip not found.' }, { status: 404 }) }
  return { ok: true, user: guard.user, trip, actorLabel: actorLabelFor(guard.user) }
}

export async function loadTrip(tripId: string): Promise<Trip | null> {
  const { data } = await createAdminClient().from('trips').select('*').eq('id', tripId).maybeSingle()
  return (data as Trip | null) ?? null
}

export type PurchaseOwnerGuard =
  | { ok: true; user: SessionUser; bundle: PurchaseBundle; actorLabel: string }
  | { ok: false; response: NextResponse }

export async function requirePurchaseOwner(purchaseId: string): Promise<PurchaseOwnerGuard> {
  const user = await getSessionUser()
  if (!user) return { ok: false, response: NextResponse.json({ error: 'Sign in first.' }, { status: 401 }) }
  const bundle = await loadPurchase(purchaseId)
  if (!bundle) return { ok: false, response: NextResponse.json({ error: 'Purchase not found.' }, { status: 404 }) }
  if (user.role !== 'admin' && bundle.purchase.hha_user_id !== user.id) {
    return { ok: false, response: NextResponse.json({ error: 'You cannot act on this purchase.' }, { status: 403 }) }
  }
  return { ok: true, user, bundle, actorLabel: actorLabelFor(user) }
}
