<script setup lang="ts">
import { computed, reactive, ref } from 'vue'
import { RouterLink, useRoute, useRouter } from 'vue-router'

import PasswordField from '../components/ui/PasswordField.vue'
import { useAuthStore } from '../stores/auth'
import { ApiRequestError } from '../lib/http'

const authStore = useAuthStore()
const route = useRoute()
const router = useRouter()

const form = reactive({
  login: '',
  password: '',
})

const passwordForm = reactive({
  currentPassword: '',
  newPassword: '',
  confirmPassword: '',
})

const loginMode = ref<'password' | 'twitch'>('password')
const errorMessage = ref('')
const successMessage = ref('')
const loginFormElement = ref<HTMLFormElement | null>(null)
const passwordChangeFormElement = ref<HTMLFormElement | null>(null)

const passwordChangeRequired = computed(() => Boolean(authStore.session?.mustChangePassword))
const successMessageClass = computed(() =>
  passwordChangeRequired.value ? 'login-form__warning' : 'login-form__success',
)

const redirectTarget = computed(() => {
  const redirect = Array.isArray(route.query.redirect)
    ? route.query.redirect[0]
    : route.query.redirect

  if (!redirect || !redirect.startsWith('/') || redirect.startsWith('/login')) {
    return '/admin'
  }

  return redirect
})

async function submitLogin() {
  if (authStore.loading) {
    return
  }

  errorMessage.value = ''
  successMessage.value = ''

  try {
    await authStore.demoLogin({
      login: form.login,
      password: form.password,
    })
  } catch (error) {
    try {
      await authStore.teamLogin({
        login: form.login,
        password: form.password,
      })
    } catch (teamError) {
      if (error instanceof ApiRequestError && error.status === 503) {
        errorMessage.value = 'Der Demo-Login ist im Backend noch nicht vollständig konfiguriert.'
        return
      }

      if (error instanceof ApiRequestError && error.status === 404 && teamError instanceof ApiRequestError && teamError.status === 404) {
        errorMessage.value = 'Der Team-Login ist auf diesem Deployment nicht aktiviert.'
        return
      }

      errorMessage.value = 'Login oder Passwort stimmt nicht.'
      return
    }
  }

  if (authStore.session?.mustChangePassword) {
    passwordForm.currentPassword = form.password
    form.password = ''
    successMessage.value = 'Bitte setze jetzt ein eigenes Passwort für diesen Team-Login.'
    return
  }

  await router.replace(redirectTarget.value)
}

async function startTwitchLogin() {
  if (authStore.loading) {
    return
  }

  errorMessage.value = ''
  successMessage.value = ''

  try {
    await authStore.startTwitchAuthorization({
      purpose: 'team-login',
      returnUrl: redirectTarget.value,
    })
  } catch (error) {
    errorMessage.value = error instanceof Error
      ? error.message
      : 'Twitch-Login konnte nicht gestartet werden.'
  }
}

async function submitPasswordChange() {
  if (authStore.loading) {
    return
  }

  errorMessage.value = ''
  successMessage.value = ''

  if (passwordForm.newPassword.length < 10) {
    errorMessage.value = 'Das neue Passwort muss mindestens 10 Zeichen lang sein.'
    return
  }

  if (passwordForm.newPassword !== passwordForm.confirmPassword) {
    errorMessage.value = 'Die neuen Passwörter stimmen nicht überein.'
    return
  }

  try {
    await authStore.changePassword({
      currentPassword: passwordForm.currentPassword,
      newPassword: passwordForm.newPassword,
    })

    await router.replace(redirectTarget.value)
  } catch (error) {
    errorMessage.value = error instanceof ApiRequestError
      ? error.message
      : 'Das Passwort konnte nicht geändert werden.'
  }
}
</script>

