import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { adversarialSchema, type AdversarialInput } from '@/lib/api/schemas'
import { listAdversarialTests, runAdversarialTest } from '@/lib/services/discovery-service'

export const dynamic = 'force-dynamic'

export const GET = apiRoute({ permission: 'discovery.read' }, async ({ searchParams }) => {
  const limit = Math.min(30, Math.max(1, Number(searchParams.get('limit')) || 10))
  const tests = await listAdversarialTests(limit)
  return { tests: tests.map((test) => ({ ...test, createdAt: test.createdAt.getTime() })) }
})

/**
 * "What is the least unusual thing that breaks this?" (§23, §107).
 *
 * Sandbox-only by construction: the search evaluates the model and writes to
 * `adversarial_tests`. There is no path from here to a live table.
 */
export const POST = apiRoute<Record<string, string>, AdversarialInput>(
  { permission: 'resilience.run', bodySchema: adversarialSchema, limit: 12 },
  async ({ body, user, request }) => {
    const outcome = await runAdversarialTest({
      assetCode: body.assetCode,
      targetRisk: body.targetRisk,
      persist: true,
      userId: user.id,
    })
    if (!outcome) throw new ApiError(ERROR_CODES.notFound)

    await writeAudit({
      action: AUDIT_ACTIONS.adversarialRun,
      entity: 'asset',
      entityId: body.assetCode,
      user,
      request,
      detail: outcome.summary,
    })

    return outcome
  },
)
