import 'server-only'

import { randomBytes } from 'node:crypto'
import { createAdminClient } from '@/lib/supabase/admin'
import { logTripEvent } from '@/lib/audit'
import { syncTripToHha } from '@/lib/integrations/hha-trip-sync'
import {
  getSynchronPayments,
  isTrustedPaymentSource,
  SynchronApiNotConfiguredError,
  SynchronUnavailableError,
  type BillingContext,
  type CheckoutLine,
  type MockScenario,
  type PurchaseStatusReport,
} from '@/lib/integrations/synchron-payments'
import {
  canTransitionFulfillment,
  canTransitionPurchase,
  isCheckoutReopenable,
  lineTotal,
  purchaseReferenceFrom,
} from '@/lib/domain/purchases'
import { resolveRoutingProducts, type ResolvedProduct } from '@/lib/data/routing-products'
import { logPurchaseEvent } from '@/lib/data/purchase-events'
import type { PaymentReference, Permit, Purchase, PurchaseItem, PurchaseStatus, Trip, TripCart, TripCartItem } from '@/types/db'

/**
 * Route purchases (task §7–§12, §16, §26).
 *
 *   trip → cart → purchase (+ items, price snapshot) → checkout → VERIFIED
 *   confirmation → paid → routing released per item.
 *
 * `applyVerifiedPaymentEvent` is the ONLY function that sets `paid`.
 */

const admin = () => createAdminClient()

export interface PricedCartLine {
  id: string
  permit_id: string
  state_code: string | null
  product_code: string
  product_name: string
  route_type: 'express' | 'extended'
  quantity: number
  unit_price_cents: number
  line_total_cents: number
  currency: string
  product_version: number
  /** Present when the permit already has a route or an open request (task §16). */
  warning: string | null
}

export interface PricedCart {
  cart: TripCart
  items: PricedCartLine[]
  subtotal_cents: number
  total_cents: number
  currency: string
}

/* ---------------- Cart ---------------- */

export async function getOrCreateOpenCart(tripId: string, userId: string): Promise<TripCart> {
  const db = admin()
  const { data } = await db.from('trip_carts').select('*').eq('trip_id', tripId).eq('user_id', userId).eq('status', 'open').maybeSingle()
  if (data) return data as TripCart
  const { data: created, error } = await db.from('trip_carts').insert({ trip_id: tripId, user_id: userId }).select('*').single()
  if (error?.code === '23505') {
    const { data: again } = await db.from('trip_carts').select('*').eq('trip_id', tripId).eq('user_id', userId).eq('status', 'open').single()
    return again as TripCart
  }
  if (error || !created) throw new Error(`Could not open a cart: ${error?.message ?? 'unknown'}`)
  await logPurchaseEvent({ event: 'cart_created', tripId, actorUserId: userId, detail: { cart_id: (created as TripCart).id } })
  return created as TripCart
}

/** Price the cart from the catalog every time; nothing is cached in the cart. */
export async function priceCart(cart: TripCart): Promise<PricedCart> {
  const db = admin()
  const { data: rows } = await db.from('trip_cart_items').select('*').eq('cart_id', cart.id).order('added_at')
  const items = (rows ?? []) as TripCartItem[]
  if (items.length === 0) return { cart, items: [], subtotal_cents: 0, total_cents: 0, currency: 'USD' }

  const [products, permitsRes, requestsRes] = await Promise.all([
    resolveRoutingProducts(items.map((i) => i.product_code)),
    db.from('permits').select('id,state_code,route_processing_status,route_links,trip_id').in('id', items.map((i) => i.permit_id)),
    db.from('service_requests').select('id,state_code,type,status').eq('trip_id', cart.trip_id).eq('type', 'route_request').neq('status', 'cancelled'),
  ])
  const permits = new Map(((permitsRes.data ?? []) as Array<Pick<Permit, 'id' | 'state_code' | 'route_processing_status' | 'route_links' | 'trip_id'>>).map((p) => [p.id, p]))
  const openRouteStates = new Set(((requestsRes.data ?? []) as Array<{ state_code: string | null }>).map((r) => r.state_code).filter(Boolean))

  const priced: PricedCartLine[] = []
  for (const item of items) {
    const product = products.get(item.product_code)
    const permit = permits.get(item.permit_id)
    if (!product || !permit) continue // stale line: product retired or permit deleted
    const hasRoute = permit.route_processing_status === 'ready' && Array.isArray(permit.route_links) && permit.route_links.length > 0
    const warning = hasRoute
      ? 'This permit already has a route. Buying again orders a new routing service.'
      : permit.state_code && openRouteStates.has(permit.state_code)
        ? 'A route request for this state is already open on the trip.'
        : null
    priced.push({
      id: item.id,
      permit_id: item.permit_id,
      state_code: permit.state_code,
      product_code: product.product_code,
      product_name: product.product_name,
      route_type: product.route_type,
      quantity: item.quantity,
      unit_price_cents: product.unit_price_cents,
      line_total_cents: lineTotal(product.unit_price_cents, item.quantity),
      currency: product.currency,
      product_version: product.product_version,
      warning,
    })
  }
  const subtotal = priced.reduce((sum, l) => sum + l.line_total_cents, 0)
  return { cart, items: priced, subtotal_cents: subtotal, total_cents: subtotal, currency: priced[0]?.currency ?? 'USD' }
}

