import { useEffect, useRef, useState, StrictMode } from "react";
import { CSSTransition } from "react-transition-group";
import styles from "./App.module.css";
import GamePanel from "./components/screens/GamePanel";
import GameSummary from "./components/screens/GameSummary";
import HomePage from "./components/screens/HomePage";
import Lobby from "./components/screens/Lobby";
import RoundSummary from "./components/screens/RoundSummary";
import ApiInfo from "./components/util/ApiInfo";
import {
  ERROR,
  IN_ROUND,
  POST_GAME,
  POST_ROUND,
  PRE_GAME,
  PRE_ROUND,
} from "./domain/gameStates";
import { dispatch, useGameState } from "./domain/gameStore";
import Loading from "./components/util/Loading";

const needsHeaderFooter = {
  [PRE_GAME]: true,
  [PRE_ROUND]: true,
  [IN_ROUND]: false,
  [POST_ROUND]: false,
  [POST_GAME]: false,
  [ERROR]: true,
};

export const Header = ({ show }) => {
  const transitionRef = useRef(null);

  return (
    <CSSTransition
      nodeRef={transitionRef}
      in={show}
      timeout={500}
      mountOnEnter
      unmountOnExit
      classNames="fade"
    >
      <div className={styles.header} ref={transitionRef}>
        <p>TerrAssumptions!</p>
      </div>
    </CSSTransition>
  );
};

export const Footer = ({ show }) => {
  const transitionRef = useRef(null);

  return (
    <CSSTransition
      nodeRef={transitionRef}
      in={show}
      timeout={500}
      mountOnEnter
      unmountOnExit
      classNames="fade"
    >
      <div className={styles.footer} ref={transitionRef}>
        <ApiInfo />
      </div>
    </CSSTransition>
  );
};

export const paramRouter = {
  join: dispatch.goToLobby,
  summary: gameId => dispatch.goToSummary(gameId, false),
};

export const State = ({ show, children, setTransitioning }) => {
  const transitionRef = useRef(null);

  return (
    <CSSTransition
      nodeRef={transitionRef}
      in={show}
      timeout={500}
      mountOnEnter
      unmountOnExit
      classNames="fade"
      onEnter={() => setTransitioning(true)}
      onExited={() => setTransitioning(false)}
    >
      <div className={styles.state} ref={transitionRef}>
        {children}
      </div>
    </CSSTransition>
  );
};

const App = () => {
  const [loading, setLoading] = useState(true);
  const [transitioning, setTransitioning] = useState(true);
  const gameState = useGameState();
  useEffect(() => {
    const url = new URL(window.location.href);
    // eslint-disable-next-line no-restricted-syntax
    for (const [param, value] of url.searchParams.entries()) {
      const route = paramRouter[param];
      if (route) {
        url.searchParams.delete(param);
        window.history.replaceState({}, document.title, url.href);
        route(value);
        break;
      }
    }
    setLoading(false);
  }, []);
  const needsHF = needsHeaderFooter[gameState];

  return (
    <StrictMode>
      <div className={styles.page}>
        <Header show={needsHF} />
        <State show={loading} setTransitioning={setTransitioning}>
          <div className={styles.loading}>
            <Loading />
          </div>
        </State>
        <State
          show={!loading && gameState === PRE_GAME}
          setTransitioning={setTransitioning}
        >
          <HomePage />
        </State>
        <State
          show={gameState === PRE_ROUND}
          setTransitioning={setTransitioning}
        >
          <Lobby />
        </State>
        {!transitioning && gameState === IN_ROUND && <GamePanel />}
        <State
          show={gameState === POST_ROUND}
          setTransitioning={setTransitioning}
        >
          <RoundSummary />
        </State>
        <State
          show={gameState === POST_GAME}
          setTransitioning={setTransitioning}
        >
          <GameSummary />
        </State>
        <State show={gameState === ERROR}>
          <p>
            Application encountered unrecoverable error, please refresh the
            page.
          </p>
        </State>
        <Footer show={needsHF} />
      </div>
    </StrictMode>
  );
};

export default App;
