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

import { ProceduralSprite } from './ProceduralSprite.js';

const WALK_SPEED = 3; // tiles per second
const WANDER_DELAY_MIN = 3;
const WANDER_DELAY_MAX = 8;
const WANDER_LIMIT_MIN = 3;
const WANDER_LIMIT_MAX = 6;
const REST_DELAY_MIN = 2;
const REST_DELAY_MAX = 20;

export class AgentSprite {
  constructor(id, meta, col, row, pathfinder) {
    this.id = id;
    this.meta = meta;
    this.pathfinder = pathfinder;

    // 위치 (타일 좌표, 실수)
    this.x = col;
    this.y = row;
    this.deskCol = col;
    this.deskRow = row;

    // 상태
    this.state = 'idle';        // FSM 상태 (from backend)
    this.detail = '';
    this.notificationCount = 0;

    // 애니메이션
    this.animState = 'idle';    // 렌더링용 상태
    this.direction = 'down';
    this.animFrame = 0;
    this.animTimer = 0;

    // 이동
    this.path = [];             // BFS 경로 [{col, row}, ...]
    this.moveProgress = 0;      // 0~1 현재 타일 → 다음 타일
    this.moveFrom = { col, row };
    this.moveTo_target = null;

    // 배회
    this._wandering = false;
    this._wanderTimer = 0;
    this._wanderCount = 0;
    this._wanderLimit = 0;
    this._restTimer = 0;
    this._isResting = false;
    this._isAtDesk = true;
  }

  /** 매 프레임 호출 */
  update(dt) {
    // 이동 처리
    if (this.path.length > 0) {
      this._updateMovement(dt);
    } else if (this._wandering) {
      this._updateWander(dt);
    }

    // 애니메이션 프레임 업데이트
    this._updateAnimation(dt);
  }

  _updateMovement(dt) {
    this.animState = 'walk';
    this.moveProgress += WALK_SPEED * dt;

    if (this.moveProgress >= 1) {
      // 현재 구간 완료
      const arrived = this.path.shift();
      this.x = arrived.col;
      this.y = arrived.row;
      this.moveFrom = { col: arrived.col, row: arrived.row };
      this.moveProgress = 0;

      if (this.path.length === 0) {
        // 최종 목적지 도착
        this._onArrival();
      } else {
        // 다음 구간의 방향 설정
        this._updateDirection(this.path[0]);
      }
    } else {
      // 보간
      const next = this.path[0];
      this.x = this.moveFrom.col + (next.col - this.moveFrom.col) * this.moveProgress;
      this.y = this.moveFrom.row + (next.row - this.moveFrom.row) * this.moveProgress;
    }
  }

  _onArrival() {
    const atDesk = Math.abs(this.x - this.deskCol) < 0.5 && Math.abs(this.y - this.deskRow) < 0.5;
    this._isAtDesk = atDesk;

    if (this.state === 'working' || this.state === 'reporting') {
      this.animState = 'type';
      this.direction = 'up'; // 모니터를 바라봄
    } else if (this.state === 'waiting') {
      this.animState = 'wait';
    } else if (this.state === 'break') {
      this.animState = 'break_anim';
    } else {
      // idle 도착 — 배회 계속 또는 자리에서 쉬기
      if (this._wandering && this._wanderCount < this._wanderLimit) {
        // 다음 배회 타이머 설정
        this._wanderTimer = WANDER_DELAY_MIN + Math.random() * (WANDER_DELAY_MAX - WANDER_DELAY_MIN);
      } else if (this._wandering) {
        // 배회 끝, 휴식
        this._wandering = false;
        this._isResting = true;
        this._restTimer = REST_DELAY_MIN + Math.random() * (REST_DELAY_MAX - REST_DELAY_MIN);
      }
      this.animState = 'idle';
    }
  }

