<script setup lang="ts">
import CreateOrJoinMenu from '@/components/CreateOrJoinMenu.vue';
import Field from '@/components/game/Field.vue';
import InfoField from '@/components/game/InfoField.vue';
import GameCreationMenu from '@/components/GameCreationMenu.vue';
import GameEndedMenu from '@/components/GameEndedMenu.vue';
import GameJoinMenu from '@/components/GameJoinMenu.vue';
import type { GameSettings } from '@/scripts/interfaces/GameSettings';
import type JoinGameObject from '@/scripts/interfaces/JoinGameObject';
import OnlineGame from '@/scripts/logic/onlineMode/OnlineGame';
import type { GameEnded } from '@/scripts/logic/signalR/GameConnection';
import { onUnmounted, ref } from 'vue';

enum CurrentState {
  CreateOrJoinSelection,
  CreatingGame,
  JoiningGame,
  Game,
  EndScreen,
}

let settings = ref<GameSettings>({
  playerName1: 'Spieler 1',
  fieldSize: { x: 7, y: 6 },
});

let joiningModel = ref<JoinGameObject>({
  playerName: 'Spieler 2',
  failed: false,
});

var currentState = ref<CurrentState>(CurrentState.CreateOrJoinSelection);
const game = ref<OnlineGame>(new OnlineGame());
const gameField = ref<number[][]>([]);
const currentSelectionIndex = ref<number | null>(null);
const gameEndedInformation = ref<GameEnded | null>(null);

game.value.onGameStateChanged = (gameState) => {
  gameField.value = gameState?.currentField ?? [];
};

game.value.onGameEnded = (gameEndedInfo) => {
  gameEndedInformation.value = gameEndedInfo;
  currentState.value = CurrentState.EndScreen;
};

game.value.onGameCreated = (gameCode: string) => {
  settings.value.message = `Das Spiel ist erstellt, deine Freund kann über folgendem Code Beitreten: ${gameCode}`;
};

game.value.onGameStarted = () => {
  currentState.value = CurrentState.Game;
};

game.value.onGameJoinedFailed = () => {
  joiningModel.value.failed = true;
};

async function createGame() {
  await game.value.createGame(settings.value);
}

async function tryToJoin() {
  await game.value.joinGame(joiningModel.value);
}

async function restartGame() {
  if(!gameEndedInformation.value?.replayGameCode) return;
  await game.value.restartGame(gameEndedInformation.value.replayGameCode);
}

onUnmounted(async () => {
  await game.value.player.disconnect();
});
</script>

<template>
  <CreateOrJoinMenu
    v-if="currentState === CurrentState.CreateOrJoinSelection"
    @createGame="currentState = CurrentState.CreatingGame"
    @joinGame="currentState = CurrentState.JoiningGame"
  />

  <GameCreationMenu
    v-model:settings="settings"
    @create-game="createGame"
    v-else-if="
      currentState === CurrentState.CreatingGame
    "
  />

  <GameJoinMenu
    :joinGameObject="joiningModel"
    v-else-if="currentState === CurrentState.JoiningGame"
    @join="tryToJoin"
  />

  <GameEndedMenu
    :game-ended-information="gameEndedInformation"
    v-else-if="currentState === CurrentState.EndScreen"
    @restart-game="restartGame()"
  ></GameEndedMenu>

  <div id="game" v-else>
    <div class="game-content">
      <Field
        :game-state="gameField"
        v-model:current-selection-index="currentSelectionIndex"
        @click-on-game-field="game.drop(currentSelectionIndex ?? 1)"
      />

      <InfoField :msg="game.currentDescription"></InfoField>
    </div>
  </div>
</template>

<style scoped></style>
