// ============================================================
// main.ts — 진입점: 모든 시스템을 연결하고 게임 시작
// ============================================================

import { GameManager } from './game/GameManager';
import { GameLoop } from './core/GameLoop';
import { InputManager } from './core/InputManager';
import { Renderer } from './render/Renderer';
import { AudioManager } from './audio/AudioManager';
import { GameMode, GamePhase } from './types';
import { getAIInput } from './game/AIPlayer';
import { COUNTDOWN_DURATION } from './constants';

function main(): void {
  const canvas = document.getElementById('game-canvas') as HTMLCanvasElement | null;
  if (!canvas) {
    throw new Error('#game-canvas 요소를 찾을 수 없습니다.');
  }

  const inputManager = new InputManager();
  const gameManager = new GameManager();
  const renderer = new Renderer(canvas);
  const audio = new AudioManager();

  inputManager.attach();

  // 첫 상호작용 시 오디오 초기화
  const initAudio = () => {
    audio.init();
    document.removeEventListener('keydown', initAudio);
    document.removeEventListener('click', initAudio);
  };
  document.addEventListener('keydown', initAudio);
  document.addEventListener('click', initAudio);

  // 사운드 트리거용 이전 상태
  let prevPhase: GamePhase = GamePhase.START_MENU;
  let prevMenuSel = 0;
  let prevSettingsCursor = 0;
  let prevP1Grounded = true;
  let prevP2Grounded = true;
  let prevP1Diving = false;
  let prevP2Diving = false;
  let prevBallPunched = false;
  let prevCountdownSec = 4;

  const update = (_dt: number): void => {
    const prevState = gameManager.getState();
    const isMenu = prevState.phase === GamePhase.START_MENU
      || prevState.phase === GamePhase.SETTINGS
      || prevState.phase === GamePhase.QUIT_CONFIRM
      || prevState.phase === GamePhase.GAME_OVER;

    // 메뉴 계열에서는 justPressed 사용, 인게임에서는 홀드 가능
    let p1Input;
    let p2Input;

    if (isMenu) {
      p1Input = inputManager.getPlayer1MenuInput();
      p2Input = inputManager.getPlayer2MenuInput();
    } else {
      p1Input = inputManager.getPlayer1Input();
      p2Input = inputManager.getPlayer2Input();
    }

    // AI
    if (prevState.gameMode === GameMode.SINGLE && !isMenu) {
      p2Input = getAIInput(prevState);
    }

    // ESC 감지
    const escPressed = inputManager.isEscPressed();

    gameManager.tick(p1Input, p2Input, escPressed);
    const state = gameManager.getState();

    // 입력 소비 (justPressed 초기화)
    inputManager.consumeInputs();

    // 볼륨 동기화
    audio.setVolume(state.settings.volume);

    // === 사운드 ===

    // 메뉴 탐색
    if (state.phase === GamePhase.START_MENU && state.menuSelection !== prevMenuSel) {
      audio.playMenuMove();
    }
    prevMenuSel = state.menuSelection;

    // 설정 커서
    if (state.phase === GamePhase.SETTINGS && state.settingsCursor !== prevSettingsCursor) {
      audio.playMenuMove();
    }
    prevSettingsCursor = state.settingsCursor;

    // 페이즈 전환
    if (state.phase !== prevPhase) {
      if (state.phase === GamePhase.SERVE_WAIT && prevPhase === GamePhase.START_MENU) {
        audio.playMenuConfirm();
      }
      if (state.phase === GamePhase.SETTINGS) audio.playMenuMove();
      if (state.phase === GamePhase.START_MENU && prevPhase === GamePhase.SETTINGS) {
        audio.playMenuConfirm();
      }
      if (state.phase === GamePhase.QUIT_CONFIRM) audio.playMenuMove();
      if (state.phase !== GamePhase.QUIT_CONFIRM && prevPhase === GamePhase.QUIT_CONFIRM) {
        audio.playMenuConfirm();
      }
      if (state.phase === GamePhase.POINT_SCORED) audio.playScore();
      if (state.phase === GamePhase.GAME_OVER) audio.playWin();
    }

    // 카운트다운 비프
    if (state.phase === GamePhase.SERVE_WAIT) {
      const sec = Math.ceil((COUNTDOWN_DURATION - state.phaseTimer) / 60);
      if (sec !== prevCountdownSec && sec >= 1 && sec <= 3) {
        audio.playCountdownBeep();
      }
      prevCountdownSec = sec;
    }
    if (state.phase === GamePhase.IN_PLAY && prevPhase === GamePhase.SERVE_WAIT) {
      audio.playCountdownGo();
    }

    // 점프
    if (!state.player1.isGrounded && prevP1Grounded) audio.playJump();
    if (!state.player2.isGrounded && prevP2Grounded) audio.playJump();
    prevP1Grounded = state.player1.isGrounded;
    prevP2Grounded = state.player2.isGrounded;

    // 다이브
    if (state.player1.isDiving && !prevP1Diving) audio.playDive();
    if (state.player2.isDiving && !prevP2Diving) audio.playDive();
    prevP1Diving = state.player1.isDiving;
    prevP2Diving = state.player2.isDiving;

    // 공 타격
    if (state.ball.isPunched && !prevBallPunched) {
      const speed = Math.sqrt(state.ball.vx ** 2 + state.ball.vy ** 2);
      if (speed > 15) {
        audio.playSmash();
      } else {
        audio.playBallHit();
      }
    }
    prevBallPunched = state.ball.isPunched;

    prevPhase = state.phase;
  };

  const render = (interpolation: number): void => {
    const state = gameManager.getState();
    renderer.render(state, interpolation);
  };

  const gameLoop = new GameLoop(update, render);
  gameLoop.start();

  console.log('⚡ Pikachu Volleyball — 게임 시작!');
}

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', main);
} else {
  main();
}