export type AddCartItemResult =
  | { ok: true; cart: PricedCart }
  | { ok: false; status: number; error: string }

export async function addCartItem(params: {
  trip: Trip
  userId: string
  actorLabel: string
  permitId: string
  productCode: string
  quantity?: number
  product: ResolvedProduct
}): Promise<AddCartItemResult> {
  const db = admin()
  const { data: permit } = await db.from('permits').select('id,trip_id,state_code,source_system').eq('id', params.permitId).maybeSingle()
  if (!permit || (permit as Permit).trip_id !== params.trip.id) return { ok: false, status: 400, error: 'That permit is not on this trip.' }
  // Synchron-processed permits include the route in the permit price (D5).
  if (params.trip.permit_policy === 'synchron_required' || (permit as Permit).source_system === 'synchron') {
    return { ok: false, status: 400, error: 'Routes are included for permits processed by Synchron Permits.' }
  }
  const cart = await getOrCreateOpenCart(params.trip.id, params.userId)
  const { error } = await db.from('trip_cart_items').upsert(
    { cart_id: cart.id, permit_id: params.permitId, product_code: params.productCode, quantity: params.quantity ?? 1 },
    { onConflict: 'cart_id,permit_id' },
  )
  if (error) return { ok: false, status: 500, error: 'Could not add the route to your cart.' }
  await logPurchaseEvent({
    event: 'item_added', tripId: params.trip.id, actorUserId: params.userId, actorLabel: params.actorLabel,
    detail: { cart_id: cart.id, permit_id: params.permitId, product_code: params.productCode, state_code: (permit as Permit).state_code },
  })
  return { ok: true, cart: await priceCart(cart) }
}

export async function removeCartItem(params: { trip: Trip; userId: string; actorLabel: string; itemId: string }): Promise<PricedCart | null> {
  const db = admin()
  const cart = await getOrCreateOpenCart(params.trip.id, params.userId)
  const { data: removed } = await db.from('trip_cart_items').delete().eq('id', params.itemId).eq('cart_id', cart.id).select('permit_id,product_code').maybeSingle()
  if (removed) {
    await logPurchaseEvent({
      event: 'item_removed', tripId: params.trip.id, actorUserId: params.userId, actorLabel: params.actorLabel,
      detail: { cart_id: cart.id, permit_id: (removed as TripCartItem).permit_id, product_code: (removed as TripCartItem).product_code },
    })
  }
  return priceCart(cart)
}

/* ---------------- Purchase creation ---------------- */

export interface PurchaseBundle {
  purchase: Purchase
  items: PurchaseItem[]
  payment: PaymentReference | null
}

export async function loadPurchase(purchaseId: string): Promise<PurchaseBundle | null> {
  const db = admin()
  const { data: purchase } = await db.from('purchases').select('*').eq('id', purchaseId).maybeSingle()
  if (!purchase) return null
  return loadBundle(purchase as Purchase)
}

export async function loadPurchaseByReference(reference: string): Promise<PurchaseBundle | null> {
  const db = admin()
  const { data: purchase } = await db.from('purchases').select('*').eq('purchase_reference', reference).maybeSingle()
  if (!purchase) return null
  return loadBundle(purchase as Purchase)
}

