import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { proofCreateSchema, type ProofCreateInput } from '@/lib/api/schemas'
import { toPerturbation } from '@/lib/api/overlay'
import { buildProof, getReplay } from '@/lib/services/proof-service'

export const dynamic = 'force-dynamic'

/** Read a frozen proof and everything attached to it. */
export const GET = apiRoute<{ code: string }>(
  { permission: 'proof.read' },
  async ({ params }) => {
    const replay = await getReplay(params.code)
    if (!replay) throw new ApiError(ERROR_CODES.notFound)
    return replay
  },
)

/**
 * Freeze the current analysis into a proof.
 *
 * The path segment is the asset the proof is about; `decisionCode` in the body attaches
 * it to a recorded decision when there is one.
 */
export const POST = apiRoute<{ code: string }, ProofCreateInput>(
  { permission: 'proof.create', bodySchema: proofCreateSchema, limit: 20 },
  async ({ params, body, user, request }) => {
    const proof = await buildProof({
      assetCode: body.assetCode || params.code,
      decisionCode: body.decisionCode ?? null,
      twinCode: body.twinCode ?? null,
      perturbation: toPerturbation(body.overlay),
      userId: user.id,
    })
    if (!proof) throw new ApiError(ERROR_CODES.notFound)

    await writeAudit({
      action: AUDIT_ACTIONS.proofCreated,
      entity: 'decision_proof',
      entityId: proof.code,
      user,
      request,
      detail: `${proof.frameCount} timeline events; weakest link ${proof.weakestLinkKey || 'none'} at ${proof.weakestLinkScore} %`,
    })

    return proof
  },
)