  _updateWander(dt) {
    if (this._isResting) {
      this._restTimer -= dt;
      if (this._restTimer <= 0) {
        this._isResting = false;
        this._startWandering();
      }
      return;
    }

    this._wanderTimer -= dt;
    if (this._wanderTimer <= 0) {
      // 랜덤 인접 타일로 이동
      const target = this.pathfinder.getRandomNearbyFloor(
        Math.round(this.x), Math.round(this.y), 4
      );
      if (target) {
        const path = this.pathfinder.findPath(
          Math.round(this.x), Math.round(this.y), target.col, target.row
        );
        if (path.length > 0 && path.length <= 6) {
          this.path = path;
          this.moveFrom = { col: Math.round(this.x), row: Math.round(this.y) };
          this.moveProgress = 0;
          this._updateDirection(path[0]);
          this._wanderCount++;
        }
      }
      // 실패해도 타이머 리셋
      this._wanderTimer = WANDER_DELAY_MIN + Math.random() * (WANDER_DELAY_MAX - WANDER_DELAY_MIN);
    }
  }

  _updateDirection(nextTile) {
    const dx = nextTile.col - Math.round(this.x);
    const dy = nextTile.row - Math.round(this.y);
    if (Math.abs(dx) > Math.abs(dy)) {
      this.direction = dx > 0 ? 'right' : 'left';
    } else {
      this.direction = dy > 0 ? 'down' : 'up';
    }
  }

  _updateAnimation(dt) {
    const config = ProceduralSprite.getAnimConfig(
      this.animState === 'walk' ? 'walk' : this.state
    );
    this.animTimer += dt;
    if (this.animTimer >= config.speed) {
      this.animTimer = 0;
      this.animFrame = (this.animFrame + 1) % config.frames;
    }
  }

  /** 백엔드 상태 변경 시 호출 */
  onStateChange(newState, detail, waypoints) {
    const prevState = this.state;
    this.state = newState;
    this.detail = detail || '';

    // 배회 중단
    this._wandering = false;
    this._isResting = false;

    switch (newState) {
      case 'working':
      case 'reporting':
      case 'waiting':
        // 자리에 없으면 자리로 이동
        if (!this._isAtDesk) {
          this._moveToDesk();
        } else {
          this.animState = newState === 'waiting' ? 'wait' : 'type';
          this.direction = 'up';
        }
        break;

      case 'break': {
        // 휴게실로 이동
        const breakWp = waypoints.break_room || waypoints.coffee;
        if (breakWp) {
          this._navigateTo(breakWp.col, breakWp.row);
        }
        break;
      }

      case 'idle':
        if (prevState === 'break') {
          // 휴게실에서 자리로 복귀
          this._moveToDesk();
        }
        // 복귀 후 배회 시작 (도착 콜백에서 처리)
        this._startWanderingAfterDelay(3);
        break;
    }
  }

  _moveToDesk() {
    this._navigateTo(this.deskCol, this.deskRow);
  }

  _navigateTo(goalCol, goalRow) {
    const startCol = Math.round(this.x);
    const startRow = Math.round(this.y);
    const path = this.pathfinder.findPath(startCol, startRow, goalCol, goalRow);
    if (path.length > 0) {
      this.path = path;
      this.moveFrom = { col: startCol, row: startRow };
      this.moveProgress = 0;
      this._updateDirection(path[0]);
    }
  }

  _startWanderingAfterDelay(delay) {
    this._wandering = true;
    this._wanderCount = 0;
    this._wanderLimit = WANDER_LIMIT_MIN + Math.floor(Math.random() * (WANDER_LIMIT_MAX - WANDER_LIMIT_MIN));
    this._wanderTimer = delay;
    this._isResting = false;
  }

  _startWandering() {
    this._startWanderingAfterDelay(WANDER_DELAY_MIN + Math.random() * (WANDER_DELAY_MAX - WANDER_DELAY_MIN));
  }

  isAtDesk() {
    return this._isAtDesk;
  }

  /** 렌더링 */
  draw(ctx, zoom, panX, panY, tileSize) {
    const ts = tileSize * zoom;
    const screenX = this.x * ts + panX + ts / 2;
    const screenY = this.y * ts + panY + ts;
    const spriteScale = zoom * 1.5; // 캐릭터 약간 크게

    ProceduralSprite.draw(
      ctx, this.id,
      this.animState === 'walk' ? 'walk' : this.state,
      this.direction, this.animFrame,
      screenX, screenY, spriteScale
    );
  }
}