async function loadBundle(purchase: Purchase): Promise<PurchaseBundle> {
  const db = admin()
  const [items, payment] = await Promise.all([
    db.from('purchase_items').select('*').eq('purchase_id', purchase.id).order('created_at'),
    db.from('payment_references').select('*').eq('purchase_id', purchase.id).order('created_at', { ascending: false }).limit(1).maybeSingle(),
  ])
  return { purchase, items: (items.data ?? []) as PurchaseItem[], payment: (payment.data as PaymentReference | null) ?? null }
}

export async function listTripPurchases(tripId: string): Promise<PurchaseBundle[]> {
  const db = admin()
  const { data } = await db.from('purchases').select('*').eq('hha_trip_id', tripId).order('created_at', { ascending: false })
  const purchases = (data ?? []) as Purchase[]
  if (purchases.length === 0) return []
  const ids = purchases.map((p) => p.id)
  const [items, payments] = await Promise.all([
    db.from('purchase_items').select('*').in('purchase_id', ids).order('created_at'),
    db.from('payment_references').select('*').in('purchase_id', ids).order('created_at', { ascending: false }),
  ])
  const byPurchase = new Map<string, PurchaseItem[]>()
  for (const it of (items.data ?? []) as PurchaseItem[]) byPurchase.set(it.purchase_id, [...(byPurchase.get(it.purchase_id) ?? []), it])
  const paymentBy = new Map<string, PaymentReference>()
  for (const p of (payments.data ?? []) as PaymentReference[]) if (!paymentBy.has(p.purchase_id)) paymentBy.set(p.purchase_id, p)
  return purchases.map((purchase) => ({ purchase, items: byPurchase.get(purchase.id) ?? [], payment: paymentBy.get(purchase.id) ?? null }))
}

export type CreatePurchaseResult =
  | { ok: true; bundle: PurchaseBundle; reused: boolean }
  | { ok: false; status: number; error: string }

/**
 * Turn the open cart into a pending purchase. Idempotent on the cart id: the
 * same open cart can only ever become ONE purchase, so a double click or a
 * retried request returns the purchase that already exists (task §16, Test E).
 */
export async function createPurchaseFromCart(params: {
  trip: Trip
  userId: string
  actorLabel: string
  billing: BillingContext
  companyId: string | null
}): Promise<CreatePurchaseResult> {
  const db = admin()
  const cart = await getOrCreateOpenCart(params.trip.id, params.userId)
  const idempotencyKey = `cart:${cart.id}`

  const { data: existing } = await db.from('purchases').select('*').eq('idempotency_key', idempotencyKey).maybeSingle()
  if (existing) return { ok: true, bundle: await loadBundle(existing as Purchase), reused: true }

  const priced = await priceCart(cart)
  if (priced.items.length === 0) return { ok: false, status: 400, error: 'Your cart is empty.' }

  const purchaseRow = {
    hha_user_id: params.userId,
    company_id: params.companyId,
    hha_trip_id: params.trip.id,
    synchron_order_token: params.billing.synchronOrderToken,
    synchron_user_token: params.billing.synchronUserToken,
    purchase_type: 'route' as const,
    subtotal_cents: priced.subtotal_cents,
    total_amount_cents: priced.total_cents,
    currency: priced.currency,
    purchase_status: 'pending_checkout' as PurchaseStatus,
    purchase_reference: purchaseReferenceFrom(randomBytes(20)),
    idempotency_key: idempotencyKey,
  }
  const { data: inserted, error } = await db.from('purchases').insert(purchaseRow).select('*').single()
  if (error?.code === '23505') {
    const { data: again } = await db.from('purchases').select('*').eq('idempotency_key', idempotencyKey).single()
    return { ok: true, bundle: await loadBundle(again as Purchase), reused: true }
  }
  if (error || !inserted) return { ok: false, status: 500, error: 'Could not create the purchase.' }
  const purchase = inserted as Purchase

  const itemRows = priced.items.map((l) => ({
    purchase_id: purchase.id,
    hha_permit_id: l.permit_id,
    product_code: l.product_code,
    route_type: l.route_type,
    unit_price_cents: l.unit_price_cents,
    quantity: l.quantity,
    line_total_cents: l.line_total_cents,
    currency: l.currency,
    product_version: l.product_version,
    fulfillment_status: 'awaiting_payment' as const,
  }))
  const { error: itemsError } = await db.from('purchase_items').insert(itemRows)
  if (itemsError) {
    // Never leave a purchase without its items: roll back the header.
    await db.from('purchases').delete().eq('id', purchase.id)
    return { ok: false, status: 500, error: 'Could not record the purchase items.' }
  }
  await db.from('trip_carts').update({ status: 'checked_out', purchase_id: purchase.id }).eq('id', cart.id)

  await logPurchaseEvent({
    event: 'purchase_submitted', purchaseId: purchase.id, tripId: params.trip.id, actorUserId: params.userId, actorLabel: params.actorLabel,
    synchronOrderToken: purchase.synchron_order_token, purchaseReference: purchase.purchase_reference,
    detail: { items: itemRows.length, total_cents: purchase.total_amount_cents, currency: purchase.currency, cart_id: cart.id },
  })
  return { ok: true, bundle: await loadBundle(purchase), reused: false }
}

