import type { Vec3 } from "../math/Vec3"
import type { MeshBatch } from "../render/ChunkBuilder"
import type { Collider } from "../world/Collider"

/** Static content recipe. Concrete game prefabs implement this engine contract and
 * are referenced as objects, never through a closed content-kind registry. */
export type Prefab<State> = {
  position: (state: State) => Vec3
  bakeNear: (state: State, batch: MeshBatch) => void
  bakeFar?: (state: State, batch: MeshBatch) => void
  collider?: (state: State) => Collider | null
}

/** Type-erased placed prefab consumed during level compilation only. */
export type PlacedPrefab = {
  position: Vec3
  bakeNear: (batch: MeshBatch) => void
  bakeFar?: (batch: MeshBatch) => void
  collider: Collider | null
}

export namespace Prefab {
  export function place<State>(
    definition: Prefab<State>,
    state: State,
  ): PlacedPrefab {
    const bakeFar = definition.bakeFar
    return {
      position: definition.position(state),
      bakeNear: (batch) => definition.bakeNear(state, batch),
      bakeFar:
        bakeFar === undefined
          ? undefined
          : (batch) => bakeFar(state, batch),
      collider: definition.collider?.(state) ?? null,
    }
  }
}
