/**
 * Lane I — the slot inventory.
 *
 * A "slot" is a named place in the scene where a custom GLB may replace the
 * procedural mesh the game builds today. Slot ids are a closed set on purpose:
 * the editor (lane J) lists them, the manifest keys on them, and an unknown key
 * in a hand-edited manifest should be reported rather than silently ignored.
 *
 * Kept free of `three` imports so the validator can be node-tested headlessly.
 */

export const SLOT_IDS = [
  'blob.body',
  'blob.face',
  'ghost.body',
  'cannon.barrel',
  'machine.plate',
  'machine.boot',
  'machine.bucket',
  'machine.arch',
  'machine.belt',
  'machine.fan',
  'machine.seesaw',
  'course.scenery.cereal',
  'course.scenery.block',
  'fx.puddle',
] as const

export type SlotId = (typeof SLOT_IDS)[number]

const SLOT_SET: ReadonlySet<string> = new Set<string>(SLOT_IDS)

export function isSlotId(v: unknown): v is SlotId {
  return typeof v === 'string' && SLOT_SET.has(v)
}

/** Plain-language labels for the editor UI (lane J reads this). */
export const SLOT_LABELS: Record<SlotId, string> = {
  'blob.body': 'Blobbo body (paintable)',
  'blob.face': 'Blobbo eyes',
  'ghost.body': 'Ghost racer',
  'cannon.barrel': 'Paint cannon',
  'machine.plate': 'Pressure plate',
  'machine.boot': 'Spring boot',
  'machine.bucket': 'Paint bucket',
  'machine.arch': 'Bubble arch',
  'machine.belt': 'Conveyor belt',
  'machine.fan': 'Fan',
  'machine.seesaw': 'See-saw plank',
  'course.scenery.cereal': 'Giant cereal box',
  'course.scenery.block': 'Purple block',
  'fx.puddle': 'Paint puddle',
}

/**
 * Slots whose replacement is constrained beyond "looks different". Surfaced in
 * the editor so John sees the rule at the moment he drops a file on the slot.
 */
export const SLOT_NOTES: Partial<Record<SlotId, string>> = {
  'blob.body':
    'Must be ONE mesh with ONE material and clean 0..1 UVs — the paint is stamped ' +
    'through those UVs. Auto-resized to the 1.0u body; manifest scale is ignored here.',
  'ghost.body':
    'Copied from blob.body automatically unless you set this slot; materials are ' +
    'forced translucent.',
  'machine.boot': 'Model it standing on the floor, origin at the base — it shakes about its origin.',
  'machine.bucket': 'Origin at the TIPPING EDGE, pours toward +X, up axis +Y.',
  'machine.belt': 'Model the belt slab only; the moving chevrons stay procedural.',
  'machine.fan': 'Face +Z. The blades stay procedural so they keep spinning.',
  'machine.seesaw': 'Plank only, long axis along X, origin at the plank centre.',
  'machine.plate': 'Frame only — the pressed pad stays procedural so it can light up.',
}
