<template>
  <v-card class="panel-pad" :class="standalone ? 'change-password-standalone' : 'span-12'">
    <h2 class="section-title mb-1">{{ forced ? 'Set a new password' : 'Change your password' }}</h2>
    <p v-if="forced" class="quiet text-body-2 mb-3">
      Your password must be changed before you can continue.
    </p>

    <v-alert v-if="rules.length" type="info" variant="tonal" density="compact" class="mb-3">
      <div class="text-caption font-weight-medium mb-1">Password requirements</div>
      <ul class="rule-list">
        <li v-for="rule in rules" :key="rule">{{ rule }}</li>
      </ul>
    </v-alert>

    <v-text-field
      v-model="current"
      type="password"
      label="Current password"
      autocomplete="current-password"
      prepend-inner-icon="mdi-lock-outline"
      density="compact"
    />
    <v-text-field
      v-model="next"
      type="password"
      label="New password"
      autocomplete="new-password"
      prepend-inner-icon="mdi-lock-plus-outline"
      density="compact"
    />
    <v-text-field
      v-model="confirm"
      type="password"
      label="Confirm new password"
      autocomplete="new-password"
      prepend-inner-icon="mdi-lock-check-outline"
      density="compact"
      :error-messages="confirm && confirm !== next ? 'Passwords do not match' : ''"
      @keyup.enter="submit"
    />

    <v-alert v-if="error" type="error" density="compact" class="mb-3">{{ error }}</v-alert>
    <v-alert v-if="success" type="success" density="compact" class="mb-3">Password updated.</v-alert>

    <div class="toolbar-row">
      <v-btn v-if="forced" variant="text" @click="$emit('cancel')">Sign out</v-btn>
      <v-spacer />
      <v-btn
        color="primary"
        prepend-icon="mdi-content-save"
        :loading="saving"
        :disabled="!canSubmit"
        @click="submit"
      >Update password</v-btn>
    </div>
  </v-card>
</template>

<script>
import { apiRequest } from '../services/api';

// Self-service password change. Reused in two places: the forced-change screen shown at login when the
// password is expired/admin-reset (`forced`), and the account menu's "Change password" dialog. It
// fetches the live policy rules to display, then PUTs to /api/profile/password.
export default {
  props: {
    token: { type: String, required: true },
    forced: { type: Boolean, default: false },
    standalone: { type: Boolean, default: false }
  },
  emits: ['changed', 'cancel'],
  data() {
    return {
      current: '',
      next: '',
      confirm: '',
      rules: [],
      saving: false,
      error: '',
      success: false
    };
  },
  computed: {
    canSubmit() {
      return this.current && this.next && this.next === this.confirm;
    }
  },
  mounted() {
    this.loadRules();
  },
  methods: {
    async loadRules() {
      try {
        const data = await (await apiRequest('/api/profile', this.token)).json();
        this.rules = data.passwordPolicy?.rules || [];
      } catch {
        this.rules = [];
      }
    },
    async submit() {
      if (!this.canSubmit) return;
      this.saving = true;
      this.error = '';
      this.success = false;
      try {
        await apiRequest('/api/profile/password', this.token, {
          method: 'PUT',
          body: JSON.stringify({ current_password: this.current, new_password: this.next })
        });
        this.success = true;
        this.current = '';
        this.next = '';
        this.confirm = '';
        this.$emit('changed');
      } catch (error) {
        this.error = error.message;
      } finally {
        this.saving = false;
      }
    }
  }
};
</script>

<style scoped>
.change-password-standalone {
  max-width: 480px;
  margin: 8vh auto;
}
.rule-list {
  padding-left: 18px;
  margin: 0;
  line-height: 1.6;
}
</style>
