<script setup lang="ts">
import {onBeforeMount, onMounted, ref} from "vue";
import { checkIfLoggedIn } from "@/helpers/api.ts";
import {useRoute, useRouter} from "vue-router";
import Password from "primevue/password";
import {Form, type FormResolverOptions, type FormSubmitEvent} from "@primevue/forms";
import InputText from "primevue/inputtext";
import Button from "primevue/button";
import Message from "primevue/message";
import Divider from "primevue/divider";
import { useToast } from 'primevue/usetoast';

const toast = useToast();
const route = useRoute();

const router = useRouter();
const loggedIn = ref<boolean>(true);

onBeforeMount(async () => {
  loggedIn.value = await checkIfLoggedIn();
  if (loggedIn.value) {
    await router.push('/');
    return;
  }
});

onMounted(() => {
  if ("error" in route.query) {
    toast.add({
      severity: "error",
      detail: route.query.error
    });
  }
});

const onFormSubmit = (ev: FormSubmitEvent) => {
  if (!ev.valid) {
    toast.add({
      severity: "error",
      detail: "Invalid data supplied."
    });
  } else {
    const form = ev.originalEvent.target as HTMLFormElement;
    form.method = "POST";
    form.action = "/api/user/register";
    form.submit();
  }
};

const formResolver = (ev: FormResolverOptions): Record<string, any> => {
  const resp: Record<string, any> = {
    errors: {
      Username: [],
      Password: [],
      RepeatPassword: []
    }
  };

  const usernameRegex = /^[a-zA-Z0-9_.]*$/;
  if ("Username" in ev.values) {
    if (ev.values["Username"] === undefined) {
      resp.errors["Username"] = ["Username cannot be blank."];
    } else if (!ev.values["Username"].match(usernameRegex)) {
      resp.errors["Username"] = ["Username contains illegal characters."];
    }
  }
  
  const regex = /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@#$%^&*!])[A-Za-z\d@#$%^&*!]{8,}$/;
  if ("Password" in ev.values && ev.values["Password"] === undefined || !ev.values["Password"].match(regex)) {
    resp.errors["Password"] = ["Password doesn't meet requirements."];
  }
  
  if ("RepeatPassword" in ev.values && ev.values["RepeatPassword"] === undefined || ev.values["RepeatPassword"] != ev.values["Password"]) {
    resp.errors["RepeatPassword"] = ["Invalid repeat password."];
  }
  
  return resp;
};
</script>

<template>
  <div class="w-full h-full flex flex-col justify-center items-center space-y-3">
    <h1 class="text-7xl font-extrabold text-amber-500">Register</h1>
    <Form v-slot="$form" :resolver="formResolver" :validateOnValueUpdate="true" :validateOnBlur="true" @submit="onFormSubmit" class="flex flex-col space-y-2">
      <div class="flex flex-col gap-1">
        <InputText name="Username" type="text" placeholder="Username" fluid required />
        <Message v-if="$form.Username?.invalid" severity="error" size="small" variant="simple">{{ $form.Username.error }}</Message>
      </div>
      <div class="flex flex-col gap-1">
        <Password name="Password" type="text" placeholder="Password" toggleMask required>
          <template #header>
            <h6>Pick a password</h6>
          </template>
          <template #footer>
            <Divider />
            <p class="mt-2">Requirements</p>
            <ul class="pl-2 ml-2 mt-0" style="line-height: 1.5">
              <li>At least one lowercase</li>
              <li>At least one uppercase</li>
              <li>At least one numeric</li>
              <li>At least one of @#$%^&*!</li>
              <li>Minimum 8 characters</li>
            </ul>
          </template>
        </Password>
        <Message v-if="$form.Password?.invalid" severity="error" size="small" variant="simple">{{ $form.Password.error }}</Message>
      </div>
      <div class="flex flex-col gap-1">
        <Password name="RepeatPassword" type="text" placeholder="Repeat Password" toggleMask required />
        <Message v-if="$form.RepeatPassword?.invalid" severity="error" size="small" variant="simple">{{ $form.RepeatPassword.error }}</Message>
      </div>
      <Button type="submit" severity="secondary" label="Register" />
      <div class="text-gray-500 text-sm">Already have an account? <a href="/login" class="text-amber-600 hover:underline">Log in here!</a></div>
    </Form>
  </div>
</template>

<style scoped>

</style>