import { NextRequest, NextResponse } from 'next/server'
import { z } from 'zod'
import { requireSurfaceApi } from '@/lib/auth/surface-guard'
import { createAdminClient } from '@/lib/supabase/admin'
import { billingForPurchase, loadPurchase, reconcilePurchase } from '@/lib/data/purchases'
import { logPurchaseEvent } from '@/lib/data/purchase-events'
import { mockScenario } from '@/lib/integrations/synchron-payments'
import { publicOrigin } from '@/lib/app-url'

/**
 * Admin purchase reconciliation actions (2026-09-29 task §24, Task 11.1).
 *
 * ops:
 *   reconcile  ask Synchron for the purchase status again and apply it through
 *              the same verified path a callback uses (applyVerifiedPaymentEvent)
 *   flag       set purchases.needs_reconciliation = true
 *   unflag     clear it
 *
 * There is deliberately NO "mark as paid": only a verified Synchron (or, in
 * development, mock) confirmation can move a purchase to `paid`.
 */

const schema = z.object({
  op: z.enum(['reconcile', 'flag', 'unflag']),
  purchase_id: z.string().uuid(),
})

export async function POST(req: NextRequest) {
  const ip = req.headers.get('x-forwarded-for')?.split(',')[0]?.trim() ?? null
  const guard = await requireSurfaceApi('purchases', ip)
  if (!guard.ok) return guard.response
  const { actor } = guard

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

  const bundle = await loadPurchase(purchase_id)
  if (!bundle) return NextResponse.json({ error: 'Purchase not found.' }, { status: 404 })
  const { purchase } = bundle

  if (op === 'reconcile') {
    const result = await reconcilePurchase({
      bundle,
      billing: await billingForPurchase(bundle),
      appOrigin: publicOrigin(req),
      scenario: mockScenario(req),
      actorLabel: actor.label,
    })
    return NextResponse.json({ ok: result.ok, result })
  }

  const needs = op === 'flag'
  const { error } = await createAdminClient()
    .from('purchases')
    .update({ needs_reconciliation: needs })
    .eq('id', purchase.id)
  if (error) return NextResponse.json({ error: 'Could not update the purchase.' }, { status: 500 })
  await logPurchaseEvent({
    event: 'reconciliation_flagged',
    purchaseId: purchase.id,
    tripId: purchase.hha_trip_id,
    purchaseReference: purchase.purchase_reference,
    synchronOrderToken: purchase.synchron_order_token,
    actorUserId: actor.id,
    actorLabel: actor.label,
    detail: { needs_reconciliation: needs, action: needs ? 'flag' : 'clear' },
  })
  return NextResponse.json({ ok: true, needs_reconciliation: needs })
}
