<script setup lang="ts">
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import { AuthRequestError, changePassword } from '@/services/authSession'
import { useAppBannersStore } from '@/stores/appBanners'

const router = useRouter()
const appBannersStore = useAppBannersStore()

const oldPassword = ref('')
const newPassword = ref('')
const newPasswordConfirm = ref('')

const showOldPassword = ref(false)
const showNewPassword = ref(false)
const showNewPasswordConfirm = ref(false)

const isSubmitting = ref(false)
const errorMessage = ref('')

const submitDisabled = computed(() => {
  return (
    isSubmitting.value ||
    oldPassword.value.length === 0 ||
    newPassword.value.length === 0 ||
    newPasswordConfirm.value.length === 0
  )
})

async function handleSubmit() {
  if (submitDisabled.value) {
    errorMessage.value = 'Bitte alle Passwortfelder ausfüllen.'
    return
  }

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

  isSubmitting.value = true
  errorMessage.value = ''

  try {
    await changePassword({
      oldPassword: oldPassword.value,
      newPassword: newPassword.value,
      newPasswordConfirm: newPasswordConfirm.value,
    })

    await router.replace({
      name: 'Login',
      query: { passwordChanged: '1' },
    })
  } catch (error) {
    if (error instanceof AuthRequestError) {
      errorMessage.value = error.message

      if (error.status === 401 || error.status === 403) {
        appBannersStore.pushError('Session abgelaufen. Bitte erneut anmelden.', 'Passwort ändern')
        await router.replace({ name: 'Login' })
        return
      }
    } else {
      errorMessage.value = 'Passwortänderung fehlgeschlagen. Bitte versuche es erneut.'
    }
  } finally {
    isSubmitting.value = false
  }
}
</script>

<template>
  <v-container fluid class="change-password-page hoard-page hoard-page--centered">
    <section class="change-password-shell hoard-panel hoard-shell-grid">
      <header class="change-password-head">
        <p class="hoard-kicker">Sicherheitsvorgabe</p>
        <h1>Passwort ändern</h1>
        <p>Hier kannst du ganz bequem dein Passwort aktualisieren.</p>
      </header>

      <v-alert
        v-if="errorMessage"
        type="error"
        variant="tonal"
        border="start"
      >
        {{ errorMessage }}
      </v-alert>

      <v-form class="change-password-form" @submit.prevent="handleSubmit">
        <v-text-field
          v-model="oldPassword"
          label="Altes Passwort"
          :type="showOldPassword ? 'text' : 'password'"
          variant="outlined"
          prepend-inner-icon="mdi-lock-outline"
          :append-inner-icon="showOldPassword ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
          autocomplete="current-password"
          required
          :disabled="isSubmitting"
          @click:append-inner="showOldPassword = !showOldPassword"
        />

        <v-divider class="change-password-divider" />
        <p class="change-password-section-label">Neues Passwort</p>

        <v-text-field
          v-model="newPassword"
          label="Neues Passwort"
          :type="showNewPassword ? 'text' : 'password'"
          variant="outlined"
          prepend-inner-icon="mdi-lock-reset"
          :append-inner-icon="showNewPassword ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
          autocomplete="new-password"
          required
          :disabled="isSubmitting"
          @click:append-inner="showNewPassword = !showNewPassword"
        />

        <v-text-field
          v-model="newPasswordConfirm"
          label="Neues Passwort bestätigen"
          :type="showNewPasswordConfirm ? 'text' : 'password'"
          variant="outlined"
          prepend-inner-icon="mdi-lock-check-outline"
          :append-inner-icon="showNewPasswordConfirm ? 'mdi-eye-off-outline' : 'mdi-eye-outline'"
          autocomplete="new-password"
          required
          :disabled="isSubmitting"
          @click:append-inner="showNewPasswordConfirm = !showNewPasswordConfirm"
        />

        <p class="change-password-hint">
          Nach erfolgreicher Änderung wirst du automatisch abgemeldet und meldest dich mit dem neuen Passwort wieder an.
        </p>

        <v-btn
          type="submit"
          color="primary"
          size="large"
          prepend-icon="mdi-content-save-outline"
          :loading="isSubmitting"
          :disabled="submitDisabled"
          block
        >
          Passwort speichern
        </v-btn>
      </v-form>
    </section>
  </v-container>
</template>

<style scoped>
.change-password-page {
  --hoard-shell-width: min(720px, 100%);
}

.change-password-shell {
  gap: var(--space-4);
}

.change-password-head h1,
.change-password-head p {
  margin: 0;
}

.change-password-head h1 {
  margin-top: var(--space-2);
  margin-bottom: var(--space-2);
}

.change-password-head p {
  color: var(--color-text-secondary);
}

.change-password-form {
  display: grid;
  gap: var(--space-3);
}

.change-password-divider {
  margin-top: var(--space-1);
  margin-bottom: 0;
  border-color: color-mix(in srgb, var(--color-border) 82%, var(--color-surface) 18%);
}

.change-password-section-label {
  margin: 0;
  color: var(--color-primary-700);
  font-size: var(--font-size-xs);
  font-weight: 600;
  letter-spacing: 0.04em;
  text-transform: uppercase;
}

.change-password-hint {
  margin: 0;
  color: var(--color-text-muted);
  font-size: var(--font-size-sm);
}

@media (prefers-reduced-motion: no-preference) {
  .change-password-shell {
    animation: hoard-soft-enter 260ms both;
  }
}

@media (width <= 600px) {
  .change-password-form {
    gap: var(--space-2);
  }
}
</style>