/* ---------------- Checkout ---------------- */

export type CheckoutResult =
  | { ok: true; checkoutUrl: string; reused: boolean }
  | { ok: false; status: number; error: string; code: 'not_connected' | 'unavailable' | 'bad_state' | 'error' }

export async function requestCheckout(params: {
  bundle: PurchaseBundle
  billing: BillingContext
  actorUserId: string
  actorLabel: string
  appOrigin: string
  scenario?: MockScenario
}): Promise<CheckoutResult> {
  const db = admin()
  const { purchase, items, payment } = params.bundle
  if (!isCheckoutReopenable(purchase.purchase_status)) {
    return { ok: false, status: 409, error: 'This purchase can no longer be checked out.', code: 'bad_state' }
  }
  // A checkout that already exists is returned, never recreated (task §26).
  if (payment?.checkout_url && purchase.purchase_status === 'pending_payment') {
    await logPurchaseEvent({ event: 'customer_redirected', purchaseId: purchase.id, tripId: purchase.hha_trip_id, actorUserId: params.actorUserId, actorLabel: params.actorLabel, purchaseReference: purchase.purchase_reference, detail: { reused: true } })
    return { ok: true, checkoutUrl: payment.checkout_url, reused: true }
  }

  const permitIds = items.map((i) => i.hha_permit_id).filter((id): id is string => !!id)
  const { data: permits } = permitIds.length ? await db.from('permits').select('id,state_code').in('id', permitIds) : { data: [] }
  const stateBy = new Map(((permits ?? []) as Array<{ id: string; state_code: string | null }>).map((p) => [p.id, p.state_code]))
  const lines: CheckoutLine[] = items.map((i) => ({
    purchaseItemId: i.id, hhaPermitId: i.hha_permit_id, synchronPermitToken: i.synchron_permit_token,
    stateCode: i.hha_permit_id ? stateBy.get(i.hha_permit_id) ?? null : null,
    productCode: i.product_code, routeType: i.route_type, unitPriceCents: i.unit_price_cents, quantity: i.quantity, lineTotalCents: i.line_total_cents,
  }))
  const returnUrl = `${params.appOrigin}/purchases/${encodeURIComponent(purchase.purchase_reference)}/return`
  const request = {
    purchaseReference: purchase.purchase_reference, purchaseId: purchase.id, billing: params.billing,
    currency: purchase.currency, totalCents: purchase.total_amount_cents, lines,
    returnUrl, cancelUrl: `${returnUrl}?cancelled=1`,
  }
  await logPurchaseEvent({ event: 'checkout_requested', purchaseId: purchase.id, tripId: purchase.hha_trip_id, actorUserId: params.actorUserId, actorLabel: params.actorLabel, purchaseReference: purchase.purchase_reference, synchronOrderToken: purchase.synchron_order_token })

  const adapter = getSynchronPayments({ scenario: params.scenario, appOrigin: params.appOrigin })
  try {
    const created = await adapter.createRoutePurchase(request)
    const session = await adapter.requestRouteCheckout(request)
    await db.from('payment_references').insert({
      purchase_id: purchase.id,
      synchron_purchase_token: session.synchronPurchaseToken ?? created.synchronPurchaseToken,
      synchron_order_token: purchase.synchron_order_token,
      stripe_checkout_session_id: session.stripeCheckoutSessionId,
      payment_status: 'pending',
      source_system: adapter.mode === 'mock' ? 'mock' : 'synchron',
      checkout_url: session.checkoutUrl,
      last_synced_at: new Date().toISOString(),
    })
    await db.from('purchases').update({ purchase_status: 'pending_payment' }).eq('id', purchase.id)
    await logPurchaseEvent({ event: 'checkout_url_received', purchaseId: purchase.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, sourceSystem: adapter.mode === 'mock' ? 'mock' : 'synchron', detail: { session_id: session.stripeCheckoutSessionId } })
    await logPurchaseEvent({ event: 'customer_redirected', purchaseId: purchase.id, tripId: purchase.hha_trip_id, actorUserId: params.actorUserId, actorLabel: params.actorLabel, purchaseReference: purchase.purchase_reference })
    return { ok: true, checkoutUrl: session.checkoutUrl, reused: false }
  } catch (error) {
    const notConnected = error instanceof SynchronApiNotConfiguredError
    const unavailable = error instanceof SynchronUnavailableError
    await logPurchaseEvent({
      event: 'synchron_api_error', outcome: 'failed', purchaseId: purchase.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference,
      detail: { operation: 'requestRouteCheckout', type: error instanceof Error ? error.name : 'unknown', message: error instanceof Error ? error.message : String(error) },
    })
    // The purchase stays pending_checkout and recoverable; nothing is fabricated.
    if (notConnected) return { ok: false, status: 503, error: 'Payments through Synchron Permits are not connected yet. Your route selections are saved.', code: 'not_connected' }
    if (unavailable) return { ok: false, status: 503, error: 'Synchron Permits is unavailable right now. Your route selections are saved — please try again shortly.', code: 'unavailable' }
    return { ok: false, status: 500, error: 'Checkout could not be started. Your route selections are saved.', code: 'error' }
  }
}

