import { AUDIT_ACTIONS, writeAudit } from '@/lib/audit'
import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { GRID_SCENARIOS, SCENARIO_KEYS } from '@/lib/engine/grid-scenarios'
import { demoBaseTimestamp } from '@/lib/demo/config'
import { getLiveGrid, getScenarioGrid } from '@/lib/services/live-grid-service'

export const dynamic = 'force-dynamic'

/**
 * The whole scene in one payload: topology, per-asset electrical state, solved flow, KPIs,
 * twin fidelity and the connection banner.
 *
 * One request rather than six because every figure on this screen has to describe the same
 * instant. A scene assembled from separate calls would show a load from one moment beside a
 * flow from another, and the disagreement would be invisible.
 */
export const GET = apiRoute(
  { permission: 'twin.read', limit: 120 },
  async ({ searchParams, user, request }) => {
    const scenario = searchParams.get('scenario')
    const twinCode = searchParams.get('twin') ?? undefined
    const offsetMin = Number(searchParams.get('offset')) || 0
    // Opt-in, never the default: the live console reads the live instant.
    const ts = searchParams.get('clock') === 'demo' ? demoBaseTimestamp() : undefined

    const payload = scenario && scenario !== 'normal'
      ? await getScenarioGrid(scenario, { twinCode, offsetMin, ts })
      : await getLiveGrid({ twinCode, offsetMin, ts })

    if (!payload) throw new ApiError(ERROR_CODES.notFound)

    // Audited once per open rather than per tick: the stream would otherwise write an
    // audit row every few seconds for the lifetime of a wall display.
    if (searchParams.get('audit') === 'open') {
      await writeAudit({
        action: AUDIT_ACTIONS.liveGridOpened,
        entity: 'live_grid',
        entityId: payload.twin.code,
        user,
        request,
        detail: `${payload.mode} · ${payload.assets.length} assets · ${payload.flow.edges.length} paths`,
      })
    }

    return {
      ...payload,
      scenarios: SCENARIO_KEYS.map((key) => ({
        key,
        label: GRID_SCENARIOS[key].label,
        labelAr: GRID_SCENARIOS[key].labelAr,
        watchFor: GRID_SCENARIOS[key].watchFor,
        watchForAr: GRID_SCENARIOS[key].watchForAr,
      })),
    }
  },
)
