// src/pages/agent-office/canvas/Pathfinder.js

/**
 * BFS 4방향 경로 탐색 (대각선 없음)
 * blocked 타일과 벽 타일을 회피하여 최단 경로 반환
 */
export class Pathfinder {
  constructor(cols, rows) {
    this.cols = cols;
    this.rows = rows;
    this.blocked = new Set();
  }

  /** blocked 타일 세팅 (wall + furniture footprint) */
  setBlocked(blockedList) {
    // Do NOT clear — setWalls already added wall tiles
    for (const [col, row] of blockedList) {
      this.blocked.add(`${col},${row}`);
    }
  }

  /** wall 타일도 blocked로 추가 (floor 배열에서 0인 셀) */
  setWalls(floorGrid) {
    for (let r = 0; r < this.rows; r++) {
      for (let c = 0; c < this.cols; c++) {
        if (floorGrid[r][c] === 0) {
          this.blocked.add(`${c},${r}`);
        }
      }
    }
  }

  isBlocked(col, row) {
    if (col < 0 || col >= this.cols || row < 0 || row >= this.rows) return true;
    return this.blocked.has(`${col},${row}`);
  }

  /**
   * BFS 최단 경로
   * @returns {Array<{col, row}>} 시작점 제외, 도착점 포함 경로. 경로 없으면 빈 배열.
   */
  findPath(startCol, startRow, goalCol, goalRow) {
    if (startCol === goalCol && startRow === goalRow) return [];

    const key = (c, r) => `${c},${r}`;
    const startKey = key(startCol, startRow);
    const goalKey = key(goalCol, goalRow);

    const queue = [{ col: startCol, row: startRow }];
    const visited = new Set([startKey]);
    const parent = new Map();

    const dirs = [
      { dc: 0, dr: -1 }, // up
      { dc: 0, dr: 1 },  // down
      { dc: -1, dr: 0 }, // left
      { dc: 1, dr: 0 }   // right
    ];

    while (queue.length > 0) {
      const current = queue.shift();

      for (const { dc, dr } of dirs) {
        const nc = current.col + dc;
        const nr = current.row + dr;
        const nk = key(nc, nr);

        if (visited.has(nk)) continue;
        // 골 지점은 blocked여도 이동 가능 (에이전트가 자기 자리에 앉으려면)
        if (nk !== goalKey && this.isBlocked(nc, nr)) continue;

        visited.add(nk);
        parent.set(nk, key(current.col, current.row));
        queue.push({ col: nc, row: nr });

        if (nc === goalCol && nr === goalRow) {
          return this._reconstructPath(parent, startKey, goalKey);
        }
      }
    }

    return []; // 경로 없음
  }

  _reconstructPath(parent, startKey, goalKey) {
    const path = [];
    let current = goalKey;
    while (current !== startKey) {
      const [c, r] = current.split(',').map(Number);
      path.unshift({ col: c, row: r });
      current = parent.get(current);
    }
    return path;
  }

  /** idle 배회용: start 주변 반경 내 랜덤 walkable 타일 */
  getRandomNearbyFloor(col, row, radius = 4) {
    const candidates = [];
    for (let dr = -radius; dr <= radius; dr++) {
      for (let dc = -radius; dc <= radius; dc++) {
        const nc = col + dc;
        const nr = row + dr;
        if (nc === col && nr === row) continue;
        if (!this.isBlocked(nc, nr)) {
          candidates.push({ col: nc, row: nr });
        }
      }
    }
    if (candidates.length === 0) return null;
    return candidates[Math.floor(Math.random() * candidates.length)];
  }
}