/** Customer closed or abandoned checkout: preserve selections, mark cancelled. */
export async function cancelPurchase(bundle: PurchaseBundle, actor: { id: string; label: string }): Promise<void> {
  const { purchase } = bundle
  if (!canTransitionPurchase(purchase.purchase_status, 'cancelled')) return
  await admin().from('purchases').update({ purchase_status: 'cancelled' }).eq('id', purchase.id).eq('purchase_status', purchase.purchase_status)
  await admin().from('purchase_items').update({ fulfillment_status: 'cancelled' }).eq('purchase_id', purchase.id).eq('fulfillment_status', 'awaiting_payment')
  await logPurchaseEvent({ event: 'purchase_cancelled', purchaseId: purchase.id, tripId: purchase.hha_trip_id, actorUserId: actor.id, actorLabel: actor.label, purchaseReference: purchase.purchase_reference })
}

/* ---------------- Verified confirmation — the only path to `paid` ---------------- */

export interface VerifiedPaymentEvent {
  source: 'synchron' | 'mock'
  report: PurchaseStatusReport
  /** Who delivered it — for the audit row. */
  via: 'callback' | 'reconcile'
}

export type ApplyResult =
  | { ok: true; changed: boolean; status: PurchaseStatus }
  | { ok: false; reason: 'untrusted_source' | 'unknown_purchase' | 'duplicate' | 'bad_transition' | 'error' }

