import BurgerMenu from "../../components/BurgerMenu"
import Logo from "../../components/Logo"
import OptionButton from "../../components/OptionButton"
import { gameContext } from "../_app"
import { faEye, faLeftLong } from "@fortawesome/pro-regular-svg-icons"
import { faPlus, faUserPlus } from "@fortawesome/pro-solid-svg-icons"
import { faCirclePlay } from "@fortawesome/pro-thin-svg-icons"
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"
import getAccessToken, {
  successfulResponse,
} from "@lib/frontend/getAccessToken"
import { GetServerSideProps } from "next"
import { useRouter } from "next/router"
import { useCallback, useContext, useEffect, useState } from "react"
import OtpInput from "react-otp-input"
import { toast } from "react-toastify"
import { z } from "zod"

interface Props {
  q: string | string[] | undefined
}
function isInputOnlyNumbers(input: string) {
  return /^\d+$/.test(input)
}

export default function Home({ q }: Props) {
  const [otp, setOtp] = useState("")
  const [gameProps, setGameProps] = useContext(gameContext)
  const router = useRouter()

  const gameFetch = useCallback(
    async (pin?: string) => {
      const createSchema = z.object({
        game: z.object({
          id: z.string(),
        }),
        pin: z.string().optional(),
        player: z.object({
          id: z.string(),
          username: z.string().optional(),
          isOwner: z.boolean().optional(),
        }),
        enemy: z
          .object({
            id: z.string(),
            username: z.string().optional(),
            isOwner: z.boolean().optional(),
          })
          .optional(),
      })
      const gamePromise = getAccessToken().then((token) => {
        console.log(otp, { ...token, pin })
        return fetch("/api/game/" + (!pin ? "create" : "join"), {
          method: "POST",
          body: JSON.stringify({ ...token, pin: pin }),
        })
          .then(successfulResponse)
          .then((game) => createSchema.parse(game))
      })

      const res = await toast.promise(gamePromise, {
        pending: {
          render: "Raum wird " + (!pin ? "erstellt" : "angefragt"),
        },
        success: {
          render: "Raum " + (!pin ? "erstellt" : "angefragt") + " 👌",
          type: "info",
          theme: "colored",
        },
        error: {
          render: "Es ist ein Fehler aufgetreten 🤯",
          type: "error",
          theme: "colored",
        },
      })

      setGameProps(res)

      await toast.promise(router.push("/dev/lobby"), {
        pending: {
          render: "Raum wird beigetreten",
        },
        success: {
          render: "Raum begetreten 👌",
          type: "info",
        },
        error: {
          render: "Es ist ein Fehler aufgetreten 🤯",
          type: "error",
        },
      })
    },
    [router, setGameProps]
  )

  useEffect(() => {
    if (otp.length !== 4) return
    if (!isInputOnlyNumbers(otp)) {
      toast("Der Code darf nur Zahlen beinhalten!", {
        type: "warning",
        theme: "dark",
      })
      return
    }
    gameFetch(otp)
  }, [otp])

  return (
    <div className="h-full bg-theme">
      <div className="mx-auto flex h-full max-w-screen-md flex-col items-center justify-evenly">
        <Logo />
        <BurgerMenu />
        {(() => {
          switch (q) {
            case "join":
              return (
                <div className="flex flex-col items-center rounded-xl border-4 border-black bg-grayish px-4 py-6 shadow-lg sm:mx-8 sm:p-12 md:w-full">
                  <button
                    className="-mt-2 w-20 self-start rounded-xl border-b-4 border-shield-gray bg-voidDark text-2xl text-grayish duration-100 active:border-b-0 active:border-t-4 sm:-mt-6 sm:w-40 sm:px-2 sm:text-5xl"
                    onClick={() =>
                      setTimeout(() => {
                        // Navigate to the same page with the `start` query parameter set to `false`
                        router.push({
                          pathname: router.pathname,
                          query: null,
                        })
                      }, 200)
                    }
                  >
                    <FontAwesomeIcon icon={faLeftLong} />
                  </button>
                  <div className="flex flex-col items-center gap-6 sm:gap-12">
                    <OptionButton icon={faPlus}>Raum erstellen</OptionButton>
                    <OptionButton
                      action={() => {
                        router.push({
                          pathname: router.pathname,
                          query: { q: "join" },
                        })
                      }}
                      icon={faUserPlus}
                    >
                      <OtpInput
                        containerStyle={{ color: "initial" }}
                        value={otp}
                        onChange={setOtp}
                        numInputs={4}
                        placeholder="0000"
                        renderSeparator={<span>-</span>}
                        renderInput={(props) => <input {...props} />}
                      />
                    </OptionButton>
                    <OptionButton icon={faEye}>Zuschauen</OptionButton>
                  </div>
                </div>
              )
            case "start":
              return (
                <div className="flex flex-col items-center rounded-xl border-4 border-black bg-grayish px-4 py-6 shadow-lg sm:mx-8 sm:p-12 md:w-full">
                  <button
                    className="-mt-2 w-20 self-start rounded-xl border-b-4 border-shield-gray bg-voidDark text-2xl text-grayish duration-100 active:border-b-0 active:border-t-4 sm:-mt-6 sm:w-40 sm:px-2 sm:text-5xl"
                    onClick={() =>
                      setTimeout(() => {
                        // Navigate to the same page with the `start` query parameter set to `false`
                        router.push({
                          pathname: router.pathname,
                          query: null,
                        })
                      }, 200)
                    }
                  >
                    <FontAwesomeIcon icon={faLeftLong} />
                  </button>
                  <div className="flex flex-col items-center gap-6 sm:gap-12">
                    <OptionButton action={() => gameFetch()} icon={faPlus}>
                      Raum erstellen
                    </OptionButton>
                    <OptionButton
                      action={() => {
                        router.push({
                          pathname: router.pathname,
                          query: { q: "join" },
                        })
                      }}
                      icon={faUserPlus}
                    >
                      Raum beitreten
                    </OptionButton>
                    <OptionButton icon={faEye}>Zuschauen</OptionButton>
                  </div>
                </div>
              )
            default:
              return (
                <>
                  <div className="flex h-36 w-64 items-center justify-center rounded-xl border-4 border-black bg-[#2227] sm:h-48 sm:w-96 md:h-72 md:w-[32rem] md:border-[6px] xl:h-[26rem] xl:w-[48rem]">
                    <FontAwesomeIcon
                      className="text-6xl sm:text-7xl md:text-8xl"
                      icon={faCirclePlay}
                    />
                  </div>
                  <button
                    className="font-farro rounded-lg border-b-4 border-orange-400 bg-warn px-12 pb-4 pt-5 text-2xl font-bold duration-100 active:border-b-0 active:border-t-4 sm:rounded-xl sm:border-b-[6px] sm:px-14 sm:pb-5 sm:pt-6 sm:text-3xl sm:active:border-t-[6px] md:rounded-2xl md:border-b-8 md:px-20 md:pb-6 md:pt-7 md:text-4xl md:active:border-t-8 xl:px-24 xl:pb-8 xl:pt-10 xl:text-5xl"
                    onClick={() =>
                      setTimeout(() => {
                        // Navigate to the same page with the `start` query parameter set to `true`
                        router.push({
                          pathname: router.pathname,
                          query: { q: "start" },
                        })
                      }, 200)
                    }
                  >
                    START
                  </button>
                </>
              )
          }
        })()}
      </div>
    </div>
  )
}

export const getServerSideProps: GetServerSideProps<Props> = async (
  context
) => {
  const { q } = context.query

  return { props: { q: q ? q : "" } }
}
