import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { cascadeSimulateSchema, type CascadeSimulateInput } from '@/lib/api/schemas'
import { toPerturbation } from '@/lib/api/overlay'
import { listCascadeRuns, persistCascade, runCascade } from '@/lib/services/cascade-service'

export const dynamic = 'force-dynamic'

/** Stored cascade runs, for the Domino View history panel. */
export const GET = apiRoute({ permission: 'simulations.read' }, async ({ searchParams }) => {
  const limit = Math.min(50, Math.max(1, Number(searchParams.get('limit')) || 20))
  const runs = await listCascadeRuns(limit)
  return {
    runs: runs.map((run) => ({
      code: run.code,
      originCode: run.originCode,
      ts: run.ts.getTime(),
      affectedAssets: run.affectedAssets,
      affectedCustomers: run.affectedCustomers,
      maxDepth: run.maxDepth,
      regionalRisk: run.regionalRisk,
      summary: run.summary,
      summaryAr: run.summaryAr,
      steps: run.steps.map((step) => ({
        ordinal: step.ordinal,
        depth: step.depth,
        offsetMin: step.offsetMin,
        assetCode: step.assetCode,
        assetName: step.assetName,
        assetNameAr: step.assetNameAr,
        mechanism: step.mechanism,
        effect: step.effect,
        loadPct: step.loadPct,
        probability: step.probability,
        severity: step.severity,
        customers: step.customers,
      })),
    })),
  }
})

/** Walk a cascade from one asset (§5, §6). */
export const POST = apiRoute<Record<string, string>, CascadeSimulateInput>(
  { permission: 'cascade.run', bodySchema: cascadeSimulateSchema, limit: 40 },
  async ({ body, user, request }) => {
    const run = await runCascade(body.assetCode, {
      perturbation: toPerturbation(body.overlay),
      horizonMin: body.horizonMin,
    })
    if (!run) throw new ApiError(ERROR_CODES.notFound)

    let code: string | null = null
    if (body.persist) code = await persistCascade(run, { userId: user.id })

    await writeAudit({
      action: AUDIT_ACTIONS.cascadeSimulated,
      entity: 'asset',
      entityId: body.assetCode,
      user,
      request,
      detail: `${run.result.affectedAssets} assets, ${run.result.affectedCustomers} customers, depth ${run.result.maxDepth}`,
    })

    return { code, summary: run.summary, summaryAr: run.summaryAr, ...run.result }
  },
)
