import { apiRoute } from '@/lib/api/handler'
import { ApiError, ERROR_CODES } from '@/lib/api/errors'
import { twinScenarioSchema, type TwinScenarioInput } from '@/lib/api/schemas'
import { generateScenario, listScenarios, saveScenario } from '@/lib/services/twin-service'

export const dynamic = 'force-dynamic'

/** The scenario library for this twin, presets first. */
export const GET = apiRoute<{ code: string }>({ permission: 'twin.read' }, async ({ params }) => {
  const scenarios = await listScenarios(params.code)
  return {
    scenarios: scenarios.map((scenario) => ({
      code: scenario.code,
      name: scenario.name,
      nameAr: scenario.nameAr,
      description: scenario.description,
      descriptionAr: scenario.descriptionAr,
      origin: scenario.origin,
      regionCode: scenario.regionCode,
      durationMin: scenario.durationMin,
      isPreset: scenario.isPreset,
      events: scenario.events.map((event) => ({
        kind: event.kind,
        label: event.label,
        labelAr: event.labelAr,
        offsetMin: event.offsetMin,
        durationMin: event.durationMin,
        magnitude: event.magnitude,
        unit: event.unit,
        regionCode: event.regionCode,
        targetCode: event.targetCode,
      })),
    })),
  }
})

/**
 * Save a composed scenario, or ask the platform to generate one (§37).
 *
 * Generation reads the grid's current state — a worst case built in mild weather is not
 * a worst case — and returns the events for review rather than running them.
 */
export const POST = apiRoute<{ code: string }, TwinScenarioInput>(
  { permission: 'twin.simulate', bodySchema: twinScenarioSchema, limit: 30 },
  async ({ params, body, user }) => {
    if (body.action === 'generate') {
      const generated = await generateScenario(body.kind ?? 'realistic', {
        regionCode: body.regionCode ?? null,
      })
      return { ...generated, twinCode: params.code, saved: false }
    }

    if (!body.events || body.events.length === 0 || !body.name) {
      throw new ApiError(ERROR_CODES.validationFailed)
    }

    const code = await saveScenario({
      twinCode: params.code,
      name: body.name,
      nameAr: body.nameAr ?? body.name,
      origin: 'manual',
      regionCode: body.regionCode ?? null,
      events: body.events,
      userId: user.id,
    })
    if (!code) throw new ApiError(ERROR_CODES.notFound)

    return { code, saved: true }
  },
)
