<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-14 sm:h-16 w-auto max-w-[14rem] 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 flex flex-col w-full max-w-md mx-auto lg:max-w-none">
        <router-link
          :to="{ name: 'dashboard' }"
          class="login-logo flex justify-center mb-4 lg:mb-6"
        >
          <LogoWidget :class-name="logoClass" />
        </router-link>

        <div class="login-form-stack flex flex-col min-h-0">
          <h5 class="title-h5 text-center">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 mt-auto 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
          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>
@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 {
    max-width: none;
    margin: 0;
    min-height: 0;
  }

  .login-form-stack {
    flex: 1;
    min-height: 0;
    overflow-y: auto;
  }

  .login-form {
    flex: 1;
    min-height: 0;
    display: flex;
    flex-direction: column;
  }

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