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

import iconImage from '@/assets/images/icon.svg'
import { AuthRequestError, login } from '@/services/authSession'
import { useAppBannersStore } from '@/stores/appBanners'

const showPassword = ref(false)
const userName = ref('')
const password = ref('')
const isSubmitting = ref(false)
const appBannersStore = useAppBannersStore()

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

const submitDisabled = computed(
  () => isSubmitting.value || userName.value.trim().length === 0 || password.value.length === 0,
)

const redirectPath = computed(() => {
  const redirectQuery = route.query.redirect
  if (typeof redirectQuery === 'string' && redirectQuery.startsWith('/')) {
    return redirectQuery
  }

  return '/'
})

async function handleSubmit() {
  if (submitDisabled.value) {
    appBannersStore.pushError('Bitte Benutzername und Passwort eingeben.', 'Anmeldung fehlgeschlagen')
    return
  }

  isSubmitting.value = true

  try {
    await login({
      userName: userName.value.trim(),
      password: password.value,
    })

    await router.replace(redirectPath.value)
  } catch (error) {
    if (error instanceof AuthRequestError) {
      appBannersStore.pushError(error.message, 'Anmeldung fehlgeschlagen')
    } else {
      appBannersStore.pushError(
        'Anmeldung fehlgeschlagen. Bitte versuche es erneut.',
        'Anmeldung fehlgeschlagen',
      )
    }
  } finally {
    isSubmitting.value = false
  }
}

onMounted(() => {
  const passwordChangedFlag = route.query.passwordChanged
  if (passwordChangedFlag !== '1' && passwordChangedFlag !== 'true') {
    return
  }

  appBannersStore.push({
    type: 'success',
    title: 'Passwort geändert',
    message: 'Bitte melde dich mit deinem neuen Passwort an.',
  })

  const nextQuery = Object.fromEntries(
    Object.entries(route.query).filter(([key]) => key !== 'passwordChanged'),
  )

  void router.replace({
    query: nextQuery,
  })
})
</script>

<template>
  <v-container fluid class="login-page hoard-page hoard-page--centered">
    <section class="login-shell hoard-panel hoard-panel-gradient hoard-spotlight">
      <aside class="login-brand">
        <div class="login-brand__logo">
          <span class="login-brand__halo" aria-hidden="true" />
          <img :src="iconImage" alt="Hoard Icon" />
        </div>

        <p class="hoard-kicker hoard-kicker--wide">Willkommen bei Hoard</p>
        <h1>
          Deine Dateien.<br />
          <span class="login-brand__accent">Aufgeräumt.</span>
        </h1>
        <p class="login-intro">
          Hoard ist deine ruhige, self-hosted Dateiablage – schnell, übersichtlich und direkt im Browser.
          Melde dich an und mach weiter, wo du aufgehört hast.
        </p>

        <ul class="login-points">
          <li>
            <span class="hoard-icon-tile"><v-icon icon="mdi-folder-outline" size="18" /></span>
            <div>
              <p class="login-points__title">Ordner und Dateien</p>
              <p class="login-points__text">Zentral organisieren, schnell finden, sauber strukturieren.</p>
            </div>
          </li>
          <li>
            <span class="hoard-icon-tile"><v-icon icon="mdi-language-markdown-outline" size="18" /></span>
            <div>
              <p class="login-points__title">Markdown direkt im Browser</p>
              <p class="login-points__text">Notizen lesen und bearbeiten, ohne externes Tool.</p>
            </div>
          </li>
          <li>
            <span class="hoard-icon-tile"><v-icon icon="mdi-shield-check-outline" size="18" /></span>
            <div>
              <p class="login-points__title">Self-hosted &amp; sicher</p>
              <p class="login-points__text">Cookie-Auth, Rollenmodell, deine Infrastruktur.</p>
            </div>
          </li>
        </ul>
      </aside>

      <v-form class="login-form" @submit.prevent="handleSubmit">
        <header class="login-form__head">
          <p class="hoard-kicker hoard-kicker--xs">Login</p>
          <h2>Anmelden</h2>
          <p>Melde dich mit deinem bestehenden Hoard-Konto an.</p>
        </header>

        <div class="login-form__fields">
          <v-text-field
            v-model="userName"
            label="Benutzername"
            type="text"
            prepend-inner-icon="mdi-account-outline"
            autocomplete="username"
            required
            :disabled="isSubmitting"
          />

          <v-text-field
            v-model="password"
            label="Passwort"
            :type="showPassword ? 'text' : 'password'"
            prepend-inner-icon="mdi-lock-outline"
            :append-inner-icon="showPassword ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
            autocomplete="current-password"
            required
            :disabled="isSubmitting"
            @click:append-inner="showPassword = !showPassword"
          />
        </div>

        <p class="login-form__hint">
          <v-icon icon="mdi-cookie-outline" size="14" />
          Anmeldung erfolgt per sicherem Session-Cookie. Keine Tokens, keine Drittanbieter.
        </p>

        <v-btn
          type="submit"
          variant="elevated"
          block
          size="large"
          prepend-icon="mdi-arrow-right"
          :loading="isSubmitting"
          :disabled="submitDisabled"
        >
          Anmelden
        </v-btn>

        <v-btn variant="text" block to="/welcome" prepend-icon="mdi-home-outline" size="small">
          Zurück zur Startseite
        </v-btn>
      </v-form>
    </section>
  </v-container>
