export async function nudgeGameAction()

in app-dev/party-game/app/actions/nudge-game.ts [24:93]


export async function nudgeGameAction({gameId, desiredState, tokens}: { gameId: string, desiredState: GameStateUpdate, tokens: Tokens }) {
  const authUser = await validateTokens(tokens);

  // Validate request
  // Will throw an error if not a string
  GameIdSchema.parse(gameId);
  GameStateUpdateSchema.parse(desiredState);

  const gameRef = await gamesRef.doc(gameId);
  const gameDoc = await gameRef.get();
  const game = GameSchema.parse(gameDoc.data());

  if (game.leader.uid !== authUser.uid) {
    // Respond with JSON indicating no game was found
    throw new Error('Only the leader of this game may advance this game.');
  }

  const totalNumberOfQuestions = Object.keys(game.questions).length;
  const finalQuestionIndex = totalNumberOfQuestions - 1;

  const nextQuestionIndex = game.currentQuestionIndex + 1;

  const {NOT_STARTED, AWAITING_PLAYER_ANSWERS, GAME_OVER, SHOWING_CORRECT_ANSWERS} = gameStates;

  // if the game is already in the desired state, no further action required
  if (game.state === desiredState.state && game.currentQuestionIndex === desiredState.currentQuestionIndex) {
    throw new Error('Desired state is same as current state. No changes to be made.');
  }

  switch (game.state) {
    case GAME_OVER:
      throw new Error('The game is over. No game progression is allowed.');
    case NOT_STARTED:
      if (desiredState.state === AWAITING_PLAYER_ANSWERS && desiredState.currentQuestionIndex === 0) {
        await gameRef.update({
          state: AWAITING_PLAYER_ANSWERS,
          currentQuestionIndex: 0,
          currentStateStartTime: FieldValue.serverTimestamp(),
        });
        return;
      }
      throw new Error('The only allowed game progression when NOT_STARTED is to AWAITING_PLAYER_ANSWERS');
    case SHOWING_CORRECT_ANSWERS:
      if (desiredState.currentQuestionIndex === nextQuestionIndex) {
        if (game.currentQuestionIndex === finalQuestionIndex) {
          await gameRef.update({
            state: GAME_OVER,
            currentStateStartTime: FieldValue.serverTimestamp(),
          });
          return;
        }
        await gameRef.update({
          state: AWAITING_PLAYER_ANSWERS,
          currentQuestionIndex: nextQuestionIndex,
          currentStateStartTime: FieldValue.serverTimestamp(),
        });
        return;
      }
      throw new Error('The only allowed game progression when SHOWING_CORRECT_ANSWERS is to AWAITING_PLAYER_ANSWERS on the next question');
    case AWAITING_PLAYER_ANSWERS:
      if (desiredState.state === SHOWING_CORRECT_ANSWERS && desiredState.currentQuestionIndex === game.currentQuestionIndex) {
        await gameRef.update({
          state: SHOWING_CORRECT_ANSWERS,
          currentStateStartTime: FieldValue.serverTimestamp(),
        });
        return;
      }
      throw new Error('The only allowed game progression when AWAITING_PLAYER_ANSWERS is to SHOWING_CORRECT_ANSWERS');
  }
}