import type { GameSettings } from '@/scripts/interfaces/GameSettings';
import GameConnection, {
  type GameEnded,
  type GameIdentifier,
  type GameInformationDto,
} from '../signalR/GameConnection';
import type JoinGameObject from '@/scripts/interfaces/JoinGameObject';
import { getRandomMovePhrase } from '@/scripts/utils/RandomPlaceMessage';

class OnlineGame {
  public player: GameConnection;
  public currentDescription: string = 'Warte auf Spielaufbau ...';
  private gameId: string = '';

  public gameState: GameInformationDto | undefined;
  public onGameCreated?: (gameCode: string) => void;
  public onGameJoinedFailed?: () => void;
  public onGameStarted?: () => void;
  public onGameStateChanged?: (gameState: GameInformationDto | undefined) => void;
  public onGameEnded?: (gameEndedInfo: GameEnded) => void;

  constructor() {
    this.player = new GameConnection();

    this.player.onGameCreated = (gameIdentifier) => {
      this.gameId = gameIdentifier.gameId;
      this.onGameCreated?.(gameIdentifier.gameCode.toString());
    };

    this.player.onGameJoined = (gameIdentifier: GameIdentifier) => {
      this.gameId = gameIdentifier.gameId;
    };

    this.player.onGameStarted = (gameInfo: GameInformationDto) => {
      console.log("Game started!", gameInfo);
      this.gameState = gameInfo;
      this.onGameStarted?.();
      this.onGameStateChanged?.(this.gameState);

      this.changePlaceDescription();
    };

    this.player.onFieldUpdated = (currentState: GameInformationDto) => {
      this.updateState(currentState);
      this.changePlaceDescription();
    };

    this.player.onGameEnded = (gameEndedInfo: GameEnded) => {
      this.onGameEnded?.(gameEndedInfo);
    };

    this.player.onError = (errorMessage: string) => {
      switch (errorMessage) {
        case 'Spiel Existiert nicht!':
          this.onGameJoinedFailed?.();
          this.player.disconnect();
          break;
        default:
          console.error('Unhandled error:', errorMessage);
      }
    };
  }

  async createGame(settings: GameSettings) {
    await this.player.connect(settings.playerName1);
    await this.player.createGame(settings.fieldSize);
  }

  async joinGame(joinObject: JoinGameObject) {
    if (joinObject.gameCode?.toString().split('').length != 6 || parseInt(joinObject.gameCode) < 0) {
      this.onGameJoinedFailed?.();
      return;
    }

    await this.player.connect(joinObject.playerName);
    await this.player.joinGame(parseInt(joinObject.gameCode));
  }

  async updateState(newState: GameInformationDto) {
    if (this.gameState) {
      this.gameState = newState;
      this.onGameStateChanged?.(this.gameState);
    }
  }

  async drop(index: number) {
    await this.player.drop(this.gameId, index);
  }

  changePlaceDescription() {
    const playerName =
      this.gameState?.currentTurn == 1 ? this.gameState.players[0]?.name : this.gameState?.players[1]?.name;
    this.currentDescription = getRandomMovePhrase(playerName ?? "Spieler");
  }

  async restartGame(replayGameCode: any) {
  const code = Number(replayGameCode.value); // Proxy → primitive number
  await this.player.disconnect();
  await this.joinGame({
    gameCode: code.toString(),
    playerName: this.player.playerName ?? 'Spieler',
    failed: false,
  });
}
}

export default OnlineGame;
