import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { modelTransitionSchema, type ModelTransitionInput } from '@/lib/api/schemas'
import {
  assessModelDrift,
  listDriftEvents,
  listModelAudit,
  listModels,
  recordDrift,
  transitionModel,
} from '@/lib/services/governance-service'

export const dynamic = 'force-dynamic'

/** Models, drift signals and the change log (§81, §82, §83). */
export const GET = apiRoute({ permission: 'governance.read' }, async ({ searchParams }) => {
  const modelKey = searchParams.get('model') ?? undefined
  const [models, report, events, audit] = await Promise.all([
    listModels(),
    assessModelDrift({ modelKey }),
    listDriftEvents({ limit: 20 }),
    listModelAudit(20),
  ])

  if (searchParams.get('record') === '1' && !report.underpowered) {
    await recordDrift(modelKey ?? 'nabdh-engine', report.verdict.signals)
  }

  return {
    models,
    drift: report,
    events,
    audit: audit.map((entry) => ({
      id: entry.id,
      action: entry.action,
      actor: entry.actor,
      detail: entry.detail,
      detailAr: entry.detailAr,
      model: `${entry.modelVersion.name} ${entry.modelVersion.version}`,
      ts: entry.ts.getTime(),
    })),
  }
})

/**
 * Move a model through its lifecycle (§83).
 *
 * The transition table is enforced server-side: a client asking to jump straight from
 * draft to active is refused, not accommodated.
 */
export const PATCH = apiRoute<Record<string, string>, ModelTransitionInput>(
  { permission: 'governance.manage', bodySchema: modelTransitionSchema, limit: 20 },
  async ({ body, user, request }) => {
    const result = await transitionModel({
      modelId: body.modelId,
      next: body.next,
      userId: user.id,
      note: body.note,
    })

    if (!result.ok) {
      throw new ApiError(
        result.reason === 'not_found' ? ERROR_CODES.notFound : ERROR_CODES.conflict,
      )
    }

    await writeAudit({
      action: AUDIT_ACTIONS.modelTransitioned,
      entity: 'model_version',
      entityId: body.modelId,
      user,
      request,
      detail: `→ ${body.next}`,
    })

    return { ok: true }
  },
)
