/**
 * Wanderer — a creature with an innate homeostatic drive. This is the FULL
 * apple/zombie agent from rpgtextmier, reborn in 3D: it doesn't just wander, it
 * has a `life` that decays (hunger), and when hungry it seeks the nearest apple,
 * eats it to restore life, and DIES if it runs out. That single decaying scalar
 * is the seed of "Learning Systems and Innate Behavior" — a felt need, in-world,
 * not in a prompt.
 *
 * Deterministic-ish (seeded wander) and terrain-aware: avoids water and bumps
 * into solid props (trees/rocks). Authored creatures (the in-world editor) can
 * do anything; this is the bundled one with real stakes.
 */
'use strict';

const SPEED = 0.45;
const TURN = Math.PI * 0.7;
const MAX_LIFE = 100;
const HUNGER = 0.05;       // life lost per tick (~50s to starve from full)
const HUNGRY_AT = 65;      // start foraging below this
const SIGHT = 50;          // how far it can spot an apple
const EAT_RANGE = 1.8;
const FOOD_LIFE = 40;

class Wanderer {
  constructor(o) {
    this.id = o.id;
    this.kind = 'wanderer';
    this.x = o.x;
    this.z = o.z;
    this.y = 0;
    this.heading = (o.seed % 628) / 100;
    this.scale = o.scale != null ? o.scale : 1;
    this.life = MAX_LIFE;
    this.maxLife = MAX_LIFE;
    this._rng = (o.seed >>> 0) || 1;
  }

  _rand() {
    this._rng = (Math.imul(this._rng, 1664525) + 1013904223) >>> 0;
    return this._rng / 4294967296;
  }

  _step(world) {
    const nx = this.x + Math.cos(this.heading) * SPEED;
    const nz = this.z + Math.sin(this.heading) * SPEED;
    const mat = world.materialAt(nx, nz);
    if (!mat || mat.liquid || !mat.walkable || world.blockedByProp(nx, nz, 0.5)) {
      this.heading += TURN * (this._rand() < 0.5 ? 1 : -1); // blocked — turn away
    } else {
      this.x = nx;
      this.z = nz;
    }
  }

  update(world) {
    // ── the innate stake ──
    this.life -= HUNGER;
    if (this.life <= 0) { world.removeEntity(this.id); return; } // starved

    // hungry → forage for the nearest apple
    let food = null;
    if (this.life < HUNGRY_AT) food = world.nearestEntity('apple', this.x, this.z, SIGHT);

    if (food) {
      const d = Math.hypot(food.x - this.x, food.z - this.z);
      if (d <= EAT_RANGE) {
        world.removeEntity(food.id);
        this.life = Math.min(this.maxLife, this.life + FOOD_LIFE); // ate
      } else {
        this.heading = Math.atan2(food.z - this.z, food.x - this.x); // head toward it
        this._step(world);
      }
    } else {
      if (this._rand() < 0.08) this.heading += (this._rand() - 0.5) * TURN; // wander
      this._step(world);
    }
    this.y = world.heightAt(this.x, this.z);
  }

  serialize() {
    return {
      id: this.id,
      kind: this.kind,
      pose: { x: this.x, y: this.y, z: this.z, heading: this.heading, rot: this.heading },
      scale: this.scale,
      life: this.life,        // lets the renderer show a hungry creature differently
      maxLife: this.maxLife,
    };
  }
}

module.exports = { Wanderer };
