import ms from "pretty-ms";
import { useCallback, useState } from "react";
import { createGame } from "../../../domain/apiMethods";
import {
  COUNTRY_RACE,
  DISTANCE,
  HARD,
  FROZEN,
  NORMAL,
  RACE,
  RANDOM_STREET_VIEW,
  TIME_BANK,
  URBAN,
  NIGHTMARE,
  RAMP,
  RAMP_HARD,
} from "../../../domain/constants";
import useCountryLookup from "../../../hooks/useCountryLookup";
import Loading from "../Loading";
import { CountryDropdown, Dropdown, DropdownGroup, Item } from "./Dropdown";
import ErrorModal from "./ErrorModal";
import styles from "./GameCreationForm.module.css";

const DEFAULTS = {
  timer: 300,
  rounds: 5,
  countryLock: null,
  generationMethod: RANDOM_STREET_VIEW,
  gameMode: NORMAL,
  clockMode: NORMAL,
  scoreMethod: DISTANCE,
  roundPointCap: null,
};

const PRESETS = {
  URBAN_AMERICA: {
    ...DEFAULTS,
    generationMethod: URBAN,
    countryLock: "us",
  },
  URBAN_GLOBAL: {
    ...DEFAULTS,
    generationMethod: URBAN,
  },
  FAST_FROZEN: {
    ...DEFAULTS,
    timer: 30,
    rounds: 3,
    generationMethod: RANDOM_STREET_VIEW,
    gameMode: FROZEN,
  },
  COUNTRY_RACE: {
    ...DEFAULTS,
    scoreMethod: COUNTRY_RACE,
  },
  FROZEN_COUNTRY_RACE: {
    ...DEFAULTS,
    timer: 30,
    gameMode: FROZEN,
    scoreMethod: COUNTRY_RACE,
  },
  BOOTLEG_GG_DUEL: {
    ...DEFAULTS,
    clockMode: RACE,
    scoreMethod: RAMP,
  },
};

export const LastSettingsButton = ({ onClick }) => (
  <div
    className={styles.reusebutton}
    role="button"
    tabIndex="0"
    onClick={onClick}
    onKeyDown={({ key }) => {
      if (key === "Enter") {
        onClick();
      }
    }}
    title="Reuse Previous Game Settings"
  >
    <span aria-label="recycle" role="img">
      ♻️
    </span>
  </div>
);

