/**
 * Lane A demo — the playground.
 *
 * Boots the shared world, builds the greybox, spawns a blob, and wires the
 * controller (physics), feel (wobble, via the frozen events) and follow camera.
 *
 * CONTROLS
 *   WASD / Arrows  move (camera-relative)
 *   Space          jump
 *
 * DEBUG KEYS (toggle — press again to reset to base). Proves modifier plumbing:
 *   1  speedMul 1.6   2  jumpMul 1.5   3  size 1.5
 *   4  massMul 3.0    5  grip 1.0      6  glow 1.0 (super-state pulse)
 *   0  reset all modifiers      R  respawn at start
 *
 * A HUD (top-left) and a once-per-second console "state" line report live values
 * so integration can verify fast without a screenshot.
 */
import { createWorld } from '../world'
import { defaultModifiers } from '../contracts'
import { buildGreybox } from '../course/greybox'
import { createBlob } from '../blob/createBlob'
import { createBlobController } from '../blob/controller'
import { createBlobFeel } from '../blob/feel'
import { createFollowCamera } from '../blob/camera'

const world = await createWorld(document.getElementById('app')!)
const course = buildGreybox(world)

const blob = createBlob(world, { position: course.spawn })
world.blob = blob

// physics system (fixed 60Hz)
world.addSystem(createBlobController(world, blob))

// feel layer — driven by the FROZEN wire events, updated per render frame
const feel = createBlobFeel(blob)
world.events.on('blob:jumped', () => feel.onJump())
world.events.on('blob:landed', (p: { impact: number }) => feel.onLand(p.impact))
world.onFrame((dt) => feel.update(dt))

// follow camera
const camera = createFollowCamera(world, blob)
world.onFrame((dt) => camera.update(dt))

// ---- event counters + last-impact (for HUD/console) ----
let jumps = 0
let lands = 0
let lastImpact = 0
world.events.on('blob:jumped', () => { jumps++ })
world.events.on('blob:landed', (p: { impact: number }) => { lands++; lastImpact = p.impact })

// ---- respawn if you fall off the world ----
world.onFrame(() => {
  const t = blob.body.translation()
  if (t.y < -25) respawn()
})
function respawn(): void {
  blob.body.setTranslation({ x: course.spawn.x, y: course.spawn.y, z: course.spawn.z }, true)
  blob.body.setLinvel({ x: 0, y: 0, z: 0 }, true)
}

// ---- debug keys ----
const m = blob.modifiers
const toggle = (cur: number, on: number, base: number) => (cur === base ? on : base)
addEventListener('keydown', (e) => {
  switch (e.code) {
    case 'Digit1': m.speedMul = toggle(m.speedMul, 1.6, 1); break
    case 'Digit2': m.jumpMul = toggle(m.jumpMul, 1.5, 1); break
    case 'Digit3': m.size = toggle(m.size, 1.5, 1); break
    case 'Digit4': m.massMul = toggle(m.massMul, 3.0, 1); break
    case 'Digit5': m.grip = toggle(m.grip, 1.0, 0); break
    case 'Digit6': m.glow = toggle(m.glow, 1.0, 0); break
    case 'Digit0': Object.assign(m, defaultModifiers()); break
    case 'KeyR': respawn(); break
    default: return
  }
  console.log('[lane-a] modifiers', JSON.stringify(m))
})

// ---- HUD overlay ----
const hud = document.createElement('div')
hud.style.cssText =
  'position:fixed;top:10px;left:10px;font:12px/1.5 ui-monospace,Menlo,monospace;' +
  'color:#0a2540;background:rgba(255,255,255,.72);padding:10px 12px;border-radius:8px;' +
  'white-space:pre;pointer-events:none;z-index:10'
document.body.appendChild(hud)

// ---- per-frame HUD + fps + once/sec console state line ----
let frames = 0
let fps = 0
let acc = 0
let logAcc = 0
world.onFrame((dt) => {
  frames++
  acc += dt
  if (acc >= 0.5) { fps = Math.round(frames / acc); frames = 0; acc = 0 }

  const t = blob.body.translation()
  const v = blob.body.linvel()
  const speed = Math.hypot(v.x, v.z)
  hud.textContent =
    `BLOBBO · lane-a   ${fps} fps\n` +
    `pos  ${t.x.toFixed(1)} ${t.y.toFixed(1)} ${t.z.toFixed(1)}\n` +
    `spd  ${speed.toFixed(2)}   jumps ${jumps}  lands ${lands}  impact ${lastImpact.toFixed(1)}\n` +
    `mods speed ${m.speedMul}  jump ${m.jumpMul}  size ${m.size}  mass ${m.massMul}  grip ${m.grip}  glow ${m.glow}\n` +
    `WASD move · Space jump · 1 speed 2 jump 3 size 4 mass 5 grip 6 glow · 0 reset · R respawn`

  logAcc += dt
  if (logAcc >= 1) {
    logAcc = 0
    console.log(
      `[lane-a] state fps=${fps} pos=(${t.x.toFixed(1)},${t.y.toFixed(1)},${t.z.toFixed(1)}) ` +
      `spd=${speed.toFixed(2)} jumps=${jumps} lands=${lands} impact=${lastImpact.toFixed(1)} ` +
      `mods=${JSON.stringify(m)}`,
    )
  }
})

world.start()
console.log('[lane-a] booted. WASD to move, Space to jump, keys 1-6 modifiers, 0 reset, R respawn.')
