/** タイルグリッドの生成とアクセスヘルパ */
import { GRID_H, GRID_W } from './config';
import { Dir, type Tile, type TileKind } from './types';

export function idx(x: number, y: number): number {
  return y * GRID_W + x;
}

export function tx(index: number): number {
  return index % GRID_W;
}

export function ty(index: number): number {
  return Math.floor(index / GRID_W);
}

export function inBounds(x: number, y: number): boolean {
  return x >= 0 && y >= 0 && x < GRID_W && y < GRID_H;
}

export function makeTile(kind: TileKind = 'floor'): Tile {
  return {
    kind,
    dir: Dir.East,
    catwalk: false,
    cargo: null,
    queue: [],
    fullFor: 0,
    progress: 0,
    outSlot: null,
    brokenFor: 0,
    assigned: null,
    cooldown: 0,
    rr: 0,
    tiers: 1,
    yardMode: 'all',
    truck: kind === 'output' || kind === 'dock' ? [] : null,
    truckTimer: 0,
    uses: 0,
  };
}

/** 初期レイアウト: 外周が壁、左に搬入口、右に出荷口、右下にボイラー室。 */
export function createGrid(): Tile[] {
  const tiles: Tile[] = new Array(GRID_W * GRID_H);
  for (let y = 0; y < GRID_H; y++) {
    for (let x = 0; x < GRID_W; x++) {
      const edge = x === 0 || y === 0 || x === GRID_W - 1 || y === GRID_H - 1;
      tiles[idx(x, y)] = makeTile(edge ? 'wall' : 'floor');
    }
  }

  // 資材搬入口 (左壁の中ほど、2マス)
  for (const y of [7, 8]) {
    const t = tiles[idx(0, y)];
    t.kind = 'intake';
    t.dir = Dir.East;
  }

  // 出荷口 (右壁の中ほど、2マス)
  for (const y of [7, 8]) {
    const t = tiles[idx(GRID_W - 1, y)];
    t.kind = 'output';
    t.dir = Dir.East;
  }

  // ボイラー室: 右下の一角。暖かいので猫が侵入したがる立入禁止区域。
  for (let y = GRID_H - 5; y <= GRID_H - 2; y++) {
    for (let x = GRID_W - 6; x <= GRID_W - 2; x++) {
      const border =
        y === GRID_H - 5 || x === GRID_W - 6;
      if (border) {
        // 上辺と左辺を壁にするが、1マスだけ開口部を残しておく (猫が入れてしまう)
        const isDoor = y === GRID_H - 5 && x === GRID_W - 3;
        tiles[idx(x, y)].kind = isDoor ? 'floor' : 'wall';
      } else {
        tiles[idx(x, y)].kind = 'boiler';
      }
    }
  }

  return tiles;
}

/** 猫が足を踏み入れられるか (キャットウォークは常に通行可) */
export function walkableForCat(t: Tile): boolean {
  if (t.catwalk) return true;
  switch (t.kind) {
    case 'wall':
      return false;
    case 'intake':
    case 'output':
      return false;
    default:
      return true;
  }
}

/** 「危険なので本来通ってほしくない」マスか (経路コストを重くする) */
export function isHazardousForCat(t: Tile): boolean {
  if (t.catwalk) return false;
  switch (t.kind) {
    case 'conveyor':
    case 'splitter':
    case 'merger':
    case 'boiler':
      return true;
    default:
      return false;
  }
}

/**
 * フォークリフトが走行できるマスか。
 * 車両はコンベアや機械の上を通れないので、必ず通路を確保する必要がある。
 */
export function drivableForForklift(t: Tile): boolean {
  switch (t.kind) {
    case 'floor':
    case 'breakroom':
    case 'pallet':
    case 'container':
    case 'forkdepot':
    case 'dock':
      return true;
    default:
      return false;
  }
}

/** 電気代の対象になる機械か */
export function isMachine(t: Tile): boolean {
  switch (t.kind) {
    case 'conveyor':
    case 'splitter':
    case 'merger':
    case 'stocker':
    case 'office':
    case 'lab':
    case 'feeder':
    case 'handler_post':
      return true;
    case 'bench':
    case 'lathe':
    case 'press':
    case 'robot':
    case 'packer':
    case 'forkdepot':
    case 'dock':
      return true;
    default:
      return false;
  }
}
