<template>
  <div class="space-y-4">
    <form @submit.prevent="changePassword" ref="passwordChangeForm">
      <sl-input
        label="Current password"
        type="password"
        autocomplete="current-password"
        placeholder="Current Password"
        required
        help-text="Enter your current password"
        :value="currentPassword"
        @input="checkCurrent"
        @sl-input="currentPassword = $event.target.value"
        ref="currentPasswordField"
        password-toggle
      ></sl-input>
      <sl-input
        label="New Password"
        type="password"
        required
        placeholder="New Password"
        autocomplete="new-password"
        help-text="Enter your new password"
        :value="newPassword"
        @sl-input="newPassword = $event.target.value"
        ref="newPasswordField"
        password-toggle
      ></sl-input>
      <sl-input
        label="New Password (repeat)"
        type="password"
        required
        placeholder="New Password"
        autocomplete="new-password"
        help-text="Confirm your new password by typing it again"
        :value="newPasswordConfirm"
        @sl-input="newPasswordConfirm = $event.target.value"
        @blur="checkPasswords"
        ref="newPasswordFieldConfirm"
        password-toggle
      ></sl-input>
      <sl-button class="mr-4" type="submit" variant="primary">Change Password</sl-button>
      <sl-button variant="default" @click="cancelChangePassword">Cancel</sl-button>
    </form>
  </div>
</template>

<script setup lang="ts">
import { ref } from 'vue'
import { useAlertsStore } from '@/store/useAlertsStore'
import { SshecretAdmin } from '@/client'
import type { UserPasswordChange } from '@/client'
import { assertSdkResponseOk } from '@/api/assertSdkResponseOk'
import { ApiError, ValidationError } from '@/api/errors'
import { setFieldValidation } from '@/api/validation'

const currentPassword = ref<string>('')
const newPassword = ref<string>('')
const newPasswordConfirm = ref<string>('')

const passwordChangeForm = ref<HTMLFormElement>()
const currentPasswordField = ref<SlInput>()
const newPasswordField = ref<SlInput>()
const newPasswordFieldConfirm = ref<Slinput>()

const alerts = useAlertsStore()

const emit = defineEmits<{ (e: 'changed'): void; (e: 'cancel'): void }>()

function checkCurrent() {
  setFieldValidation(currentPasswordField)
  currentPasswordField.value.reportValidity()
}

function checkPasswords() {
  if (newPassword.value !== newPasswordConfirm.value) {
    setFieldValidation(newPasswordFieldConfirm, 'Passwords do not match match')
  } else {
    setFieldValidation(newPasswordFieldConfirm)
  }
}

function resetForm() {
  passwordChangeForm.value?.reset()
}

function cancelChangePassword() {
  resetForm()
  emit('cancel')
}
async function changePassword() {
  const data: UserPasswordChange = {
    current_password: currentPassword.value,
    new_password: newPassword.value,
    new_password_confirm: newPasswordConfirm.value,
  }
  const response = await SshecretAdmin.changePasswordApiV1PasswordPost({ body: data })
  try {
    assertSdkResponseOk(response)
    emit('changed')
    resetForm()
  } catch (err) {
    if (err instanceof ValidationError) {
      // This should be caught in js, but we might as well
      setFieldValidation(newPasswordFieldConfirm, 'Passwords do not match match')
    } else if (err instanceof ApiError && err.message.includes('Invalid current password')) {
      setFieldValidation(currentPasswordField, 'Invalid current password')
    } else {
      alerts.showAlert(err.message, 'error', 'Error changing password')
    }
  }
}
</script>