export async function applyVerifiedPaymentEvent(event: VerifiedPaymentEvent): Promise<ApplyResult> {
  if (!isTrustedPaymentSource(event.source)) {
    await logPurchaseEvent({ event: 'synchron_api_error', outcome: 'failed', sourceSystem: event.source, purchaseReference: event.report.purchaseReference, detail: { reason: 'untrusted_source', via: event.via } })
    return { ok: false, reason: 'untrusted_source' }
  }
  const bundle = await loadPurchaseByReference(event.report.purchaseReference)
  if (!bundle) return { ok: false, reason: 'unknown_purchase' }
  const { purchase } = bundle
  const db = admin()

  // Dedupe on the external event id BEFORE touching state (Test L).
  const fresh = await logPurchaseEvent({
    event: 'synchron_payment_verified', purchaseId: purchase.id, tripId: purchase.hha_trip_id, sourceSystem: event.source,
    purchaseReference: purchase.purchase_reference, synchronOrderToken: purchase.synchron_order_token, externalEventId: event.report.externalEventId,
    detail: { via: event.via, payment_status: event.report.paymentStatus, session_id: event.report.stripeCheckoutSessionId, intent_id: event.report.stripePaymentIntentId },
  })
  if (!fresh) {
    await logPurchaseEvent({ event: 'duplicate_event_ignored', outcome: 'skipped', purchaseId: purchase.id, tripId: purchase.hha_trip_id, sourceSystem: event.source, purchaseReference: purchase.purchase_reference, detail: { external_event_id: event.report.externalEventId } })
    return { ok: false, reason: 'duplicate' }
  }

  const target: PurchaseStatus | null =
    event.report.paymentStatus === 'paid' ? 'paid'
    : event.report.paymentStatus === 'failed' ? 'payment_failed'
    : event.report.paymentStatus === 'expired' ? 'expired'
    : event.report.paymentStatus === 'cancelled' ? 'cancelled'
    : event.report.paymentStatus === 'refunded' ? 'refunded'
    : event.report.paymentStatus === 'partially_refunded' ? 'partially_refunded'
    : null // pending: only refresh the reference

  await db.from('payment_references').upsert({
    ...(bundle.payment ? { id: bundle.payment.id } : {}),
    purchase_id: purchase.id,
    synchron_purchase_token: event.report.synchronPurchaseToken ?? bundle.payment?.synchron_purchase_token ?? null,
    synchron_order_token: purchase.synchron_order_token,
    stripe_checkout_session_id: event.report.stripeCheckoutSessionId ?? bundle.payment?.stripe_checkout_session_id ?? null,
    stripe_payment_intent_id: event.report.stripePaymentIntentId ?? bundle.payment?.stripe_payment_intent_id ?? null,
    stripe_charge_id: event.report.stripeChargeId ?? bundle.payment?.stripe_charge_id ?? null,
    payment_status: event.report.paymentStatus,
    payment_confirmed_at: event.report.paymentConfirmedAt ?? bundle.payment?.payment_confirmed_at ?? null,
    source_system: event.source,
    checkout_url: bundle.payment?.checkout_url ?? null,
    last_synced_at: new Date().toISOString(),
  })

  if (!target) {
    await logPurchaseEvent({ event: 'payment_pending', purchaseId: purchase.id, tripId: purchase.hha_trip_id, sourceSystem: event.source, purchaseReference: purchase.purchase_reference })
    return { ok: true, changed: false, status: purchase.purchase_status }
  }
  if (target === purchase.purchase_status) return { ok: true, changed: false, status: target }
  if (!canTransitionPurchase(purchase.purchase_status, target)) {
    await db.from('purchases').update({ needs_reconciliation: true }).eq('id', purchase.id)
    await logPurchaseEvent({ event: 'reconciliation_flagged', outcome: 'failed', purchaseId: purchase.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, detail: { from: purchase.purchase_status, to: target } })
    return { ok: false, reason: 'bad_transition' }
  }

  // Compare-and-set on the previous status so two racing deliveries cannot both win.
  const { data: updated } = await db.from('purchases').update({ purchase_status: target }).eq('id', purchase.id).eq('purchase_status', purchase.purchase_status).select('id').maybeSingle()
  if (!updated) return { ok: false, reason: 'error' }

  const common = { purchaseId: purchase.id, tripId: purchase.hha_trip_id, sourceSystem: event.source, purchaseReference: purchase.purchase_reference, synchronOrderToken: purchase.synchron_order_token }
  if (target === 'paid') {
    await logPurchaseEvent({ event: 'purchase_marked_paid', ...common, detail: { total_cents: purchase.total_amount_cents } })
    await releaseRoutingItems(bundle)
  } else if (target === 'payment_failed') {
    await logPurchaseEvent({ event: 'payment_failed', outcome: 'failed', ...common })
  } else if (target === 'cancelled') {
    await db.from('purchase_items').update({ fulfillment_status: 'cancelled' }).eq('purchase_id', purchase.id).eq('fulfillment_status', 'awaiting_payment')
    await logPurchaseEvent({ event: 'purchase_cancelled', ...common })
  } else if (target === 'expired') {
    await logPurchaseEvent({ event: 'purchase_expired', ...common })
  } else {
    await logPurchaseEvent({ event: 'refund_reported', ...common, detail: { status: target } })
  }
  return { ok: true, changed: true, status: target }
}

/* ---------------- Fulfillment: paid ≠ completed ---------------- */

/**
 * After a verified payment, each item becomes a route request the existing
 * routing pipeline understands (service_requests, type route_request). Paid
 * is not completed: the item moves to submitted_to_synchron and Synchron's
 * route delivery (existing permit processing / callbacks) completes it.
 */
