/**
 * @file Root application component that handles routing and authentication.
 * @copyright nhcarrigan
 * @license Naomi's Public License
 * @author Naomi Carrigan
 */
import { type JSX, useState } from "react";
import { CharacterPage } from "./components/game/characterPage.js";
import { GameLayout } from "./components/game/gameLayout.js";
import { LeaderboardPage } from "./components/game/leaderboardPage.js";
import { LoginPage } from "./components/game/loginPage.js";
import { ProfilePage } from "./components/game/profilePage.js";
import { GameProvider } from "./context/gameContext.js";

const getProfileDiscordId = (): string | null => {
  const match = /^\/profile\/(?<id>\d+)$/.exec(window.location.pathname);
  return match?.groups?.id ?? null;
};

const getCharacterDiscordId = (): string | null => {
  const match = /^\/character\/(?<id>\d+)$/.exec(window.location.pathname);
  return match?.groups?.id ?? null;
};

const handleAuthCallback = (): boolean => {
  if (window.location.pathname !== "/auth/callback") {
    return false;
  }

  const parameters = new URLSearchParams(window.location.search);
  const token = parameters.get("token");

  if (token !== null && token.length > 0) {
    localStorage.setItem("elysium_token", token);
  }

  window.history.replaceState(null, "", "/");
  return token !== null && token.length > 0;
};

const isAuthenticated = (): boolean => {
  const fromCallback = handleAuthCallback();
  if (fromCallback) {
    return true;
  }
  const storedToken = localStorage.getItem("elysium_token");
  return storedToken !== null && storedToken.length > 0;
};

/**
 * Renders the root application component, handling routing and authentication.
 * @returns The JSX element.
 */
const app = (): JSX.Element => {
  const [ loggedIn, setLoggedIn ] = useState(isAuthenticated);

  const profileDiscordId = getProfileDiscordId();
  if (profileDiscordId !== null) {
    return <ProfilePage discordId={profileDiscordId} />;
  }

  const characterDiscordId = getCharacterDiscordId();
  if (characterDiscordId !== null) {
    return <CharacterPage discordId={characterDiscordId} />;
  }

  if (window.location.pathname === "/leaderboards") {
    return <LeaderboardPage />;
  }

  function handleLogin(): void {
    setLoggedIn(true);
  }

  if (!loggedIn) {
    return <LoginPage onLogin={handleLogin} />;
  }

  return (
    <GameProvider>
      <GameLayout />
    </GameProvider>
  );
};

export { app as App };
