/**
 * HULLROT — one hand-authored 24×24 deck.
 *
 * Legend: '#' hull wall, 'C' cable wall, 'G' demon-grate wall,
 *         'D' door, 'L' locked door (red keycard), '.' floor,
 *         'P' player spawn, 'h' husk, 's' stalker, 'B' brute,
 *         'a' ammo, 'm' medkit, 'k' keycard, 'E' exit beacon.
 */

export const CELL = {
  FLOOR: 0,
  HULL: 1,
  CABLE: 2,
  GRATE: 3,
  DOOR: 4,
  LOCKED: 5,
} as const;

const MAP_SRC = [
  '#GGGGGGGGGGGGGGGGGGGGGG#',
  'G.....G..........G...E.G',
  'G..h.......B........s..G',
  'G.........a............G',
  'G.....G....m.....G.....G',
  '##########GLG###########',
  '########C......C########',
  '#########......#########',
  '########C..h...C########',
  '###########D############',
  '###########..###########',
  '#..h...#........C....s.C',
  '#a.....................C',
  '#.k....#......s.C....m.C',
  '#....h.####..###C.a....C',
  '###########..###########',
  '###########..###########',
  '###########D############',
  '########........########',
  '########.....a..########',
  '########........########',
  '########...P....########',
  '########........########',
  '########################',
];

export type EnemyKind = 'husk' | 'stalker' | 'brute';
export type PickupKind = 'medkit' | 'ammo' | 'keycard';

export interface EnemySpawn { kind: EnemyKind; x: number; y: number; }
export interface PickupSpawn { kind: PickupKind; x: number; y: number; }

export interface LightZone {
  x0: number; y0: number; x1: number; y1: number;
  mode: 'flicker' | 'pulse' | 'dim';
  /** random seed / phase offset */
  seed: number;
}

export interface Level {
  w: number;
  h: number;
  grid: Uint8Array;
  jitter: Float32Array;
  spawnX: number;
  spawnY: number;
  spawnAngle: number;
  enemies: EnemySpawn[];
  pickups: PickupSpawn[];
  exitX: number;
  exitY: number;
  zones: LightZone[];
}

function hash(x: number, y: number): number {
  let h = (x * 374761393 + y * 668265263) | 0;
  h = ((h ^ (h >> 13)) * 1274126177) | 0;
  return ((h ^ (h >> 16)) >>> 0) / 4294967295;
}

export function buildLevel(): Level {
  const h = MAP_SRC.length;
  const w = MAP_SRC[0]!.length;
  const grid = new Uint8Array(w * h);
  const jitter = new Float32Array(w * h);
  const enemies: EnemySpawn[] = [];
  const pickups: PickupSpawn[] = [];
  let spawnX = 1.5, spawnY = 1.5, exitX = 1.5, exitY = 1.5;

  for (let y = 0; y < h; y++) {
    const row = MAP_SRC[y]!;
    if (row.length !== w) throw new Error(`map row ${y} has length ${row.length}, expected ${w}`);
    for (let x = 0; x < w; x++) {
      const ch = row[x]!;
      const cx = x + 0.5, cy = y + 0.5;
      let cell: number = CELL.FLOOR;
      switch (ch) {
        case '#': cell = CELL.HULL; break;
        case 'C': cell = CELL.CABLE; break;
        case 'G': cell = CELL.GRATE; break;
        case 'D': cell = CELL.DOOR; break;
        case 'L': cell = CELL.LOCKED; break;
        case 'P': spawnX = cx; spawnY = cy; break;
        case 'h': enemies.push({ kind: 'husk', x: cx, y: cy }); break;
        case 's': enemies.push({ kind: 'stalker', x: cx, y: cy }); break;
        case 'B': enemies.push({ kind: 'brute', x: cx, y: cy }); break;
        case 'a': pickups.push({ kind: 'ammo', x: cx, y: cy }); break;
        case 'm': pickups.push({ kind: 'medkit', x: cx, y: cy }); break;
        case 'k': pickups.push({ kind: 'keycard', x: cx, y: cy }); break;
        case 'E': exitX = cx; exitY = cy; break;
        case '.': break;
        default: throw new Error(`unknown map char '${ch}' at ${x},${y}`);
      }
      grid[y * w + x] = cell;
      jitter[y * w + x] = 0.86 + hash(x, y) * 0.22;
    }
  }

  const zones: LightZone[] = [
    // the hold: slow hellish red pulse
    { x0: 0, y0: 0, x1: 23, y1: 5, mode: 'pulse', seed: 0.0 },
    // antechamber: broken light, hard random flicker
    { x0: 8, y0: 6, x1: 15, y1: 9, mode: 'flicker', seed: 1.7 },
    // south corridor: dim with soft flicker
    { x0: 10, y0: 15, x1: 13, y1: 17, mode: 'dim', seed: 3.1 },
  ];

  return {
    w, h, grid, jitter,
    spawnX, spawnY,
    spawnAngle: -Math.PI / 2, // facing north (up the map)
    enemies, pickups, exitX, exitY, zones,
  };
}
