<template>
	<el-form class="forgetPwd-content-form" ref="forgetRef" :model="state.ruleForm" :rules="rules" label-position="top" label-width="100px">
		<el-form-item prop="currentPassword" class="login-animation1" label="旧密码">
			<el-input
				class="inputDeep"
				clearable
				type="password"
				show-password
				placeholder="请输旧就密码"
				v-model="state.ruleForm.currentPassword"
				autocomplete="off"
			>
				<template #prefix>
					<el-icon class="el-input__icon">
						<ele-Unlock />
					</el-icon>
				</template>
			</el-input>
		</el-form-item>
		<el-form-item prop="newPassword" label="新密码" class="login-animation2">
			<el-input
				class="inputDeep"
				clearable
				type="password"
				show-password
				placeholder="请输入新密码"
				v-model="state.ruleForm.newPassword"
				autocomplete="off"
			>
				<template #prefix>
					<el-icon class="el-input__icon">
						<ele-Unlock />
					</el-icon>
				</template>
			</el-input>
			<div class="intensity">
				<span class="psdText">密码强度：{{ modes === 1 ? '弱' : modes === 2 ? '中' : modes === 3 ? '强' : '' }}</span>
				<span class="line lowLine" :class="modes === 1 ? 'low' : ''"></span>
				<span class="line middleLine" :class="modes === 2 ? 'middle' : ''"></span>
				<span class="line highLine" :class="modes === 3 ? 'high' : ''"></span>
			</div>
		</el-form-item>
		<el-form-item prop="confirmPassword" label="确认密码" class="login-animation3">
			<el-input
				class="inputDeep"
				clearable
				type="password"
				show-password
				placeholder="请再次输入密码"
				v-model="state.ruleForm.confirmPassword"
				autocomplete="off"
			>
				<template #prefix>
					<el-icon class="el-input__icon">
						<ele-Unlock />
					</el-icon>
				</template>
			</el-input>
		</el-form-item>
		<el-button
			type="primary"
			class="forgetPwd-content-submit login-animation3"
			round
			@click="onChangeConfirm(forgetPwdRef)"
			v-waves="'light'"
			:loading="state.loading"
			>确认修改</el-button
		>
		<div class="font12 mt10 forgetPwd-msg login-animation4">提示：密码不得少于8位数，且必须包含数字、字母大小写和特殊字符</div>
		<div class="login-msg login-animation4">
			<span></span>
			<el-button link type="primary" class="font16" @click="goLogin">返回登录</el-button>
		</div>
	</el-form>
</template>