</template>

<style scoped>
.login-page {
  --hoard-centered-offset: 200px;
}

.login-shell {
  --hoard-shell-width: 1080px;
  --hoard-shell-padding: 0;
  --hoard-shell-gap: 0;
  --hoard-gradient-angle: 120deg;
  --hoard-gradient-start: color-mix(in srgb, var(--color-primary-100) 70%, var(--color-surface) 30%);
  --hoard-gradient-end: var(--color-surface);
  --hoard-gradient-end-stop: 60%;

  grid-template-columns: minmax(280px, 1.1fr) minmax(320px, 460px);
  border-radius: var(--radius-xl);
  overflow: hidden;
}

.login-brand {
  position: relative;
  padding: var(--space-10) var(--space-8);
  display: flex;
  flex-direction: column;
  justify-content: center;
  z-index: 1;
}

.login-brand__logo {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 64px;
  height: 64px;
  margin-bottom: var(--space-5);
}

.login-brand__halo {
  position: absolute;
  inset: -12px;
  border-radius: var(--radius-full);
  background:
    radial-gradient(
      closest-side,
      color-mix(in srgb, var(--color-accent-lime) 38%, transparent),
      transparent 70%
    );
  filter: blur(10px);
  opacity: 0.7;
}

.login-brand__logo img {
  position: relative;
  width: 64px;
  height: 64px;
  object-fit: contain;
  filter: drop-shadow(0 8px 18px rgb(28 101 47 / 30%));
}

h1 {
  margin: 0 0 var(--space-3);
  max-width: 16ch;
  font-size: clamp(2rem, 1.4rem + 1.5vw, 2.8rem);
  font-weight: 700;
  line-height: 1.05;
  letter-spacing: -0.025em;
}

.login-brand__accent {
  background: linear-gradient(120deg, var(--color-primary-700), var(--color-primary-500));
  -webkit-background-clip: text;
  background-clip: text;
  color: transparent;
}

.login-intro {
  margin: 0 0 var(--space-6);
  max-width: 46ch;
  color: var(--color-text-secondary);
  font-size: var(--font-size-md);
  line-height: 1.6;
}

.login-points {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  padding: 0;
  margin: 0;
  list-style: none;
}

.login-points li {
  display: grid;
  grid-template-columns: auto 1fr;
  gap: var(--space-3);
  align-items: flex-start;
}

.login-points__title,
.login-points__text {
  margin: 0;
}

.login-points__title {
  color: var(--color-text);
  font-size: var(--font-size-md);
  font-weight: 600;
  line-height: 1.3;
}

.login-points__text {
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
  line-height: 1.5;
}

.login-form {
  position: relative;
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-8);
  border-left: 1px solid var(--color-border);
  background:
    linear-gradient(
      180deg,
      color-mix(in srgb, var(--color-surface) 96%, var(--color-surface-alt) 4%),
      var(--color-surface)
    );
  z-index: 1;
}

.login-form__head {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.login-form__head h2 {
  margin: 0;
  font-size: var(--font-size-2xl);
  letter-spacing: -0.015em;
}

.login-form__head p {
  margin: 0;
  color: var(--color-text-secondary);
}

.login-form__fields {
  display: grid;
  gap: var(--space-3);
}

.login-form__hint {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  padding: var(--space-3);
  border-radius: var(--radius-sm);
  background-color: color-mix(in srgb, var(--color-surface-alt) 80%, var(--color-surface) 20%);
  color: var(--color-text-muted);
  font-size: var(--font-size-xs);
  line-height: 1.45;
}

.login-form__hint .v-icon {
  color: var(--color-primary-700);
  flex: 0 0 auto;
}

@media (prefers-reduced-motion: no-preference) {
  .login-brand,
  .login-form {
    animation: hoard-soft-enter 320ms both;
  }

  .login-form {
    animation-delay: 80ms;
  }
}

@media (width <= 960px) {
  .login-shell {
    grid-template-columns: 1fr;
  }

  .login-brand {
    padding: var(--space-7) var(--space-6) 0;
  }

  .login-form {
    padding: var(--space-6);
    border-left: none;
    border-top: 1px solid var(--color-border);
  }
}

@media (width <= 600px) {
  .login-brand {
    padding: var(--space-6) var(--space-5) 0;
  }

  .login-form {
    padding: var(--space-5);
  }

  .login-intro {
    margin-bottom: var(--space-5);
  }

  .login-points li {
    align-items: flex-start;
  }

  :deep(.login-form .v-btn) {
    min-height: 44px;
  }
}
</style>
