/* eslint-disable no-plusplus */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { defineComponent, PropType, reactive, Ref, ref } from 'vue';
import { useNamespace } from '@ibiz-template/vue-util';
import './forget-password.scss';

interface UserData {
  loginName: string;
  verificationCode: string;
  newPwd: string;
  comfirmPwd: string;
}

export const ForgetPassword = defineComponent({
  name: 'ForgetPassword',
  props: {
    dismiss: {
      type: Function as PropType<(_result: IParams) => void>,
    },
  },
  setup(props) {
    const ns = useNamespace('forget-password');

    const formRef = ref<IData | null>(null);

    const userData = reactive<UserData>({
      loginName: '',
      verificationCode: '',
      newPwd: '',
      comfirmPwd: '',
    });

    const rules = {
      loginName: [
        {
          required: true,
          message: '请输入账号',
          trigger: 'blur',
        },
      ],
      verificationCode: [
        {
          required: true,
          message: '请输入验证码',
          trigger: 'blur',
        },
      ],
      newPwd: [
        {
          required: true,
          message: '请输入新密码',
          trigger: 'blur',
        },
        {
          validator: (rule: IData, value: string, callback: any) => {
            // 至少8位字符
            if (value && value.length < 8) {
              callback(new Error('密码长度不能少于8位'));
            }
            // 至少1个大写字母
            if (!/[A-Z]/.test(value)) {
              callback(new Error('至少1个大写字母'));
            }
            // 至少1个小写字母
            if (!/[a-z]/.test(value)) {
              callback(new Error('至少1个小写字母'));
            }
            // 至少1个数字
            if (!/[0-9]/.test(value)) {
              callback(new Error('至少1个数字'));
            }
            // 至少1个特殊符号
            if (!/[!@#$%^&*]/.test(value)) {
              callback(new Error('至少1个特殊符号'));
            }
            callback();
          },
          trigger: 'blur',
        },
      ],
      comfirmPwd: [
        {
          required: true,
          message: '请再次输入新密码',
          trigger: 'blur',
        },
        {
          validator: (rule: IData, value: string, callback: any) => {
            const { newPwd, comfirmPwd } = userData;
            if (newPwd !== comfirmPwd) {
              callback(new Error('两次输入密码不一致'));
            }
            callback();
          },
          trigger: 'blur',
        },
      ],
    };

    const loading = ref(false);

    const timer: Ref<ReturnType<typeof setInterval> | null> = ref(null);

    const countdown = ref(0);

    const standCountdown = () => {
      countdown.value = 60;
      timer.value = setInterval(() => {
        if (countdown.value > 1) {
          countdown.value--;
        } else if (timer.value) {
          countdown.value--;
          clearInterval(timer.value);
          timer.value = null;
        }
      }, 1000);
    };

    const sendVerificationCode = () => {
      const { loginName } = userData;
      if (!loginName) {
        ibiz.notification.warning({
          title: '请先输入账号',
        });
        return;
      }
      ibiz.net
        .post(`/v7/forgetPwd/sendVerificationCode/${loginName}`, {})
        .then((res: IData) => {
          standCountdown();
          if (res.ok) {
            ibiz.notification.success({
              title: '获取验证码成功',
            });
          } else {
            ibiz.notification.error({
              title: res.data?.message || '获取验证码失败',
            });
          }
        })
        .catch((err: IData) => {
          standCountdown();
          ibiz.notification.error({
            title: (err as IData).response?.data?.message || '获取验证码失败',
          });
        });
    };

    const onClick = () => {
      if (!ibiz.env.publicKey) {
        ibiz.message.error('请联系系统管理员配置公钥');
        return;
      }
      formRef.value!.validate(async (valid: boolean) => {
        if (valid) {
          try {
            loading.value = true;
            const { loginName } = userData;
            let { newPwd, comfirmPwd, verificationCode } = userData;
            if (ibiz.env.enableRSA) {
              newPwd = ibiz.util.text.rsa(newPwd);
              comfirmPwd = ibiz.util.text.rsa(comfirmPwd);
              verificationCode = ibiz.util.text.rsa(verificationCode);
            }
            const res = await ibiz.net.axios({
              url: '/v7/forgetPwd',
              method: 'post',
              baseURL: ibiz.env.baseUrl,
              headers: {
                'Content-Type': 'application/json;charset=UTF-8',
                Accept: 'application/json',
              },
              data: {
                loginName,
                verificationCode,
                newPwd,
                comfirmPwd,
              },
            });
            if (res.status === 200) {
              ibiz.notification.success({
                title: '重置密码成功',
              });
              props.dismiss?.({ ok: true, data: {} });
            }
            loading.value = false;
          } catch (error) {
            ibiz.notification.error({
              title: (error as IData).response?.data?.message || '重置密码失败',
            });
            loading.value = false;
          }
        }
      });
    };

    return () => (
      <div class={ns.b()}>
        <div class={ns.e('header')}>重置密码</div>
        <div class={ns.e('content')}>
          <i-form ref={formRef} props={{ model: userData, rules }}>
            <i-form-item prop='loginName'>
              <i-input
                type='text'
                value={userData.loginName}
                on-on-change={(evt: InputEvent) => {
                  const { value } = evt.target as HTMLInputElement;
                  userData.loginName = value;
                }}
                placeholder='请输入账号'
                size='large'
              >
                <i-icon type='md-person' slot='prefix'></i-icon>
              </i-input>
            </i-form-item>
            <i-form-item prop='verificationCode' class={ns.e('verification')}>
              <i-input
                type='number'
                value={userData.verificationCode}
                on-on-change={(evt: InputEvent) => {
                  const { value } = evt.target as HTMLInputElement;
                  userData.verificationCode = value;
                }}
                placeholder='请输入验证码'
              ></i-input>
              <i-button
                class={ns.is('disabled', !!timer.value)}
                disabled={!!timer.value}
                on-click={sendVerificationCode}
              >
                {countdown.value > 0
                  ? `${countdown.value}秒后重发`
                  : '获取验证码'}
              </i-button>
            </i-form-item>
            <i-form-item prop='newPwd'>
              <i-input
                type='password'
                value={userData.newPwd}
                on-on-change={(evt: InputEvent) => {
                  const { value } = evt.target as HTMLInputElement;
                  userData.newPwd = value;
                }}
                placeholder='请输入新密码'
                size='large'
                password
              >
                <i-icon type='ios-unlock' slot='prefix'></i-icon>
              </i-input>
            </i-form-item>
            <i-form-item prop='comfirmPwd'>
              <i-input
                type='password'
                value={userData.comfirmPwd}
                on-on-change={(evt: InputEvent) => {
                  const { value } = evt.target as HTMLInputElement;
                  userData.comfirmPwd = value;
                }}
                placeholder='请再次输入新密码'
                size='large'
                password
              >
                <i-icon type='ios-unlock' slot='prefix'></i-icon>
              </i-input>
            </i-form-item>
            <i-form-item>
              <i-button
                type='primary'
                shape='circle'
                loading={loading.value}
                long
                on-click={onClick}
              >
                确认修改
              </i-button>
            </i-form-item>
          </i-form>
        </div>
        <div class={ns.e('footer')}>
          <div>1. 密码长度至少有8位</div>
          <div>2. 至少有1个大写字母</div>
          <div>3. 至少有1个小写字母</div>
          <div>4. 至少有1个数字</div>
          <div>5. 至少有1个特殊符号（包括但不限于!@#$%^&*）</div>
          <div>
            6.
            不应以姓名、电话号码、出生日期以及账号名、系统名、公司名等作为口令或者口令的组成部分
          </div>
          <div>
            7.
            不可出现3位以上（含3位）的键盘排序密码，以及连续或重复的字母、数字、特殊字符
          </div>
          <div>8. 不可与近5次的密码相同</div>
        </div>
      </div>
    );
  },
});
