import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { demoControlSchema, type DemoControlInput } from '@/lib/api/schemas'
import { getLocale } from '@/lib/i18n/server'
import { DEMO_STAGE_COUNT } from '@/lib/demo/config'
import { advanceDemoRun, getDemoState, startDemoRun } from '@/lib/services/demo-service'

export const dynamic = 'force-dynamic'

/** Read the state for a stage without changing anything. */
export const GET = apiRoute({ permission: 'demo.run' }, async ({ searchParams }) => {
  const stage = Math.min(DEMO_STAGE_COUNT, Math.max(1, Number(searchParams.get('stage')) || 1))
  const locale = await getLocale()
  return getDemoState(stage, locale, { runCode: searchParams.get('run'), running: true })
})

/**
 * Drive the demo.
 *
 * Stage transitions are audited like any other operator action — a demonstration that
 * leaves no trace would be the one place in the platform where something happened and
 * nothing was recorded.
 */
export const POST = apiRoute<Record<string, string>, DemoControlInput>(
  { permission: 'demo.run', bodySchema: demoControlSchema, limit: 120 },
  async ({ body, user, request, searchParams }) => {
    const locale = await getLocale()
    const currentRun = searchParams.get('run')
    const currentStage = Math.min(
      DEMO_STAGE_COUNT,
      Math.max(1, Number(searchParams.get('stage')) || 1),
    )

    let stage = currentStage
    let runCode = currentRun

    switch (body.action) {
      case 'start':
        stage = 1
        runCode = await startDemoRun(user.id)
        await writeAudit({
          action: AUDIT_ACTIONS.demoStarted,
          entity: 'demo_run',
          entityId: runCode,
          user,
          request,
        })
        break
      case 'next':
        stage = Math.min(DEMO_STAGE_COUNT, currentStage + 1)
        break
      case 'previous':
        stage = Math.max(1, currentStage - 1)
        break
      case 'goto':
        stage = Math.min(DEMO_STAGE_COUNT, Math.max(1, body.stage ?? 1))
        break
      case 'reset':
        stage = 1
        break
    }

    if (runCode && body.action !== 'start') {
      await advanceDemoRun(runCode, stage)
      await writeAudit({
        action: AUDIT_ACTIONS.demoAdvanced,
        entity: 'demo_run',
        entityId: runCode,
        user,
        request,
        detail: `stage ${stage}/${DEMO_STAGE_COUNT}`,
      })
    }

    return getDemoState(stage, locale, { runCode, running: true })
  },
)
