<script setup>
import GoogleWidget from "../../components/auth/GoogleWidget.vue";
import AppleWidget from "../../components/auth/AppleWidget.vue";
import MicrosoftWidget from "../../components/auth/MicrosoftWidget.vue";
import LogoWidget from "../../components/landing/LogoWidget.vue";
import BaseCheckbox from "../../components/base/BaseCheckbox.vue";
import BaseInputText from "../../components/base/BaseInputText.vue";
import { ref, onMounted, watch, computed } from "vue";
import { useRoute, useRouter } from "vue-router";

import { api, ensureCsrf } from "../../services/api";
import { hydrateUser } from "../../composables/useAuth";
import { appBranding, loginSettings } from "../../composables/useAppSettings";

const router = useRouter();
const route = useRoute();

const email = ref("");
const password = ref("");
const remember = ref(false);

const submitting = ref(false);

const validationMessage = ref("");

const hasSocialLogin = computed(
  () =>
    loginSettings.providers.microsoft ||
    loginSettings.providers.google ||
    loginSettings.providers.apple,
);

const logoClass = computed(() =>
  hasSocialLogin.value
    ? "max-h-none h-12 sm:h-14 w-auto object-contain"
    : "max-h-none w-auto object-contain max-w-[min(100%,15rem)]",
);

function signInWithMicrosoft() {
  window.location.assign("/auth/microsoft/redirect");
}

function applyOAuthErrorFromQuery() {
  const err = route.query.error;
  if (typeof err === "string" && err.length) {
    validationMessage.value = err;
  }
}

onMounted(applyOAuthErrorFromQuery);
watch(() => route.query.error, applyOAuthErrorFromQuery);

async function onSubmit(event) {
  event.preventDefault();
  validationMessage.value = "";
  submitting.value = true;
  try {
    await ensureCsrf();
    await api.post("/login", {
      email: email.value,
      password: password.value,
      remember: remember.value,
    });
    await hydrateUser();

    const target = typeof route.query.redirect === "string"
      ? route.query.redirect
      : "/dashboard";
    router.replace(target);
  } catch (error) {
    const body = error?.response?.data;
    validationMessage.value =
      body?.message ||
      body?.errors?.email?.[0] ||
      "Could not authenticate. Try again.";
  } finally {
    submitting.value = false;
  }
}
</script>

<template>
  <section
    class="min-h-screen flex items-center lg:items-start lg:py-20 justify-center animate-fadein animate-duration-300 animate-ease-in max-w-[100rem] mx-auto"
  >
    <div class="flex w-full h-full justify-center gap-12">
      <div class="flex flex-col py-20 lg:min-w-[30rem]">
        <div class="flex flex-col justify-center grow">
          <div class="max-w-md mx-auto w-full">
            <router-link
              :to="{ name: 'dashboard' }"
              class="flex justify-center mb-6"
            >
              <LogoWidget :class-name="logoClass" />
            </router-link>
            <h5 class="title-h5 text-center lg:text-left">Login</h5>
            <template v-if="hasSocialLogin">
              <button
                v-if="loginSettings.providers.microsoft"
                type="button"
                class="social-button mt-8"
                @click="signInWithMicrosoft"
              >
                <MicrosoftWidget /> Sign in with Microsoft
              </button>
              <button
                v-if="loginSettings.providers.google"
                type="button"
                class="social-button mt-4"
              >
                <GoogleWidget /> Sign in with Google
              </button>
              <button
                v-if="loginSettings.providers.apple"
                type="button"
                class="social-button mt-4"
              >
                <AppleWidget /> Sign in with Apple
              </button>
              <div class="flex items-center gap-3.5 my-7">
                <span
                  class="flex-1 h-[1px] bg-surface-200 dark:bg-surface-800"
                />
                <span
                  class="body-small text-surface-400 dark:text-surface-600"
                  >or</span
                >
                <span
                  class="flex-1 h-[1px] bg-surface-200 dark:bg-surface-800"
                />
              </div>
            </template>
            <form
              class="flex flex-col gap-4"
              :class="{ 'mt-8': !hasSocialLogin }"
              @submit.prevent="onSubmit"
            >
              <BaseInputText
                v-model="email"
                type="email"
                class="w-full"
                autocomplete="username"
                placeholder="Email"
              />
              <BaseInputText
                v-model="password"
                type="password"
                class="w-full"
                autocomplete="current-password"
                placeholder="Password"
              />
              <div class="flex items-center justify-between pt-4">
                <div class="flex items-center gap-2">
                  <BaseCheckbox
                    v-model="remember"
                    id="remember"
                    :binary="true"
                  />
                  <label for="remember" class="body-small">Remember me</label>
                </div>
              </div>
              <p
                v-if="validationMessage"
                class="text-sm text-red-600 dark:text-red-400 mb-3"
              >
                {{ validationMessage }}
              </p>
              <button
                type="submit"
                class="body-button w-full"
                :disabled="submitting"
              >
                Login
              </button>
            </form>
          </div>
        </div>
        <div
          class="mt-8 text-center lg:text-start block relative text-surface-400 dark:text-surface-500 text-sm"
        >
          ©{{ new Date().getFullYear() }} Maestro
        </div>
      </div>
      <div class="hidden lg:flex h-full py-20">
        <div
          class="h-full w-full lg:max-w-[32.5rem] xl:max-w-[60.5rem] mx-auto flex items-center justify-center shadow-[0px_1px_2px_0px_rgba(18,18,23,0.05)] rounded-3xl overflow-hidden"
        >
          <img
            class="w-auto h-full max-h-[min(100vh-10rem,42rem)] object-contain object-left"
            :src="appBranding.loginHero"
            alt=""
          />
        </div>
      </div>
    </div>
  </section>
</template>
