import 'server-only'

import { createAdminClient } from '@/lib/supabase/admin'
import { isMissingColumn } from '@/lib/db-compat'
import { logTripEvent } from '@/lib/audit'
import { sendPermitRequestToSynchron } from '@/lib/data/permit-request-email'
import { syncTripToHha } from '@/lib/integrations/hha-trip-sync'
import type { Permit, ServiceRequest, Trip, TripParticipant } from '@/types/db'

/**
 * The "record a service request and tell Synchron" core of
 * `POST /api/trips/[id]/requests`, extracted (2026-09-29, task §9) so the
 * two-step Buy More Permits flow can submit the saved draft per state after
 * the card-on-file confirmation without re-entering the HTTP route.
 *
 * Validation (participant guard, rate confirmation, re-order permit lookup,
 * state code shape) stays with the callers; this function only does what
 * happens once the input is known-good, in the same order the route always
 * did: insert → trip sync → vendor link → audit → Synchron email.
 */
export interface CreatePermitRequestParams {
  tripId: string
  trip: Trip
  user: { id: string; email: string; name: string }
  participant: TripParticipant
  /** requester_label — participant name, else email. */
  label: string
  type: 'permit_request' | 'route_request'
  /** Already upper-cased two-letter code (or null for a route request without one). */
  stateCode: string | null
  notes: string | null
  routeType: 'express' | 'extended' | null
  notify: string[] | null
  paidWith: 'credit' | 'card' | null
  payer: 'requester' | 'broker' | 'carrier' | null
  replacedPermit: Permit | null
  /** publicOrigin(req) — for links inside the Synchron email. */
  origin: string
}

export type CreatePermitRequestResult =
  | { ok: true; request: ServiceRequest; email: { status: string; reason?: string; attachments: string[] } | null }
  | { ok: false; error: string }

export async function createPermitRequest(params: CreatePermitRequestParams): Promise<CreatePermitRequestResult> {
  const { tripId, trip, user, participant, label, replacedPermit, payer } = params
  const admin = createAdminClient()

  const baseRow = {
    trip_id: tripId,
    type: params.type,
    state_code: params.stateCode,
    notes: params.notes || null,
    requested_by: user.id,
    requester_label: label,
    route_type: params.routeType ?? null,
    notify: params.notify ?? null,
  }
  const newColumns = {
    paid_with: params.paidWith,
    payer,
    replaces_permit_id: replacedPermit?.id ?? null,
  }

  let { data: request, error } = await admin
    .from('service_requests')
    .insert({ ...baseRow, ...newColumns })
    .select()
    .single()
  if (isMissingColumn(error, 'paid_with', 'payer', 'replaces_permit_id')) {
    // Migration 0011 not applied — record the request without the new
    // columns rather than losing the order.
    ;({ data: request, error } = await admin.from('service_requests').insert(baseRow).select().single())
  }
  if (error || !request) {
    return { ok: false, error: 'Could not create the request.' }
  }

  // The order request is emailed to Synchron. GPT receives the current trip
  // snapshot for agent context; it does not invent a second Synchron order.
  const sync = await syncTripToHha(tripId)
  if (!sync.ok) console.error('Permit request trip sync failed:', sync.error)
  const vendorOrderId = trip.synchron_order_token ?? null
  if (vendorOrderId && params.type === 'permit_request') {
    const { error: linkError } = await admin.from('service_requests')
      .update({ vendor_order_id: vendorOrderId, status: 'in_progress' }).eq('id', request.id)
    if (!linkError) request = { ...request, vendor_order_id: vendorOrderId, status: 'in_progress' }
  }

  await logTripEvent({
    tripId,
    actorId: user.id,
    actorLabel: label,
    action: 'service_requested',
    detail: {
      type: params.type,
      state_code: baseRow.state_code,
      ...(newColumns.paid_with ? { paid_with: newColumns.paid_with } : {}),
      ...(payer ? { payer } : {}),
      ...(replacedPermit ? { replaces_permit: replacedPermit.permit_number ?? replacedPermit.id } : {}),
    },
  })

  // Nash, 2026-09-23: every permit request also goes to Synchron Permits by email — rate
  // confirmation and the previous permit for that state attached, dimensions and unit sheet in
  // the body, the requester copied. The request above is already recorded.
  let email: { status: string; reason?: string; attachments: string[] } | null = null
  if (params.type === 'permit_request' && trip && baseRow.state_code) {
    email = await sendPermitRequestToSynchron({
      trip, requestId: request.id, stateCode: baseRow.state_code, replacedPermit, participant, user,
      payer, notes: params.notes || null, orderNumber: vendorOrderId, origin: params.origin,
    })
  }

  return { ok: true, request: request as ServiceRequest, email }
}
