import React, { useState } from "react";
import {
  PRE_GAME,
  PRE_ROUND,
  IN_ROUND,
  POST_ROUND,
  POST_GAME,
  ERROR,
} from "./GameState";
import HeaderAndFooter from "./HeaderAndFooter";
import PreGame from '../screens/PreGame';
import PreRound from '../screens/PreRound';
import GamePanel from "../screens/GamePanel";
import RoundSummary from '../screens/RoundSummary';
import PlayerScores from "../screens/PlayerScores";

const initialState = {
  gameState: PRE_GAME,
  gameId: null,
  playerName: null,
  lastRound: null,
  joined: false,
}

const extractAndRemoveSearchParam = param => {
  const u = new URL(window.location.href);
  const extracted = u.searchParams.get(param);
  u.searchParams.delete(param);
  window.history.replaceState({}, document.title, u.href);
  return extracted;
}

const Game = () => {
  const [ state, rawSetState ] = useState(initialState);
  const setGameState = gameState => rawSetState({ ...state, gameState });
  const setGameStateAnd = (gameState, updates) => rawSetState({ ...state, gameState, ...updates });
  const onGameJoined = ({ gameId, playerName }) => setGameStateAnd(PRE_ROUND, { gameId, playerName, joined: true });
  
  const joinCode = extractAndRemoveSearchParam("join");
  if (joinCode) {
    setGameStateAnd(PRE_ROUND, { gameId: joinCode, joined: false });
  }

  const summaryCode = extractAndRemoveSearchParam("summary");
  if (summaryCode) {
    setGameStateAnd(POST_GAME, { gameId: summaryCode });
  }

  switch (state.gameState) {
    case PRE_GAME:
      return (
        <HeaderAndFooter>
          <PreGame
            initPlayerName={state.playerName}
            onGameJoined={onGameJoined}
          />
        </HeaderAndFooter>
      );
    case PRE_ROUND:
      return (
        <HeaderAndFooter>
          <PreRound
            gameId={state.gameId}
            playerName={state.playerName}
            joined={state.joined}
            onGameJoined={onGameJoined}
            onStart={() => setGameState(IN_ROUND)}
          />
        </HeaderAndFooter>
      );
    case IN_ROUND:
      return <GamePanel
        gameId={state.gameId}
        playerName={state.playerName}
        onRoundEnd={lastRound => setGameStateAnd(POST_ROUND, { lastRound })}
        onGameEnd={() => setGameState(POST_GAME)}
      />
    case POST_ROUND:
      return <RoundSummary
        gameId={state.gameId}
        playerName={state.playerName}
        round={state.lastRound}
        onNext={() => setGameState(IN_ROUND)}
      />
    case POST_GAME:
      return (
        <HeaderAndFooter>
          <PlayerScores
            gameId={state.gameId}
            onReturnToStart={() => setGameStateAnd(PRE_GAME, { gameId: null, joined: false })}
          />
        </HeaderAndFooter>
      );
    case ERROR:
      // TODO - would be nice to hook this into the sub-components, maybe with a HOC?
      return <p>Application encountered unrecoverable error, please refresh the page.</p>
    default:
      setGameState(ERROR);
      return <p>Application state is inconsistent, please refresh and rejoin your previous game.</p>
  }
}

export default Game;
