import type { ZodType } from 'zod'
import type { UiGridColumn } from '../ui/adapter/contracts'
export type CrudConcurrencyMode = 'NONE' | 'ETAG_IF_MATCH'
export type CrudIdempotencyMode = 'NONE' | 'IDEMPOTENCY_KEY'
export type CrudRowField<TRow> = Extract<keyof TRow, string>
export interface CrudResourceDefinition<TQuery, TRow, TForm> {
  resourceId: string
  querySchemaVersion: string
  responseSchemaVersion: string
  querySchema: ZodType<TQuery>
  rowSchema: ZodType<TRow>
  formSchema: ZodType<TForm>
  columns: readonly UiGridColumn[]
  sensitiveFields: readonly CrudRowField<TRow>[]
  permissionPolicy: string
  concurrencyMode: CrudConcurrencyMode
  idempotencyMode: CrudIdempotencyMode
}
export function assertCrudResourceDefinition<TQuery, TRow, TForm>(definition: CrudResourceDefinition<TQuery, TRow, TForm>): void {
  if (!definition.resourceId.trim()) throw new Error('resourceId is required')
  if (!definition.querySchemaVersion.trim() || !definition.responseSchemaVersion.trim()) throw new Error('schema versions are required')
  if (!definition.permissionPolicy.trim()) throw new Error('permissionPolicy is required')
  if (definition.concurrencyMode !== 'NONE' && definition.concurrencyMode !== 'ETAG_IF_MATCH') throw new Error('invalid concurrencyMode')
  if (definition.idempotencyMode !== 'NONE' && definition.idempotencyMode !== 'IDEMPOTENCY_KEY') throw new Error('invalid idempotencyMode')
  const fields = new Set(definition.columns.map(x => x.field))
  for (const sensitive of definition.sensitiveFields) {
    const column = definition.columns.find(x => x.field === sensitive)
    if (!fields.has(sensitive) || !column?.sensitive) throw new Error(`Sensitive field '${sensitive}' has no sensitive grid column contract`)
  }
}