<template>
  <main class="login-page">
    <div class="login-page__stars" aria-hidden="true">
      <span class="login-page__star login-page__star--one">✦</span>
      <span class="login-page__star login-page__star--two">✧</span>
      <span class="login-page__star login-page__star--three">✦</span>
      <span class="login-page__star login-page__star--four">✧</span>
    </div>

    <RouterLink to="/" class="login-page__brand" aria-label="Zur Landingpage">
      <span class="login-page__brand-icon">✦</span>
      <span>VTuber Star Award</span>
    </RouterLink>

    <section class="login-card" aria-labelledby="login-title">
      <div class="login-card__eyebrow">{{ passwordChangeRequired ? 'Erster Login' : 'Team Zugang' }}</div>
      <h1 id="login-title">{{ passwordChangeRequired ? 'Passwort ändern' : 'Admin Login' }}</h1>
      <p>
        <template v-if="passwordChangeRequired">
          Dieser Account wurde mit einem temporären Passwort erstellt. Bitte vergib jetzt ein eigenes Passwort.
        </template>
        <template v-else>
          Melde dich mit Team-Login an oder nutze deinen gebundenen Twitch-Account.
        </template>
      </p>

      <div v-if="!passwordChangeRequired" class="login-mode-toggle" role="tablist" aria-label="Login-Art">
        <button
          type="button"
          :class="loginMode === 'password' ? 'login-mode-toggle__button login-mode-toggle__button--active' : 'login-mode-toggle__button'"
          @click="loginMode = 'password'"
        >
          Login
        </button>
        <button
          type="button"
          :class="loginMode === 'twitch' ? 'login-mode-toggle__button login-mode-toggle__button--active' : 'login-mode-toggle__button'"
          @click="loginMode = 'twitch'"
        >
          Twitch
        </button>
      </div>

      <form ref="loginFormElement" v-if="!passwordChangeRequired && loginMode === 'password'" class="login-form" @submit.prevent="submitLogin">
        <label>
          <span>Login</span>
          <input
            v-model.trim="form.login"
            type="text"
            autocomplete="username"
            required
            placeholder="E-Mail oder Username"
            @keydown.enter.exact.prevent="loginFormElement?.requestSubmit()"
          >
        </label>

        <label>
          <span>Passwort</span>
          <PasswordField
            v-model="form.password"
            variant="login"
            autocomplete="current-password"
            required
            placeholder="Team-Passwort eingeben"
            @keydown.enter.exact.prevent="loginFormElement?.requestSubmit()"
          />
        </label>

        <p v-if="errorMessage" class="login-form__error" role="alert">
          {{ errorMessage }}
        </p>

        <p v-if="successMessage" :class="successMessageClass" role="status">
          {{ successMessage }}
        </p>

        <button class="login-form__submit" type="submit" :disabled="authStore.loading">
          <span v-if="authStore.loading">Sternentor öffnet...</span>
          <span v-else>Admin Panel öffnen</span>
        </button>
      </form>

      <form v-else-if="!passwordChangeRequired" class="login-form" @submit.prevent="startTwitchLogin">
        <div class="login-form__oauth-note">
          <strong>Offizieller Twitch Login</strong>
          <span>Du wirst zu Twitch weitergeleitet und danach automatisch zurück ins Admin Panel gebracht.</span>
        </div>

        <p v-if="errorMessage" class="login-form__error" role="alert">
          {{ errorMessage }}
        </p>

        <p v-if="successMessage" :class="successMessageClass" role="status">
          {{ successMessage }}
        </p>

        <button class="login-form__submit" type="submit" :disabled="authStore.loading">
          <span v-if="authStore.loading">Twitch wird geöffnet...</span>
          <span v-else>Mit Twitch offiziell anmelden</span>
        </button>
      </form>

      <form ref="passwordChangeFormElement" v-else class="login-form" @submit.prevent="submitPasswordChange">
        <label>
          <span>Aktuelles Passwort</span>
          <PasswordField
            v-model="passwordForm.currentPassword"
            variant="login"
            autocomplete="current-password"
            required
            placeholder="Temporäres Passwort"
            @keydown.enter.exact.prevent="passwordChangeFormElement?.requestSubmit()"
          />
        </label>

        <label>
          <span>Neues Passwort</span>
          <PasswordField
            v-model="passwordForm.newPassword"
            variant="login"
            autocomplete="new-password"
            required
            minlength="10"
            placeholder="Mindestens 10 Zeichen"
            @keydown.enter.exact.prevent="passwordChangeFormElement?.requestSubmit()"
          />
        </label>

        <label>
          <span>Passwort wiederholen</span>
          <PasswordField
            v-model="passwordForm.confirmPassword"
            variant="login"
            autocomplete="new-password"
            required
            minlength="10"
            placeholder="Neues Passwort bestätigen"
            @keydown.enter.exact.prevent="passwordChangeFormElement?.requestSubmit()"
          />
        </label>

        <p v-if="errorMessage" class="login-form__error" role="alert">
          {{ errorMessage }}
        </p>

        <p v-if="successMessage" :class="successMessageClass" role="status">
          {{ successMessage }}
        </p>

        <button class="login-form__submit" type="submit" :disabled="authStore.loading">
          <span v-if="authStore.loading">Passwort wird gespeichert...</span>
          <span v-else>Passwort speichern</span>
        </button>
      </form>

      <div class="login-card__footer">
        <RouterLink to="/">Zurück zur Landingpage</RouterLink>
        <span>Demo-Modus</span>
      </div>
    </section>
  </main>
