<script setup lang="ts">
import type { EasyFlowFormSchema } from '#/adapter/form';

import { computed, ref } from 'vue';
import { useRouter } from 'vue-router';

import { ProfilePasswordSetting, z } from '@easyflow/common-ui';
import { preferences } from '@easyflow/preferences';
import { useUserStore } from '@easyflow/stores';

import { ElMessage } from 'element-plus';

import { getCredentialKeyApi } from '#/api';
import { api } from '#/api/request';
import { $t } from '#/locales';
import { useAuthStore } from '#/store';
import { encryptCredentialPayload } from '#/utils/credential-encryption';
import { isStrongPassword } from '#/utils/password-policy';
import { isPasswordResetRequired } from '#/utils/password-reset';

const profilePasswordSettingRef = ref();
const authStore = useAuthStore();
const router = useRouter();
const userStore = useUserStore();

const isForcedPasswordChange = computed(() => {
  return isPasswordResetRequired(userStore.userInfo);
});

const formSchema = computed((): EasyFlowFormSchema[] => {
  const schema: EasyFlowFormSchema[] = [
    {
      fieldName: 'newPassword',
      label: $t('sysAccount.newPwd'),
      component: 'EasyFlowInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: $t('sysAccount.newPwd') + $t('common.isRequired'),
      },
      renderComponentContent() {
        return {
          strengthText: () => $t('sysAccount.passwordStrongTip'),
        };
      },
      rules: z
        .string({
          required_error: $t('sysAccount.newPwd') + $t('common.isRequired'),
        })
        .min(1, { message: $t('sysAccount.newPwd') + $t('common.isRequired') })
        .refine((value) => isStrongPassword(value), {
          message: $t('sysAccount.passwordStrengthInvalid'),
        }),
    },
    {
      fieldName: 'confirmPassword',
      label: $t('sysAccount.confirmPwd'),
      component: 'EasyFlowInputPassword',
      componentProps: {
        passwordStrength: true,
        placeholder: $t('sysAccount.repeatPwd'),
      },
      dependencies: {
        rules(values) {
          const { newPassword } = values;
          return z
            .string({ required_error: $t('sysAccount.repeatPwd') })
            .min(1, { message: $t('sysAccount.repeatPwd') })
            .refine((value) => value === newPassword, {
              message: $t('sysAccount.notSamePwd'),
            });
        },
        triggerFields: ['newPassword'],
      },
    },
  ];

  if (!isForcedPasswordChange.value) {
    schema.unshift({
      fieldName: 'password',
      label: $t('sysAccount.oldPwd'),
      component: 'EasyFlowInputPassword',
      componentProps: {
        placeholder: $t('sysAccount.oldPwd') + $t('common.isRequired'),
      },
      rules: z
        .string({
          required_error: $t('sysAccount.oldPwd') + $t('common.isRequired'),
        })
        .min(1, { message: $t('sysAccount.oldPwd') + $t('common.isRequired') }),
    });
  }

  return schema;
});

const updateLoading = ref(false);
async function handleSubmit(values: any) {
  const wasForcedPasswordChange = isForcedPasswordChange.value;
  updateLoading.value = true;
  try {
    const encryptedPayload = await encryptCredentialPayload(
      getCredentialKeyApi,
      values,
    );
    const res = await api.post(
      '/api/v1/sysAccount/updatePassword',
      encryptedPayload,
    );
    if (res.errorCode === 0) {
      ElMessage.success($t('message.success'));
      const userInfo = await authStore.fetchUserInfo();
      if (wasForcedPasswordChange) {
        await router.replace(
          userInfo?.homePath || preferences.app.defaultHomePath || '/',
        );
      }
    }
  } finally {
    updateLoading.value = false;
  }
}
</script>
<template>
  <ProfilePasswordSetting
    :button-loading="updateLoading"
    :button-text="$t('button.update')"
    ref="profilePasswordSettingRef"
    class="w-1/3"
    :form-schema="formSchema"
    @submit="handleSubmit"
  />
</template>
