import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { resolveBillingContext } from '@/lib/data/billing-context'
import { loadOwnDraft, permitPaymentReturnUrl, requirePermitRequester, updateDraft } from '@/lib/data/permit-request-drafts'
import { logPurchaseEvent } from '@/lib/data/purchase-events'
import { publicOrigin } from '@/lib/app-url'
import {
  getSynchronPayments,
  mockScenario,
  SynchronApiNotConfiguredError,
  SynchronUnavailableError,
} from '@/lib/integrations/synchron-payments'

const schema = z.object({ draft_id: z.string().uuid(), card_id: z.string().trim().min(1).max(200) })

/**
 * "Send permit order" with a card on file (D4): the customer picked a card;
 * Synchron's hosted page takes the CVV. HHA never renders that field.
 */
export async function POST(req: NextRequest, ctx: { params: Promise<{ id: string }> }) {
  const { id: tripId } = await ctx.params
  const access = await requirePermitRequester(tripId)
  if (!access.ok) return access.response
  const { user } = access.guard

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

  const own = await loadOwnDraft(parsed.data.draft_id, tripId, user.id)
  if (!own.ok) return own.response
  if (own.draft.status === 'submitted') return NextResponse.json({ error: 'This permit order was already sent.' }, { status: 409 })

  const billing = await resolveBillingContext(user, access.trip)
  if (!billing.ok) return NextResponse.json({ error: 'Not authorized to bill for this trip.' }, { status: 403 })

  try {
    const adapter = getSynchronPayments({ scenario: mockScenario(req), appOrigin: publicOrigin(req) })
    const returnUrl = permitPaymentReturnUrl(req, access.trip, own.draft.id)
    const session = await adapter.confirmCardUse(billing.billing, parsed.data.card_id, returnUrl)
    await updateDraft(own.draft.id, { readiness_status: 'setup_pending', setup_reference: session.setupReference })
    await logPurchaseEvent({
      event: 'card_setup_requested',
      tripId,
      actorUserId: user.id,
      sourceSystem: adapter.mode === 'mock' ? 'mock' : 'hha',
      synchronOrderToken: billing.billing.synchronOrderToken,
      detail: { draft_id: own.draft.id, setup_reference: session.setupReference, mode: 'confirm', card_id: parsed.data.card_id },
    })
    return NextResponse.json({ ok: true, setup_url: session.setupUrl, setup_reference: session.setupReference })
  } catch (error) {
    if (error instanceof SynchronApiNotConfiguredError || error instanceof SynchronUnavailableError) {
      await logPurchaseEvent({ event: 'synchron_api_error', tripId, actorUserId: user.id, outcome: 'failed', detail: { operation: 'confirmCardUse', reason: error.name } })
      return NextResponse.json({ error: 'Synchron Permits is unavailable right now. Your request is saved — please try again shortly.' }, { status: 503 })
    }
    throw error
  }
}
