<template>
  <div class="grow flex items-center justify-center py-12 px-4 sm:px-6 lg:px-8">
    <div class="max-w-md w-full space-y-8 pb-20">
      <div class="flex flex-col items-center gap-4">
        <AppLogo />
        <h2 class="text-center text-4xl font-extrabold text-gray-900">
          {{ clubName }}
        </h2>
      </div>

      <form class="flex flex-col gap-2" @submit.prevent="submit">
        <div class="-space-y-px">
          <div class="relative">
            <input
              id="username"
              name="username"
              type="text"
              required
              placeholder="Benutzer"
              :class="routine == '' ? '' : 'rounded-b-none!'"
              :value="username"
              :disabled="username != ''"
            />
            <div v-if="usernameStatus" class="h-full flex items-center justify-center w-5 absolute top-0 right-2">
              <Spinner v-if="usernameStatus == 'loading'" class="my-auto" />
              <SuccessCheckmark v-else-if="usernameStatus == 'success'" />
              <FailureXMark v-else-if="usernameStatus == 'failed'" />
            </div>
          </div>
          <div v-if="routine != ''">
            <input
              v-if="routine == 'totp'"
              id="totp"
              name="totp"
              type="text"
              required
              placeholder="TOTP"
              class="rounded-t-none!"
              autocomplete="off"
            />
            <input
              v-else
              id="password"
              name="password"
              type="password"
              required
              placeholder="Passwort"
              class="rounded-t-none!"
              autocomplete="current-password"
            />
          </div>
        </div>
        <p v-if="username != ''" class="w-fit self-end text-primary cursor-pointer" @click="resetRoutine">
          Benutzer wechseln
        </p>
        <RouterLink :to="{ name: 'reset-start' }" class="w-fit self-end text-primary">Zugang verloren</RouterLink>

        <div class="flex flex-row gap-2">
          <button type="submit" primary :disabled="loginStatus == 'loading' || loginStatus == 'success'">
            {{ routine == "" ? "Benutzer prüfen" : "anmelden" }}
          </button>
          <Spinner v-if="loginStatus == 'loading'" class="my-auto" />
          <SuccessCheckmark v-else-if="loginStatus == 'success'" />
          <FailureXMark v-else-if="loginStatus == 'failed'" />
        </div>
        <p v-if="loginError" class="text-center">{{ loginError }}</p>
      </form>

      <FormBottomBar />
    </div>
  </div>
</template>

<script setup lang="ts">
import { defineComponent } from "vue";
import Spinner from "@/components/Spinner.vue";
import SuccessCheckmark from "@/components/SuccessCheckmark.vue";
import FailureXMark from "@/components/FailureXMark.vue";
import { resetAllPiniaStores } from "@/helpers/piniaReset";
import FormBottomBar from "@/components/FormBottomBar.vue";
import AppLogo from "@/components/AppLogo.vue";
import { mapState } from "pinia";
import { useConfigurationStore } from "@/stores/configuration";
import { hashString } from "../helpers/crypto";
</script>

<script lang="ts">
export default defineComponent({
  data() {
    return {
      loginStatus: undefined as undefined | "loading" | "success" | "failed",
      usernameStatus: undefined as undefined | "loading" | "success" | "failed",
      loginError: "" as string,
      username: "" as string,
      routine: "" as string,
    };
  },
  computed: {
    ...mapState(useConfigurationStore, ["clubName"]),
  },
  mounted() {
    resetAllPiniaStores();
    this.username = localStorage.getItem("username") ?? "";
    this.routine = localStorage.getItem("routine") ?? "";

    if (this.username != "") {
      this.$http
        .post(`/auth/kickof`, {
          username: this.username,
        })
        .then((result) => {
          this.usernameStatus = "success";
          this.routine = result.data.routine;
          localStorage.setItem("routine", result.data.routine);
        })
        .catch((err) => {
          this.usernameStatus = "failed";
          this.loginError = err.response?.data;
        });
    }
  },
  methods: {
    resetRoutine() {
      this.routine = "";
      this.username = "";
      localStorage.removeItem("routine");
      localStorage.removeItem("username");
    },
    submit(e: any) {
      if (this.routine == "") this.kickof(e);
      else this.login(e);
    },
    kickof(e: any) {
      let formData = e.target.elements;
      let username = formData.username.value;
      this.usernameStatus = "loading";
      this.loginError = "";
      this.$http
        .post(`/auth/kickof`, {
          username: username,
        })
        .then((result) => {
          this.usernameStatus = "success";
          this.routine = result.data.routine;
          this.username = username;
          localStorage.setItem("routine", result.data.routine);
          localStorage.setItem("username", username);
        })
        .catch((err) => {
          this.usernameStatus = "failed";
          this.loginError = err.response?.data;
        })
        .finally(() => {
          setTimeout(() => {
            this.usernameStatus = undefined;
            this.loginError = "";
          }, 2000);
        });
    },
    async login(e: any) {
      let formData = e.target.elements;
      this.loginStatus = "loading";
      this.loginError = "";

      let secret = "";
      if (this.routine == "totp") {
        secret = formData.totp.value;
      } else {
        secret = await hashString(formData.password.value);
      }

      this.$http
        .post(`/auth/login`, {
          username: formData.username.value,
          secret: secret,
        })
        .then((result) => {
          this.loginStatus = "success";
          localStorage.setItem("accessToken", result.data.accessToken);
          localStorage.setItem("refreshToken", result.data.refreshToken);
          setTimeout(() => {
            this.$router.push(`/admin`);
          }, 1000);
        })
        .catch((err) => {
          this.loginStatus = "failed";
          this.loginError = err.response?.data;
        });
    },
  },
});
</script>