<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 logoClass =
  "h-16 sm:h-20 w-auto max-w-[17rem] object-contain object-center";

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

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="login-page min-h-screen flex items-center justify-center px-4 py-12 lg:py-20 animate-fadein animate-duration-300 animate-ease-in"
  >
    <div class="login-layout w-full max-w-6xl mx-auto">
      <div class="login-panel w-full max-w-md mx-auto lg:max-w-none">
        <div class="login-panel-content flex flex-col w-full">
          <router-link
            :to="{ name: 'dashboard' }"
            class="login-logo flex justify-center shrink-0"
          >
            <LogoWidget :class-name="logoClass" />
          </router-link>

          <div class="login-card flex flex-col w-full">
            <h5 class="title-h5 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="login-form 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="login-form-actions flex flex-col gap-4">
                <div class="flex items-center gap-2 pt-4">
                  <BaseCheckbox
                    v-model="remember"
                    id="remember"
                    :binary="true"
                  />
                  <label for="remember" class="body-small">Remember me</label>
                </div>
                <p
                  v-if="validationMessage"
                  class="text-sm text-red-600 dark:text-red-400"
                >
                  {{ validationMessage }}
                </p>
                <button
                  type="submit"
                  class="body-button w-full"
                  :disabled="submitting"
                >
                  Login
                </button>
              </div>
            </form>
          </div>
        </div>

        <div
          class="login-panel-footer lg:hidden shrink-0 mt-8 text-center text-surface-400 dark:text-surface-500 text-sm"
        >
          ©{{ new Date().getFullYear() }} Maestro
        </div>
      </div>

      <div class="login-hero-column hidden lg:flex flex-col min-w-0">
        <div
          class="login-hero-frame shadow-[0px_1px_2px_0px_rgba(18,18,23,0.05)] rounded-3xl overflow-hidden"
        >
          <img
            class="login-hero-image w-full h-full object-cover object-center"
            :src="appBranding.loginHero"
            alt=""
          />
        </div>
        <p
          class="login-hero-footer shrink-0 mt-4 text-center text-surface-400 dark:text-surface-500 text-sm"
        >
          ©{{ new Date().getFullYear() }} Maestro
        </p>
      </div>
    </div>
  </section>
</template>

<style scoped>
.login-panel-content {
  gap: 2rem;
}

.login-card {
  gap: 0;
}

@media (min-width: 1024px) {
  .login-layout {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    gap: 3rem;
    align-items: start;
  }

  .login-panel,
  .login-hero-frame {
    height: min(100vh - 10rem, 42rem);
    max-height: min(100vh - 10rem, 42rem);
  }

  .login-panel {
    display: flex;
    flex-direction: column;
    justify-content: center;
    max-width: none;
    margin: 0;
    min-height: 0;
  }

  .login-panel-content {
    gap: 2.5rem;
    max-height: 100%;
    overflow-y: auto;
  }

  .login-hero-frame {
    width: 100%;
  }
}
</style>