<script setup lang="ts" name="forgetPwdComponent">
import { reactive, ref } from 'vue';
import { useRouter } from 'vue-router';
import { ElNotification } from 'element-plus';
import type { FormInstance } from 'element-plus';
import {Cookie, Session} from '/@/utils/storage';
import { changePwd } from '/@/api/login/user';
// 修改密码参数类型
interface ChangePwdState {
	currentPassword: string;
	newPassword: string;
	confirmPassword: string;
}
// 定义变量
const router = useRouter();
const state = reactive({
	ruleForm: <ChangePwdState>{
		currentPassword: '',  // 旧密码
		newPassword: '',  // 新密码
		confirmPassword: '',  // 确认密码
	},
	loading: false, // 确认修改按钮loading
});
const forgetPwdRef = ref<FormInstance>(); // 表单ref
// 确认重置
const onChangeConfirm = async (formEl: FormInstance | undefined) => {
	if (!formEl) return;
	await formEl.validate((valid: boolean) => {
		if (!valid) return;
		state.loading = true;
		changePwd(state.ruleForm)
			.then(async () => {
				// 清理清理缓存
				Session.clear();
        Cookie.clear();
				await router.push('/');
				ElNotification({
					title: '成功',
					type: 'success',
					message: '密码重置成功，请重新登录',
				});
			})
			.catch(() => {
				state.loading = false;
			});
	});
};
//  检查密码强度
let modes = ref<number>(0);
const checkPassword = (rule: any, value: string, callback: any) => {
	if (!value) {
		modes.value = 0;
		return callback('新密码不能为空');
	}
	if (value.length < 8) {
		modes.value = 0;
		return callback('新密码不少于8位');
	}
	/*
    最短8位， {6,}
    可以包含小写大母 [a-z] 和大写字母 [A-Z]
    可以包含数字 [0-9]
    可以包含下划线 [ _ ] 和减号 [ - ]
  */
	if (/^[\w_-]{6,}$/.test(state.ruleForm.newPassword)) {
		modes.value = 1;
	}
	/*
    最短8位， {8,}
    必须包含1个数字
    必须包含1个小写字母
    必须包含1个大写字母
    必须包含1个特殊字符
  */
	if (/^\S*(?=\S{8,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*.?])\S*$/.test(state.ruleForm.newPassword)) modes.value = 2; //中等
	/*
    最短8位， {8,}
    必须包含1个数字
    必须包含1个小写字母
    必须包含1个大写字母
    必须包含2个特殊字符
  */
	if (/^\S*(?=\S{8,})(?=\S*\d)(?=\S*[A-Z])(?=\S*[a-z])(?=\S*[!@#$%^&*.?]{2,})\S*$/.test(state.ruleForm.newPassword)) modes.value = 3; //强密码
	if (modes.value == 0 || modes.value == 1) {
		return callback('提示：密码不得少于8位数，且必须包含字母大小写和特殊字符'); //弱密码
	}
	if (value === state.ruleForm.currentPassword) {
		return callback('新密码不能与旧密码一致，请重新输入');
	}
	return callback();
};
// 检查输入密码是否一致
const checkConfirmPassword = (rule: any, value: any, callback: any) => {
	if (!value) {
		return callback('请再次输入密码');
	}
	if (value != state.ruleForm.newPassword) {
		return callback('两次密码输入不一致，请重新输入');
	}
	return callback();
};
const rules = reactive({
	currentPassword: [{ required: true, message: '请输入旧密码', trigger: ['change', 'blur'] }],
	newPassword: [{ required: true, validator: checkPassword, trigger: ['change', 'blur'] }],
	confirmPassword: [{ required: true, validator: checkConfirmPassword, trigger: 'blur' }],
});
// 返回登录
const goLogin = () => {
	router.push({
		path: '/login',
	});
};
</script>

<style scoped lang="scss">
.forgetPwd-content-form {
	@for $i from 1 through 4 {
		.login-animation#{$i} {
			opacity: 0;
			animation-name: error-num;
			animation-duration: 0.5s;
			animation-fill-mode: forwards;
			animation-delay: calc($i/10) + s;
		}
	}
	.forgetPwd-content-submit {
		width: 100%;
		font-weight: 300;
		background: linear-gradient(-90deg, #3c7ee0 0%, #3c50e0 100%);
		border: none;
		border-radius: 8px;
		height: 40px;
		margin-top: 20px;
	}

	.forgetPwd-msg {
		color: var(--el-text-color-placeholder);
	}
	.login-msg {
		margin-top: 10px;
		display: flex;
		justify-content: space-between;
		align-items: center;
		color: var(--el-color-primary);
		b {
			color: #999;
			padding-left: 4px;
		}
	}
	.intensity {
		.psdText {
			font-size: 14px;
			margin-right: 10px;
			color: #5a5a5a;
		}

		.line {
			display: inline-block;
			width: 48px;
			height: 10px;
			background: #d8d8d8;
			margin-right: 2px;

			&.lowLine {
				border-radius: 6px 0 0 6px;
			}

			&.low {
				background: #bfcdff;
			}

			&.middle {
				background: #93a6fa;
			}

			&.high {
				background: #3c50e0;
			}

			&.highLine {
				border-radius: 0 6px 6px 0;
			}
		}

		.level {
			margin: 0 16px 0 8px;
		}
	}
}
</style>