async function releaseRoutingItems(bundle: PurchaseBundle): Promise<void> {
  const db = admin()
  const { purchase } = bundle
  const { data: buyer } = await db.from('profiles').select('full_name,email').eq('id', purchase.hha_user_id).maybeSingle()
  const label = (buyer as { full_name?: string; email?: string } | null)?.full_name || (buyer as { email?: string } | null)?.email || 'purchaser'

  for (const item of bundle.items) {
    if (!canTransitionFulfillment(item.fulfillment_status, 'ready_for_processing')) continue
    if (item.service_request_id) continue // already released (repeat delivery guard)
    const { data: permit } = item.hha_permit_id ? await db.from('permits').select('state_code').eq('id', item.hha_permit_id).maybeSingle() : { data: null }
    const baseRow = {
      trip_id: purchase.hha_trip_id,
      type: 'route_request',
      state_code: (permit as { state_code?: string | null } | null)?.state_code ?? null,
      notes: `Purchased route · ${purchase.purchase_reference}`,
      requested_by: purchase.hha_user_id,
      requester_label: label,
      route_type: item.route_type,
      notify: null,
      paid_with: 'card',
      payer: null,
      ...(purchase.synchron_order_token ? { vendor_order_id: purchase.synchron_order_token, status: 'in_progress' } : {}),
    }
    const { data: request, error } = await db.from('service_requests').insert(baseRow).select('id').single()
    if (error || !request) {
      await db.from('purchase_items').update({ fulfillment_status: 'failed' }).eq('id', item.id)
      await logPurchaseEvent({ event: 'synchron_api_error', outcome: 'failed', purchaseId: purchase.id, purchaseItemId: item.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, detail: { operation: 'releaseRoutingItems', message: error?.message ?? 'insert failed' } })
      continue
    }
    await db.from('purchase_items').update({ service_request_id: request.id, fulfillment_status: 'submitted_to_synchron' }).eq('id', item.id)
    await logPurchaseEvent({ event: 'routing_item_released', purchaseId: purchase.id, purchaseItemId: item.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, synchronOrderToken: purchase.synchron_order_token, detail: { service_request_id: request.id, state_code: baseRow.state_code, route_type: item.route_type } })
    await logTripEvent({
      tripId: purchase.hha_trip_id, actorId: purchase.hha_user_id, actorLabel: label, action: 'service_requested',
      detail: { type: 'route_request', state_code: baseRow.state_code, paid_with: 'card', purchase_reference: purchase.purchase_reference },
    })
  }
  const sync = await syncTripToHha(purchase.hha_trip_id)
  if (!sync.ok) console.error('Purchase release trip sync failed:', sync.error)
}

/** Reconcile one purchase against Synchron (cron, admin button, return page). */
export async function reconcilePurchase(params: { bundle: PurchaseBundle; billing: BillingContext; appOrigin: string; scenario?: MockScenario; actorLabel?: string }): Promise<ApplyResult> {
  const adapter = getSynchronPayments({ scenario: params.scenario, appOrigin: params.appOrigin })
  const { purchase } = params.bundle
  await logPurchaseEvent({ event: 'reconciliation_run', outcome: 'started', purchaseId: purchase.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, actorLabel: params.actorLabel ?? 'system' })
  try {
    const report = await adapter.reconcilePurchaseStatus(purchase.purchase_reference, params.billing)
    return applyVerifiedPaymentEvent({ source: adapter.mode === 'mock' ? 'mock' : 'synchron', report, via: 'reconcile' })
  } catch (error) {
    await logPurchaseEvent({ event: 'synchron_api_error', outcome: 'failed', purchaseId: purchase.id, tripId: purchase.hha_trip_id, purchaseReference: purchase.purchase_reference, detail: { operation: 'reconcilePurchaseStatus', type: error instanceof Error ? error.name : 'unknown', message: error instanceof Error ? error.message : String(error) } })
    return { ok: false, reason: 'error' }
  }
}

/** Billing context for a purchase that already exists (cron/admin paths have no session). */
export async function billingForPurchase(bundle: PurchaseBundle): Promise<BillingContext> {
  const db = admin()
  const { purchase } = bundle
  const [{ data: company }] = await Promise.all([
    purchase.company_id ? db.from('companies').select('source_token').eq('id', purchase.company_id).maybeSingle() : Promise.resolve({ data: null }),
  ])
  return {
    hhaUserId: purchase.hha_user_id,
    hhaCompanyId: purchase.company_id,
    synchronUserToken: purchase.synchron_user_token,
    synchronCarrierToken: (company as { source_token?: string | null } | null)?.source_token ?? null,
    synchronOrderToken: purchase.synchron_order_token,
    hhaTripId: purchase.hha_trip_id,
  }
}
