<template>
  <div class="change-password-panel">
    <a-alert
      v-if="success"
      message="密码修改成功，其他设备将自动登出。"
      type="success"
      show-icon
      closable
      class="change-password-panel__alert"
      @close="success = false"
    />
    <a-alert
      v-if="error"
      :message="error"
      type="error"
      show-icon
      closable
      class="change-password-panel__alert"
      @close="error = ''"
    />

    <a-form
      layout="vertical"
      :model="form"
      :rules="rules"
      ref="formRef"
      class="change-password-panel__form"
      @finish="handleSubmit"
    >
      <a-form-item label="当前密码" name="oldPassword" :rules="rules.oldPassword">
        <a-input-password
          v-model:value="form.oldPassword"
          size="large"
          placeholder="请输入当前密码"
          :disabled="loading"
        />
      </a-form-item>
      <a-form-item label="新密码" name="newPassword" :rules="rules.newPassword">
        <a-input-password
          v-model:value="form.newPassword"
          size="large"
          placeholder="至少 8 个字符"
          :disabled="loading"
        />
      </a-form-item>
      <a-form-item label="确认新密码" name="confirmPassword" :rules="rules.confirmPassword">
        <a-input-password
          v-model:value="form.confirmPassword"
          size="large"
          placeholder="再次输入新密码"
          :disabled="loading"
        />
      </a-form-item>
      <a-form-item>
        <a-button
          type="primary"
          html-type="submit"
          size="large"
          :loading="loading"
          class="change-password-panel__submit"
        >
          修改密码
        </a-button>
      </a-form-item>
    </a-form>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive } from 'vue'
import { message } from 'ant-design-vue'
import type { Rule } from 'ant-design-vue/es/form'
import { useAuthStore } from '@/stores/auth'

const authStore = useAuthStore()

const formRef = ref()
const loading = ref(false)
const error = ref('')
const success = ref(false)

const form = reactive({
  oldPassword: '',
  newPassword: '',
  confirmPassword: '',
})

/** Cross-field validator: confirmPassword must equal newPassword. */
const confirmPasswordValidator = async (_rule: Rule, value: string): Promise<void> => {
  if (value !== form.newPassword) {
    throw new Error('两次输入的密码不一致')
  }
}

const rules: Record<string, Rule[]> = {
  oldPassword: [
    { required: true, message: '请输入当前密码' },
  ],
  newPassword: [
    { required: true, message: '请输入新密码' },
    { min: 8, message: '新密码至少需要 8 个字符' },
  ],
  confirmPassword: [
    { required: true, message: '请再次输入新密码' },
    { validator: confirmPasswordValidator, trigger: 'blur' },
  ],
}

function resetForm(): void {
  form.oldPassword = ''
  form.newPassword = ''
  form.confirmPassword = ''
}

async function handleSubmit(): Promise<void> {
  error.value = ''
  success.value = false
  loading.value = true
  try {
    const result: { revoked_other_sessions?: number } = await authStore.changePassword(
      form.oldPassword,
      form.newPassword,
    )
    success.value = true
    resetForm()
    if (typeof result?.revoked_other_sessions === 'number' && result.revoked_other_sessions > 0) {
      message.success(`密码已修改，${result.revoked_other_sessions} 个其他设备的会话已撤销`)
    } else {
      message.success('密码已修改')
    }
  } catch (err) {
    const msg =
      err && typeof err === 'object'
        ? (err as { detail?: unknown; message?: unknown }).detail ??
          (err as { message?: unknown }).message
        : null
    error.value = typeof msg === 'string' && msg ? msg : '密码修改失败'
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
.change-password-panel {
  max-width: 480px;
}

.change-password-panel__alert {
  margin-bottom: 16px;
}

.change-password-panel__form {
  padding-top: 8px;
}

.change-password-panel__submit {
  font-weight: 600;
}
</style>