</template>

<style scoped>
.login-page {
  position: relative;
  min-height: 100vh;
  overflow: hidden;
  display: grid;
  place-items: center;
  padding: 32px 18px;
  background:
    radial-gradient(circle at 18% 24%, rgba(255, 221, 238, 0.9), transparent 26%),
    radial-gradient(circle at 82% 20%, rgba(210, 190, 255, 0.75), transparent 28%),
    radial-gradient(circle at 50% 100%, rgba(255, 220, 151, 0.38), transparent 32%),
    linear-gradient(145deg, #fbf6ff 0%, #f2e9ff 48%, #fff8f1 100%);
  color: #3f3556;
  font-family: 'Outfit', sans-serif;
}

.login-page::before {
  content: "";
  position: absolute;
  inset: 11% 8% auto;
  height: 330px;
  border-radius: 999px;
  background: linear-gradient(90deg, rgba(139, 108, 219, 0.14), rgba(231, 177, 62, 0.16), rgba(247, 108, 173, 0.12));
  filter: blur(42px);
  transform: rotate(-6deg);
}

.login-page__brand {
  position: absolute;
  top: 28px;
  left: 32px;
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: #3f3556;
  text-decoration: none;
  font-family: 'Fredoka', sans-serif;
  font-weight: 700;
  font-size: 18px;
}

.login-page__brand-icon {
  display: inline-grid;
  place-items: center;
  width: 36px;
  height: 36px;
  border-radius: 13px;
  color: #fff;
  background: linear-gradient(135deg, #8b6cdb, #e7b13e);
  box-shadow: 0 14px 30px rgba(139, 108, 219, 0.26);
}

.login-page__stars {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.login-page__star {
  position: absolute;
  color: rgba(139, 108, 219, 0.7);
  text-shadow: 0 0 22px rgba(139, 108, 219, 0.4);
  animation: loginTwinkle 3s ease-in-out infinite;
}

.login-page__star--one {
  top: 18%;
  left: 22%;
  font-size: 34px;
}

.login-page__star--two {
  top: 21%;
  right: 20%;
  font-size: 28px;
  animation-delay: 0.8s;
}

.login-page__star--three {
  bottom: 20%;
  left: 18%;
  font-size: 22px;
  color: rgba(231, 177, 62, 0.72);
  animation-delay: 1.3s;
}

.login-page__star--four {
  right: 17%;
  bottom: 24%;
  font-size: 24px;
  color: rgba(247, 108, 173, 0.62);
  animation-delay: 1.9s;
}

.login-card {
  position: relative;
  z-index: 1;
  width: min(100%, 520px);
  padding: 42px;
  border: 1px solid rgba(139, 108, 219, 0.18);
  border-radius: 38px;
  background: rgba(255, 255, 255, 0.72);
  box-shadow: 0 28px 80px rgba(76, 48, 119, 0.16);
  backdrop-filter: blur(22px);
}

.login-card__eyebrow {
  color: #8b6cdb;
  font-size: 13px;
  font-weight: 900;
  letter-spacing: 0.22em;
  text-transform: uppercase;
}

.login-card h1 {
  margin: 10px 0 12px;
  font-family: 'Playfair Display', serif;
  font-size: clamp(42px, 8vw, 70px);
  line-height: 0.95;
  color: #3f3556;
}

.login-card p {
  margin: 0;
  color: #736987;
  font-size: 17px;
  line-height: 1.65;
}

.login-form {
  display: grid;
  gap: 18px;
  margin-top: 30px;
}

.login-mode-toggle {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 6px;
  margin: 24px 0 18px;
  padding: 6px;
  border: 1px solid rgba(124, 86, 196, 0.16);
  border-radius: 16px;
  background: rgba(255, 255, 255, 0.65);
}

.login-mode-toggle__button {
  min-height: 42px;
  border: 0;
  border-radius: 11px;
  background: transparent;
  color: #7c7192;
  font-family: 'Outfit', sans-serif;
  font-size: 14px;
  font-weight: 800;
  cursor: pointer;
}

.login-mode-toggle__button--active {
  background: #6f4fd1;
  color: #fff;
  box-shadow: 0 10px 22px rgba(111, 79, 209, 0.24);
}

.login-form label {
  display: grid;
  gap: 9px;
  color: #65748b;
  font-size: 12px;
  font-weight: 900;
  letter-spacing: 0.18em;
  text-transform: uppercase;
}

.login-form input {
  width: 100%;
  box-sizing: border-box;
  border: 1.5px solid #ded4ff;
  border-radius: 22px;
  padding: 17px 18px;
  background: rgba(255, 255, 255, 0.82);
  color: #3f3556;
  font: 700 17px 'Outfit', sans-serif;
  outline: none;
  box-shadow: 0 12px 32px rgba(139, 108, 219, 0.06);
  transition: border-color 0.2s ease, box-shadow 0.2s ease, transform 0.2s ease;
}

.login-form input:focus {
  border-color: #8b6cdb;
  box-shadow: 0 0 0 5px rgba(139, 108, 219, 0.14);
  transform: translateY(-1px);
}

.login-form__oauth-note {
  display: grid;
  gap: 6px;
  padding: 16px;
  border: 1px solid rgba(145, 70, 255, 0.16);
  border-radius: 18px;
  background: rgba(248, 245, 255, 0.88);
  color: #6f6685;
  font-size: 14px;
  line-height: 1.5;
}

.login-form__oauth-note strong {
  color: #3f3556;
  font-size: 15px;
}

.login-form__error {
  padding: 13px 15px;
  border: 1px solid rgba(225, 29, 72, 0.18);
  border-radius: 18px;
  background: rgba(255, 241, 242, 0.9);
  color: #be123c !important;
  font-size: 14px !important;
  font-weight: 800;
}

.login-form__success {
  padding: 13px 15px;
  border: 1px solid rgba(22, 163, 74, 0.18);
  border-radius: 18px;
  background: rgba(240, 253, 244, 0.9);
  color: #15803d !important;
  font-size: 14px !important;
  font-weight: 800;
}

.login-form__warning {
  padding: 13px 15px;
  border: 1px solid rgba(217, 119, 6, 0.24);
  border-radius: 18px;
  background: rgba(255, 251, 235, 0.96);
  color: #b45309 !important;
  font-size: 14px !important;
  font-weight: 800;
}

.login-form__submit {
  min-height: 58px;
  border: 0;
  border-radius: 999px;
  color: #fff;
  cursor: pointer;
  font: 900 17px 'Fredoka', sans-serif;
  background: linear-gradient(135deg, #7c52dc 0%, #ad42e8 48%, #f76cad 100%);
  box-shadow: 0 18px 40px rgba(139, 108, 219, 0.32);
  transition: transform 0.2s ease, box-shadow 0.2s ease, opacity 0.2s ease;
}

.login-form__submit:hover:not(:disabled) {
  transform: translateY(-2px);
  box-shadow: 0 22px 48px rgba(139, 108, 219, 0.38);
}

.login-form__submit:disabled {
  cursor: wait;
  opacity: 0.72;
}

.login-card__footer {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 24px;
  color: #9286a7;
  font-size: 14px;
  font-weight: 700;
}

.login-card__footer a {
  color: #7355c8;
  text-decoration: none;
}

@keyframes loginTwinkle {
  0%, 100% {
    opacity: 0.45;
    transform: scale(0.92) rotate(0deg);
  }

  50% {
    opacity: 1;
    transform: scale(1.08) rotate(8deg);
  }
}

@media (max-width: 640px) {
  .login-page {
    place-items: start center;
    padding-top: 104px;
  }

  .login-page__brand {
    left: 18px;
    top: 20px;
  }

  .login-card {
    padding: 30px 22px;
    border-radius: 30px;
  }
}
</style>