const GameCreationForm = ({ afterCreate, lastSettings = null }) => {
  const [loading, setLoading] = useState(false);
  const [creationError, setCreationError] = useState(false);
  const [timer, setTimer] = useState(DEFAULTS.timer);
  const [rounds, setRounds] = useState(DEFAULTS.rounds);
  const [countryLock, setCountryLock] = useState(DEFAULTS.countryLock);
  const [generationMethod, setGenMethod] = useState(DEFAULTS.generationMethod);
  const [gameMode, setGameMode] = useState(DEFAULTS.gameMode);
  const [clockMode, setClockMode] = useState(DEFAULTS.clockMode);
  const [scoreMethod, setScoreMethod] = useState(DEFAULTS.scoreMethod);
  const [roundPointCap, setRoundPointCap] = useState(DEFAULTS.roundPointCap);

  const countryLookup = useCountryLookup(generationMethod);

  const [presetOpen, setPresetOpen] = useState(false);
  const setPreset = useCallback(
    ({
      timer: newTimer,
      rounds: newRounds,
      countryLock: newCountryLock,
      generationMethod: newGenMethod,
      gameMode: newGameMode,
      clockMode: newClockMode,
      scoreMethod: newScoreMethod,
      roundPointCap: newRoundPointCap,
    }) => {
      setTimer(newTimer);
      setRounds(newRounds);
      setCountryLock(newCountryLock);
      setGenMethod(newGenMethod);
      setGameMode(newGameMode);
      setClockMode(newClockMode);
      setScoreMethod(newScoreMethod);
      setRoundPointCap(newRoundPointCap);
    },
    []
  );

  if (loading || countryLookup === null) {
    return <Loading />;
  }

  const onCreateGame = async () => {
    setLoading(true);
    let gameId;
    try {
      gameId = await createGame(
        timer,
        rounds,
        countryLock,
        generationMethod,
        gameMode,
        clockMode,
        scoreMethod,
        roundPointCap
      );
    } catch (e) {
      setCreationError(true);
      setLoading(false);
      return;
    }
    if (afterCreate) {
      afterCreate(gameId);
    }
  };

  return (
    <div className={styles.form}>
      <ErrorModal
        open={creationError}
        onClose={() => setCreationError(false)}
      />
      <div className={styles.buttoncontainer}>
        <Dropdown
          buttonClass={styles.favbutton}
          selected={DEFAULTS}
          onClick={() => setPresetOpen(o => !o)}
          onSelect={v => {
            setPresetOpen(false);
            setPreset(v);
          }}
          open={presetOpen}
        >
          <Item value={DEFAULTS} display="⭐">
            Default
          </Item>
          <Item value={PRESETS.URBAN_AMERICA} display="⭐">
            Urban America
          </Item>
          <Item value={PRESETS.URBAN_GLOBAL} display="⭐">
            Urban Global
          </Item>
          <Item value={PRESETS.FAST_FROZEN} display="⭐">
            Fast Frozen
          </Item>
          <Item value={PRESETS.COUNTRY_RACE} display="⭐">
            Country Race
          </Item>
          <Item value={PRESETS.FROZEN_COUNTRY_RACE} display="⭐">
            Frozen Country Race
          </Item>
          <Item value={PRESETS.BOOTLEG_GG_DUEL} display="⭐">
            Legally Distinct from Geoguessr Duels
          </Item>
        </Dropdown>
        {lastSettings && (
          <LastSettingsButton onClick={() => setPreset(lastSettings)} />
        )}
        <button className={styles.start} onClick={onCreateGame} type="button">
          New Game
        </button>
      </div>
      <div className={styles.dropdowns}>
        <DropdownGroup>
          <Dropdown selected={timer} onSelect={setTimer} open="timer">
            <Item value={30} display={ms(30 * 1000)}>
              30 Seconds
            </Item>
            <Item value={120} display={ms(2 * 60 * 1000)}>
              2 Minutes
            </Item>
            <Item value={300} display={ms(5 * 60 * 1000)}>
              5 Minutes
            </Item>
            <Item value={3600} display={ms(60 * 60 * 1000)}>
              1 Hour
            </Item>
          </Dropdown>
          <Dropdown selected={rounds} onSelect={setRounds} open="rounds">
            <Item value={1}>1 Round</Item>
            <Item value={3}>3 Rounds</Item>
            <Item value={5}>5 Rounds</Item>
            <Item value={10}>10 Rounds</Item>
          </Dropdown>
          <Dropdown
            selected={generationMethod}
            onSelect={setGenMethod}
            open="gen"
          >
            <Item value={RANDOM_STREET_VIEW} display="🎲">
              Random Street View
            </Item>
            <Item value={URBAN} display="🏙️">
              Urban Centers
            </Item>
          </Dropdown>
          <CountryDropdown
            countryLookup={countryLookup}
            selected={countryLock}
            onSelect={setCountryLock}
            open="country"
          />
          <Dropdown selected={gameMode} onSelect={setGameMode} open="gameMode">
            <Item value={NORMAL} display="📍">
              Normal
            </Item>
            <Item value={FROZEN} display="❄️">
              Frozen
            </Item>
          </Dropdown>
          <Dropdown
            selected={clockMode}
            onSelect={setClockMode}
            open="clockMode"
          >
            <Item value={NORMAL} display="⏰">
              Standard
            </Item>
            <Item value={TIME_BANK} display="🏦">
              Time Bank
            </Item>
            <Item value={RACE} display="⚔️">
              Duel
            </Item>
          </Dropdown>
          <Dropdown
            selected={scoreMethod}
            onSelect={setScoreMethod}
            open="scoreMethod"
          >
            <Item value={DISTANCE} display="📏">
              Distance
            </Item>
            <Item value={RAMP} display="📈">
              Ramping
            </Item>
            <Item value={COUNTRY_RACE} display="🗾">
              Country Race
            </Item>
            <Item value={HARD} display="😬">
              Hard Mode
            </Item>
            <Item value={RAMP_HARD} display="🧀">
              Ramping Hard Mode
            </Item>
            <Item value={NIGHTMARE} display="💀">
              Nightmare Mode
            </Item>
          </Dropdown>
          <Dropdown
            selected={roundPointCap}
            onSelect={setRoundPointCap}
            open="roundPointCap"
          >
            <Item value={null} display="♾️">
              No Limit
            </Item>
            <Item value={10000} display="10k">
              10k Total Points per Round
            </Item>
            <Item value={20000} display="20k">
              20k Total Points per Round
            </Item>
          </Dropdown>
        </DropdownGroup>
      </div>
    </div>
  );
};

export default GameCreationForm;
