// POST /v1/products  — create a product. GUARDED + IDEMPOTENT.
//
// - `guards: [requireScope('products:write')]` → 403 unless the resolved
//   Subject carries that scope. The app's `apiKeyStrategy` (see app.config)
//   maps the demo bearer token to a subject WITH the scope; an anonymous
//   caller is rejected.
// - `idempotency: true` in app.config makes a POST carrying an
//   `Idempotency-Key` header replay-safe: a retry with the same key replays
//   the first response instead of inserting twice.
//
// The `body` is parsed from the JSON request body and decoded against the
// `body` sub-schema (a bad shape → 400 before the handler runs).

import { defineRestRoute, requireScope } from '@voltro/protocol/rest'
import { Schema } from 'effect'
import { randomUUID } from 'node:crypto'
import type { DataStore } from '@voltro/runtime'
import { Product, toProduct } from '../../lib/product'

export default defineRestRoute({
  method: 'POST',
  path:   '/v1/products',
  input: Schema.Struct({
    body: Schema.Struct({
      name:       Schema.NonEmptyString,
      priceCents: Schema.Number.pipe(Schema.int(), Schema.greaterThanOrEqualTo(0)),
    }),
  }),
  output:  Product,
  summary: 'Create a product',
  guards:  [requireScope('products:write')],
  handler: async ({ body }, ctx) => {
    const store = ctx.store as DataStore
    // Explicit id + createdAt — the REST store path doesn't run the mutation
    // middleware that auto-injects them, so we own them here.
    const row = {
      id:         `prod_${randomUUID().replace(/-/g, '')}`,
      name:       body.name,
      priceCents: body.priceCents,
      createdAt:  new Date(),
    }
    await store.insert('products', row as never)
    return toProduct(row)
  },
})
