<script lang="ts" setup>
import { getSecurityInfo } from '@/services/security-enhance.service';
import { traduction } from '@/utils/language';
import { reactive, ref, computed, watch, nextTick, onMounted, onBeforeUnmount } from 'vue';
import useStore from '@/stores';
import {
  IAuthorityEnum,
  IInputOption,
  ISelectOption,
  ISwitchOption,
} from '../models/security.datatype';
import {
  factoryEnhanceData,
  formatSecInfo,
  initLoginFailOpt,
  inputBlurFn,
  isEqual,
  getShowedComps,
  saveParams,
} from '../utils/enhance.utils';
import { rangeVerification } from '@/validators/validation-functions';
import { IRule } from '@/model/Service/vnc-interface';
import { getStoreData, loading, setStoreData } from '@/utils/composition';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import PullDownTriangle from '@/components/PullDownTriangle/PullDownTriangle.vue';
import { LDAP_PAGE_ENABLED } from '@/model/configure';

const store = useStore();
const dialogRef = ref();
const MaxAccountLockoutThreshold = ref(0);
const MaxAccountLockoutDuration = ref(0);
const MaxPreviousPasswordsDisallowedCount = ref(0);
// 获取locked锁定值
let systemLockDownEnabled = computed(() => {
  return store.state.glob.systemLocked;
});

watch(systemLockDownEnabled, () => {
  init();
});
const hasSecurityConfig = checkPrivil(UserPrivil.securityConfig);
const hasUserConfig = checkPrivil(UserPrivil.userConfig);

let minimumPasswordLength = '';
let inited = false;
const buttonDisable = ref(true);
let authorityData: any = null;
const tlsSupported = ref(false);
const tlsVersionOptions = ref([] as any[]);
const dialogConfig = reactive({
  title: '',
  content: '',
  id: '',
});

const popoverVisible = reactive({
  passwordPeriod: false,
  passwordMinLen: false,
  leastPeriod: false,
  inactivity: false,
  loginFailLockInput: false,
  loginFailInput: false,
  expireWarning: false,
  banPassword: false,
});

// 系统锁定模式
const openLock = reactive({
  show: false,
  label: traduction('SECURITY_HOME_OPENLOCK'),
  value: false,
  initValue: false,
  id: 'openLock',
  disabled: getStoreData('loct', 'ur').indexOf('Administrator') < 0,
  associated: IAuthorityEnum.systemLockDownEnabled,
  valida: 'right',
} as ISwitchOption);
// 业务侧管理员操作使能
const serviceEnable = reactive({
  label: traduction('SECURITY_SERVICE_ENABLE'),
  value: false,
  initValue: false,
  associated: IAuthorityEnum.OSAdministratorPrivilegeEnabled,
  id: 'serviceEnable',
  disabled: !hasUserConfig,
} as ISwitchOption);
// 密码检查
const passwordCheck = reactive({
  label: traduction('SECURITY_PASSWORD_COMPLEXITY_CHECK'),
  value: false,
  initValue: false,
  id: 'passwordCheck',
  associated: IAuthorityEnum.passwordComplexityCheckEnabled,
  tip: hasSecurityConfig ? traduction('SECUTITY_CFG_USER_MNG_MEG') : '',
  disabled: !hasSecurityConfig,
} as ISwitchOption);
// SSH密码认证
const loginSecurity = reactive({
  label: traduction('SECURITY_SSH_AUTHENTICATION'),
  value: false,
  initValue: false,
  id: 'loginSecurity',
  associated: IAuthorityEnum.SSHPasswordAuthenticationEnabled,
  tip: hasUserConfig ? traduction('SECUTITY_CFG_PWD_CHECK') : '',
  disabled: !hasUserConfig,
} as ISwitchOption);
// 防DNS重绑定
const dnsBinding = reactive({
  label: traduction('SECURITY_ANTI_REBIND'),
  value: false,
  initValue: false,
  id: 'dnsBinding',
  associated: IAuthorityEnum.antiDNSRebindEnabled,
  disabled: !hasSecurityConfig,
} as ISwitchOption);
// TLS版本
const productLabel = getStoreData('loct', 'sn');
const tlsVersion = reactive({
  label: traduction('SECURITY_TLS_VERSION'),
  id: 'tlsVersion',
  tip: '',
  value: null as any,
  initValue: '',
  options: [
    {
      value: 'TLS1.2',
      label: traduction('TLS_1_POINTER_2_LABEL'),
    },
    {
      value: 'TLS1.3',
      label: traduction('TLS_1_POINTER_3_LABEL'),
    },
  ],
  associated: IAuthorityEnum.tlsVersion,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// 密码有效期
const passwordPeriod = reactive({
  id: 'passwordPeriod',
  label: traduction('SECURITY_VNC_PASSWORD_DATE'),
  value: '',
  tip: traduction('SECUTITY_CFG_PWD_DAY'),
  initValue: '',
  // 密码有效期与密码最短使用期的校验互相关联，当有一处值更改时，另一处的校验需要重新设置
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.passwordValidityDays,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 密码最小长度配置
const passwordMinLen = reactive({
  id: 'passwordMinLen',
  label: traduction('PASSWPRD_MIN_LEN'),
  tip: hasSecurityConfig ? traduction('VALIDATOR_PASSWORD_MIN_LEN') : '',
  initValue: '',
  recommendValue: '8',
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.minimumPasswordLength,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 密码最短使用期
const leastPeriod = reactive({
  id: 'leastPeriod',
  label: traduction('SECURITY_MINIMUM_PERIOD'),
  value: '',
  tip: hasSecurityConfig ? traduction('SECUTITY_CFG_MIN_PWD_DAY') : '',
  initValue: '',
  associated: IAuthorityEnum.minimumPasswordAgeDays,
  // 密码有效期与密码最短使用期的校验互相关联，当有一处值更改时，另一处的校验需要重新设置
  change: () => {
    detectChange();
  },
  disabled: !hasSecurityConfig,
} as IInputOption);
// 不活动期限
const inactivity = reactive({
  id: 'inactivity',
  label: traduction('SECURITY_INACTIVITYPERIOD'),
  value: '',
  tip: hasSecurityConfig ? traduction('SECURITY_PERIOD_NOLIMITED') : '',
  initValue: '',
  associated: IAuthorityEnum.accountInactiveTimelimit,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 紧急登录用户
const emergencyUser = reactive({
  label: traduction('SECURITY_EMERGENCY_USER'),
  id: 'emergencyUser',
  options: [],
  value: null as any,
  initValue: '',
  tip: hasSecurityConfig
    ? traduction('SECURITY_EMERGENCY_USER_TIP', { softwareName: productLabel })
    : '',
  show: hasUserConfig,
  associated: IAuthorityEnum.emergencyLoginUser,
  change: () => {
    detectChange();
  },
  disabled: !hasSecurityConfig,
} as ISelectOption);

// 禁用历史密码
const banPassword = reactive({
  label: traduction('SECURITY_DISABLE_HISTORY_PASSWORD'),
  id: 'banPassword',
  tip: hasSecurityConfig ? traduction('SECURITY_HISTORY_DISABLED_TIP', { m: MaxPreviousPasswordsDisallowedCount.value }) : '',
  value: '',
  initValue: '',
  associated: IAuthorityEnum.previousPasswordsDisallowedCount,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 登录失败锁定
const loginFailLockInput = reactive({
  label: `${traduction('SECURITY_LOGIN_FAILURE_LOCK')}(${traduction('SECURITY_NUMBER_FAILURES')})`,
  id: 'loginFailLockInput',
  show: true,
  value: '',
  initValue: '',
  locked: true,
  initLocked: true,
  tip: traduction('VALID_VALUE_RANGE_TIP', [1, MaxAccountLockoutThreshold.value]),
  associated: IAuthorityEnum.accountLockoutThreshold,
  disabled: !hasSecurityConfig,
} as IInputOption);

const loginFailInput = reactive({
  id: 'loginFailInput',
  label: traduction('SECURITY_LOCKING_TIME'),
  show: true,
  initValue: '',
  value: '',
  tip: traduction('VALID_VALUE_RANGE_TIP', [1, MaxAccountLockoutDuration.value]),
  associated: IAuthorityEnum.accountLockoutDuration,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 证书过期提前告警时间
const expireWarning = reactive({
  label: traduction('SECURITY_EXPIRE_WARNING'),
  id: 'expireWarning',
  value: '',
  tip: traduction('SECURITY_EXPIRE_WARNING_TIP'),
  recommendValue: '90',
  initValue: '90',
  associated: IAuthorityEnum.certificateOverdueWarningTime,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 吊销列表过期检测模式
const crlOverdueWarningMode = reactive({
  label: traduction('SECURITY_CRL_EXPIRE_DETECTION_MODE'),
  id: 'crlOverdueWarningMode',
  value: '',
  initValue: 'Customized',
  options: [
    {
      value: 'Auto',
      label: traduction('SECURITY_AUTO'),
    },
    {
      value: 'Customized',
      label: traduction('SECURITY_SPECIFY'),
    },
  ],
  changeFn: () => {
    crlOverdueWarningTime.value = crlOverdueWarningTime.initValue;
    detectChange();
  },
  associated: IAuthorityEnum.crlOverdueWarningMode,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// 吊销列表过期提前告警时间
const crlOverdueWarningTime = reactive({
  id: 'crlOverdueWarningTime',
  label: traduction('SECURITY_CRL_EXPIRE_EXPIRE_WARNING'),
  tip: traduction('VALIDATOR_revocation_RANGE'),
  value: '',
  initValue: '90',
  recommendValue: '90',
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.crlOverdueWarningTime,
  disabled: !hasSecurityConfig,
} as IInputOption);

// 本地用户密码校验规则
const localAccountPasswordRulePolicy = reactive({
  label: traduction('SECURITY_LOCAL_PASSWORD_RULE'),
  id: 'localAccountPasswordRulePolicy',
  value: '',
  initValue: 'Default',
  options: [
    {
      value: 'Default',
      label: traduction('SECURITY_RULE_MODE1'),
    },
    {
      value: 'Customized',
      label: traduction('SECURITY_RULE_MODE2'),
    },
    {
      value: 'Hybrid',
      label: traduction('SECURITY_RULE_MODE3'),
    },
  ],
  associated: IAuthorityEnum.localAccountPasswordRulePolicy,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// 本地用户密码校验正则表达式
const localAccountPasswordPattern = reactive({
  id: 'localAccountPasswordPattern',
  label: traduction('SECURITY_LOCAL_PASSWORD_REG'),
  tip: traduction('SECURITY_PATTERN_RULE'),
  value: '',
  initValue: '',
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.localAccountPasswordPattern,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// SNMP团体名校验规则
const snmpCommunityPasswordRulePolicy = reactive({
  label: traduction('SECURITY_SNMP_PASSWORD_RULE'),
  id: 'snmpCommunityPasswordRulePolicy',
  value: '',
  initValue: 'Default',
  options: [
    {
      value: 'Default',
      label: traduction('SECURITY_RULE_MODE1'),
    },
    {
      value: 'Customized',
      label: traduction('SECURITY_RULE_MODE2'),
    },
    {
      value: 'Hybrid',
      label: traduction('SECURITY_RULE_MODE3'),
    },
  ],
  associated: IAuthorityEnum.snmpCommunityPasswordRulePolicy,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// SNMP团体名校验正则表达式
const snmpCommunityPasswordPattern = reactive({
  id: 'snmpCommunityPasswordPattern',
  label: traduction('SECURITY_SNMP_PASSWORD_REG'),
  tip: traduction('SECURITY_PATTERN_RULE'),
  value: '',
  initValue: '',
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.snmpCommunityPasswordPattern,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// vnc密码校验规则
const vncPasswordRulePolicy = reactive({
  label: traduction('SECURITY_VNC_PASSWORD_RULE'),
  id: 'vncPasswordRulePolicy',
  value: '',
  initValue: 'Default',
  options: [
    {
      value: 'Default',
      label: traduction('SECURITY_RULE_MODE1'),
    },
    {
      value: 'Customized',
      label: traduction('SECURITY_RULE_MODE2'),
    },
    {
      value: 'Hybrid',
      label: traduction('SECURITY_RULE_MODE3'),
    },
  ],
  associated: IAuthorityEnum.vncPasswordRulePolicy,
  disabled: !hasSecurityConfig,
} as ISelectOption);

// vnc密码校验正则表达式
const vncPasswordPattern = reactive({
  id: 'vncPasswordPattern',
  label: traduction('SECURITY_VNC_PASSWORD_REG'),
  tip: traduction('SECURITY_PATTERN_RULE'),
  value: '',
  initValue: '',
  change: () => {
    detectChange();
  },
  associated: IAuthorityEnum.vncPasswordPattern,
  disabled: !hasSecurityConfig,
} as ISelectOption);


const formComponents = [
  openLock,
  serviceEnable,
  passwordCheck,
  loginSecurity,
  tlsVersion,
  passwordMinLen,
  passwordPeriod,
  leastPeriod,
  inactivity,
  emergencyUser,
  banPassword,
  loginFailLockInput,
  loginFailInput,
  expireWarning,
  dnsBinding,
  crlOverdueWarningMode,
  crlOverdueWarningTime,
  localAccountPasswordRulePolicy,
  localAccountPasswordPattern,
  snmpCommunityPasswordRulePolicy,
  snmpCommunityPasswordPattern,
  vncPasswordRulePolicy,
  vncPasswordPattern,
];
const formComponentsObj = reactive({
  openLock: openLock,
  serviceEnable: serviceEnable,
  passwordCheck: passwordCheck,
  loginSecurity: loginSecurity,
  tlsVersion: tlsVersion,
  passwordMinLen: passwordMinLen,
  passwordPeriod: passwordPeriod,
  leastPeriod: leastPeriod,
  inactivity: inactivity,
  emergencyUser: emergencyUser,
  banPassword: banPassword,
  loginFailLockInput: loginFailLockInput,
  loginFailInput: loginFailInput,
  expireWarning: expireWarning,
  dnsBinding: dnsBinding,
  crlOverdueWarningMode: crlOverdueWarningMode,
  crlOverdueWarningTime: crlOverdueWarningTime,
  localAccountPasswordRulePolicy,
  localAccountPasswordPattern,
  snmpCommunityPasswordRulePolicy,
  snmpCommunityPasswordPattern,
  vncPasswordRulePolicy,
  vncPasswordPattern,
});

// 表单校验结果
let validateResult = {};
const ruleFormRef = ref();

// 输入框 发生input 事件
function input(inputItem: IInputOption, value: number, valid: string) {
  inputItem.value = value;
  if (inputItem.id === 'passwordPeriod') {
    ruleFormRef.value.validateField(['leastPeriod.value']);
  } else if (inputItem.id === 'leastPeriod') {
    ruleFormRef.value.validateField(['passwordPeriod.value']);
  }
  validateResult[inputItem.id + '.value'] = formRules[valid].validator(
    formRules[valid],
    value,
    () => {},
  );

  nextTick(() => {
    detectChange();
  });
}

function focus(key: string) {
  popoverVisible[key] = true;
}

function blur(key: string) {
  popoverVisible[key] = false;
  inputBlurFn(formComponentsObj[key]);
}

function clear(key: string) {
  // 如果没有focus，那么这个地方需要手动调用一次校验
  if (!popoverVisible[key]) {
    ruleFormRef.value.validateField(key + '.value');
  }
}

// 表单校验发生时 - 控制保存按钮状态 state:校验结果
function validate(key: string, state: boolean) {
  validateResult[key] = state;
  nextTick(() => {
    detectChange();
  });
}

const detectChange = (data?: string): any => {
  if (!inited) {
    return;
  }
  if (data === 'passwordCheck') {
    if (!passwordCheck.value) {
      passwordMinLen.disabled = true;
      passwordMinLen.value = minimumPasswordLength;
    } else {
      passwordMinLen.disabled = false;
    }
  }
  if (data === 'localAccountPasswordRulePolicy') {
    if (localAccountPasswordRulePolicy.value === 'Default') {
      localAccountPasswordPattern.disabled = true;
      localAccountPasswordPattern.value = localAccountPasswordPattern.initValue;
      ruleFormRef.value.validateField('localAccountPasswordPattern.value');
    } else {
      localAccountPasswordPattern.disabled = false;
    }
  }
  if (data === 'snmpCommunityPasswordRulePolicy') {
    if (snmpCommunityPasswordRulePolicy.value === 'Default') {
      snmpCommunityPasswordPattern.disabled = true;
      snmpCommunityPasswordPattern.value = snmpCommunityPasswordPattern.initValue;
      ruleFormRef.value.validateField('snmpCommunityPasswordPattern.value');
    } else {
      snmpCommunityPasswordPattern.disabled = false;
    }
  }
  if (data === 'vncPasswordRulePolicy') {
    if (vncPasswordRulePolicy.value === 'Default') {
      vncPasswordPattern.disabled = true;
      vncPasswordPattern.value = vncPasswordPattern.initValue;
      ruleFormRef.value.validateField('vncPasswordPattern.value');
    } else {
      vncPasswordPattern.disabled = false;
    }
  }

  for (let key in validateResult) {
    // 任意一个校验失败
    // 输入框校验失败，勾选永不锁定时，将失败锁定输入框重置为原始值
    if (key === 'loginFailLockInput.value' && loginFailLockInput.locked) {
      buttonDisable.value = false;
      loginFailLockInput.value = '5';
    } else {
      if (!validateResult[key]) {
        buttonDisable.value = true;
        return;
      }
    }
  }

  const showedFormComps = getShowedComps(formComponents);
  let isChange = false;
  showedFormComps.forEach(form => {
    if (form.value === null && form.initValue === null) {
      return;
    }
    if (!isEqual(form.value, form.initValue)) {
      isChange = true;
      return;
    }
    if (form.associated === IAuthorityEnum.accountLockoutThreshold) {
      if (!isEqual(form.locked, form.initLocked)) {
        isChange = true;
        return;
      }
    }
  });
  buttonDisable.value = !isChange;
};

function showMessage() {
  const tipsInfo = [];
  // 只有当密码复杂度由开启状态变为关闭状态时，才提示“禁用密码复杂度检查会降低系统安全性。”
  const pwdItem = formComponents.filter(item => item.id === 'passwordCheck')[0];
  if (pwdItem && !pwdItem.value && pwdItem.initValue) {
    tipsInfo.push(traduction('SECURITY_CLOSE_PWD_CHECK'));
  }
  if (parseInt(passwordPeriod.value, 10) !== 0) {
    tipsInfo.push(traduction('SECURITY_URGENT_USER_TIP'));
  }
  if (parseInt(inactivity.value, 10) !== 0) {
    tipsInfo.push(traduction('SECURITY_URGENT_USER_TIP2'));
  }
  if (tlsVersion.options[0].label) {
    tipsInfo.push(traduction('COMMON_ASK_OK'));
  }
  let content = '';
  if (tipsInfo.length > 0) {
    tipsInfo.forEach((value, index) => {
      const count = tipsInfo.length > 1 ? index + 1 + ') ' : '';
      content += count + value + '\n';
    });
  } else {
    content = traduction('COMMON_ASK_OK');
  }

  dialogConfig.id = 'oneKeyModel';
  dialogConfig.title = traduction('COMMON_CONFIRM');
  dialogConfig.content = content;
  dialogRef.value.show();
}

function dialogClose(reason: boolean) {
  dialogRef.value.hide();
  if (reason) {
    save();
  }
}

function save() {
  let hasTls = false;
  loading(true);
  let changedForm = getShowedComps(formComponents).filter(form => {
    if (!isEqual(form.value, form.initValue)) {
      if (form.associated === IAuthorityEnum.tlsVersion) {
        hasTls = true;
        return false;
      }
      return true;
    }
    if (form.associated === IAuthorityEnum.accountLockoutThreshold) {
      if (!isEqual(form.locked, form.initLocked)) {
        return true;
      }
    }
    return false;
  });
  if (hasTls) {
    changedForm = changedForm.concat(tlsVersion);
  }
  saveParams(changedForm, tlsSupported.value).then(
    (res: any) => {
      if (res.data.error) {
        const errorId = res.data.error[0].code;
        const errorMsg = traduction(errorId + '.errorMessage') || traduction('COMMON_FAILED');
        store.state.event.setEventState({
          type: 'alertMessage',
          value: { type: 'error', message: errorMsg },
        });
      } else {
        // 更改store中的值state.glob.systemLocked
        let sysStateData = res.data.SystemLockDownEnabled;
        store.state.glob.setGlobState({ type: 'systemLocked', value: sysStateData });
        setStoreData('glob', 'localAccountPasswordRulePolicy', res.data.LocalAccountPasswordRulePolicy || 'Default');
        setStoreData('glob', 'localAccountPasswordPattern', new RegExp(res?.data?.LocalAccountPasswordPattern || ''));
        setStoreData('glob', 'snmpCommunityPasswordRulePolicy', res.data.SnmpCommunityPasswordRulePolicy || 'Default');
        setStoreData('glob', 'snmpCommunityPasswordPattern', new RegExp(res?.data?.SnmpCommunityPasswordPattern || ''));
        setStoreData('glob', 'vncPasswordRulePolicy', res.data.VNCPasswordRulePolicy || 'Default');
        setStoreData('glob', 'vncPasswordPattern', new RegExp(res?.data?.VNCPasswordPattern || ''));
        store.state.event.setEventState({
          type: 'alertMessage',
          value: { type: 'success', message: traduction('COMMON_SUCCESS') },
        });
      }
      initValue(factoryEnhanceData(res.data));
      loading(false);
    },
    (error: any) => {
      store.state.event.setEventState({
        type: 'alertMessage',
        value: { type: 'error', message: traduction('COMMON_FAILED') },
      });
      init();
      loading(false);
    },
  );
  buttonDisable.value = true;
}

const formRules = reactive({
  banPasswordValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 0,
    max: MaxPreviousPasswordsDisallowedCount.value,
    message: hasSecurityConfig ? traduction('SECURITY_HISTORY_DISABLED_TIP', { m: MaxPreviousPasswordsDisallowedCount.value }) : '',
    validator: rangeVerification,
    trigger: 'blur',
  },
  loginFailLockValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 1,
    max: MaxAccountLockoutThreshold.value,
    message: traduction('VALID_VALUE_RANGE_TIP', [1, MaxAccountLockoutThreshold.value]),
    validator: rangeVerification,
    trigger: 'blur',
  },
  loginFailValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 1,
    max: MaxAccountLockoutDuration.value,
    message: traduction('VALID_VALUE_RANGE_TIP', [1, MaxAccountLockoutDuration.value]),
    validator: rangeVerification,
    trigger: 'blur',
  },
  inactivityValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 30,
    max: 365,
    validator: (rule: IRule, valueTemp: any, callback: any) => {
      let value = valueTemp;
      if (value === '') {
        callback(new Error(traduction('VALID_VALUE_RANGE_TIP', [30, 365])));
        return false;
      }
      // 输入的要是数字字符串 或者 数字
      const reg = /(^[\-0-9][0-9]*(.[0-9]+)?)$/;
      if (!reg.test(value)) {
        callback(new Error(traduction('VALID_NUMBER_INFO')));
        return false;
      }
      if (typeof value === 'string') {
        value = Number(value);
      }
      if (value === 0 || rangeVerification(rule, value, () => {})) {
        callback();
        return true;
      } else {
        callback(new Error(traduction('VALID_VALUE_RANGE_TIP', [30, 365])));
        return false;
      }
    },
    trigger: 'blur',
  },
  expiresValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 7,
    max: 180,
    message: traduction('VALID_VALUE_RANGE_TIP', [7, 180]),
    validator: rangeVerification,
    trigger: 'blur',
  },
  // 密码有效期与密码最短使用期的校验互相关联，当有一处值更改时，另一处的校验需要重新设置
  leastPeriodValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 0,
    max: 365,
    validator: (rule: IRule, value: string | number, callback: any) => {
      if (!rangeVerification(rule, value, () => {})) {
        callback(new Error(traduction('VALID_VALUE_RANGE_TIP', [0, 365])));
        return false;
      }
      let currentValue = Number(value);
      let period = isNaN(passwordPeriod.value) ? 0 : Number(passwordPeriod.value);
      if (currentValue !== 0 && period > 0 && period < 10) {
        callback(new Error(traduction('VALIDATOR_VALIDATOR_PASSWORD_ONLY')));
        return false;
      } else if (currentValue !== 0 && period !== 0 && currentValue + 10 >= period) {
        callback(new Error(traduction('VALIDATOR_PASSWORD_PERIOD_BIG')));
        return false;
      } else {
        callback();
        return true;
      }
    },
    trigger: 'blur',
  },
  passwordMinLen: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 8,
    max: 20,
    message: traduction('VALIDATOR_PASSWORD_MIN_LEN'),
    validator: rangeVerification,
    trigger: 'blur',
  },
  // 密码有效期与密码最短使用期的校验互相关联，当有一处值更改时，另一处的校验需要重新设置
  periodValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 0,
    max: 365,
    validator: (rule: IRule, value: string | number, callback: any) => {
      if (!rangeVerification(rule, value, () => {})) {
        callback(new Error(traduction('VALID_VALUE_RANGE_TIP', [0, 365])));
        return false;
      }
      let currentValue = Number(value);
      let period = isNaN(leastPeriod.value) ? 0 : Number(leastPeriod.value);
      if (currentValue !== 0 && period >= 355) {
        callback(new Error(traduction('VALIDATOR_PASSWORD_USAGE_PERIOD')));
        return false;
      } else if (currentValue !== 0 && period !== 0 && currentValue - 10 <= period) {
        callback(new Error(traduction('VALIDATOR_PASSWORD_PERIOD_BIG')));
        return false;
      } else {
        callback();
        return true;
      }
    },
    trigger: 'blur',
  },
  revocationValid: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 0,
    max: 180,
    message: traduction('VALID_VALUE_RANGE_TIP', [0, 180]),
    validator: (rule: IRule, value: string | number, callback: any) => {
      if (crlOverdueWarningMode.value === 'Auto') {
        return true;
      } else {
        return rangeVerification(rule, value, callback);
      }
    },
    trigger: 'blur',
  },
  patternValid: {
    type: 'string',
    required: true,
    minLength: 0,
    maxLength: 255,
    validator: (rules: IRule, value: any, callback: (error?: Error) => void) => {
      const { minLength, maxLength } = rules;
      const len = value.length;
      if (value === '') {
        return true;
      }
      // 最小长度
      if (minLength && len < minLength) {
        callback(new Error(traduction('COMMON_FORMAT_ERROR')));
        return false;
      }
      // 最大长度
      if (maxLength && len > maxLength) {
        callback(new Error(traduction('COMMON_FORMAT_ERROR')));
        return false;
      }
      // 正则表达式校验
      if (!/^\^.*\$$/.test(value)) {
        callback(new Error(traduction('COMMON_FORMAT_ERROR')));
        return false;
      } 
      return true;
    },
    trigger: 'blur',
  }
});

function init() {
  getSecurityInfo().then(res => {
    authorityData = factoryEnhanceData(formatSecInfo(res));
    initValue(authorityData);
  });
}
onMounted(() => {
  init();
});

onBeforeUnmount(() => {
  const inputs = document.querySelectorAll('#securty-box input');
  inputs.forEach((inputEl) => {
    const clonedInput = inputEl.cloneNode(true);
    if (inputEl.parentNode) {
      inputEl.parentNode.replaceChild(clonedInput, inputEl);
      clonedInput.parentNode?.removeChild(clonedInput);
    }
  });
});

function initValue(authData: any) {
  openLock.value = authData.systemLockDownEnabled;
  setSystemLockDownEnabled(Boolean(openLock.value));
  openLock.show = typeof openLock.value === 'boolean';
  emergencyUser.options = authData.user || [];
  passwordCheck.value = authData.passwordComplexityCheckEnabled || false;
  serviceEnable.value = authData.OSAdministratorPrivilegeEnabled || false;
  loginSecurity.value = authData.sshPasswordAuthenticationEnabled || false;
  dnsBinding.value = authData.antiDNSRebindEnabled || false;
  passwordPeriod.value = String(authData.passwordValidityDays);
  leastPeriod.value = String(authData.minimumPasswordAgeDays);
  passwordMinLen.value = String(authData.minimumPasswordLength);
  minimumPasswordLength = String(authData.minimumPasswordLength);
  inactivity.value = String(authData.accountInactiveTimelimit);
  emergencyUser.value = authData.emergencyLoginUser;
  banPassword.value = String(authData.previousPasswordsDisallowedCount);
  banPassword.tip = hasSecurityConfig ? traduction('SECURITY_HISTORY_DISABLED_TIP', { m: authData.MaxPreviousPasswordsDisallowedCount }) : '';
  formRules.banPasswordValid.max = authData.MaxPreviousPasswordsDisallowedCount;
  formRules.banPasswordValid.message = hasSecurityConfig ? traduction('SECURITY_HISTORY_DISABLED_TIP', { m: authData.MaxPreviousPasswordsDisallowedCount }) : '';
  if (authData.accountLockoutThreshold === 0) {
    loginFailLockInput.locked = true;
    loginFailLockInput.value = '5';
  } else {
    loginFailLockInput.locked = false;
    loginFailLockInput.value = String(authData.accountLockoutThreshold);
  }
  loginFailLockInput.tip = traduction('VALID_VALUE_RANGE_TIP', [1, authData.MaxAccountLockoutThreshold]);
  formRules.loginFailLockValid.max = authData.MaxAccountLockoutThreshold;
  formRules.loginFailLockValid.message = traduction('VALID_VALUE_RANGE_TIP', [1, authData.MaxAccountLockoutThreshold]);
  loginFailInput.value = String(authData.accountLockoutDuration);
  loginFailInput.tip = traduction('VALID_VALUE_RANGE_TIP', [1, authData.MaxAccountLockoutDuration]);
  formRules.loginFailValid.max = authData.MaxAccountLockoutDuration;
  formRules.loginFailValid.message = traduction('VALID_VALUE_RANGE_TIP', [1, authData.MaxAccountLockoutDuration]);
  expireWarning.value = String(authData.certificateOverdueWarningTime);
  crlOverdueWarningMode.value = String(authData.crlOverdueWarningMode);
  crlOverdueWarningTime.value = String(authData.crlOverdueWarningTime);
  localAccountPasswordRulePolicy.value = String(authData.localAccountPasswordRulePolicy);
  localAccountPasswordPattern.value = String(authData.localAccountPasswordPattern);
  snmpCommunityPasswordRulePolicy.value = String(authData.snmpCommunityPasswordRulePolicy);
  snmpCommunityPasswordPattern.value = String(authData.snmpCommunityPasswordPattern);
  vncPasswordRulePolicy.value = String(authData.vncPasswordRulePolicy);
  vncPasswordPattern.value = String(authData.vncPasswordPattern);
  tlsVersionOptions.value = [];
  if (authData?.tlsSupported?.length > 2) {
    tlsSupported.value = true;
    for (let item of authData?.tlsSupported) {
      tlsVersionOptions.value.push({
        label: item,
        value: item,
        disabled: item === 'TLS1.3',
      });
    }
  } else {
    tlsSupported.value = false;
  }
  tlsVersion.value = tlsSupported.value? authData.tlsVersion : authData.tlsVersion[0];
  setDisabled();
  setInitValue();
  inited = true;
  loading(false);
}

function setDisabled(): void {
  if (!passwordCheck.value || systemLockDownEnabled.value || !hasSecurityConfig) {
    passwordMinLen.disabled = true;
  } else {
    passwordMinLen.disabled = false;
  }
  if (localAccountPasswordRulePolicy.value === 'Default' || systemLockDownEnabled.value || !hasSecurityConfig) {
    localAccountPasswordPattern.disabled = true;
  } else {
    localAccountPasswordPattern.disabled = false;
  }
  if (snmpCommunityPasswordRulePolicy.value === 'Default' || systemLockDownEnabled.value || !hasSecurityConfig) {
    snmpCommunityPasswordPattern.disabled = true;
  } else {
    snmpCommunityPasswordPattern.disabled = false;
  }
  if (vncPasswordRulePolicy.value === 'Default' || systemLockDownEnabled.value || !hasSecurityConfig) {
    vncPasswordPattern.disabled = true;
  } else {
    vncPasswordPattern.disabled = false;
  }
}

// 记录后台返回值，以后用来做判断是否进行了更改
function setInitValue(): void {
  for (const form of formComponents) {
    if (form.value !== undefined) {
      form.initValue = form.value;
      if (form.associated === IAuthorityEnum.accountLockoutThreshold) {
        form.initLocked = form.locked;
      }
    } else if (typeof form.value === 'object') {
      form.initValue = Object.assign({}, form.value);
    } else {
      form.initValue = form.value;
    }
  }
}

function setSystemLockDownEnabled(value: boolean) {
  // 切换系统为锁定状态
  store.state.glob.setGlobState({ type: 'systemLocked', value });
}
</script>

<template>
  <div id="securityEnhance">
    <el-form
      id="securityEnhanceForm"
      ref="ruleFormRef"
      label-width="auto"
      label-position="left"
      :model="formComponentsObj"
      :rules="formRules"
      :validate-on-rule-change="false"
      @validate="validate"
    >
      <!-- 系统锁定模式 -->
      <el-form-item v-show="openLock.show" :label="openLock.label" class="small-item">
        <el-switch
          :id="openLock.id"
          v-model="openLock.value"
          :disabled="openLock.disabled"
          class="switchLineHeight"
          @change="detectChange()"
        ></el-switch>
      </el-form-item>
      <!-- 业务侧管理员操作使能 -->
      <el-form-item :label="serviceEnable.label" class="small-item">
        <el-switch
          :id="serviceEnable.id"
          v-model="serviceEnable.value"
          class="switchLineHeight"
          :disabled="systemLockDownEnabled || serviceEnable.disabled"
          @change="detectChange()"
        ></el-switch>
      </el-form-item>
      <!-- SSH密码认证 -->
      <el-form-item :label="loginSecurity.label" class="small-item">
        <el-tooltip
          :content="loginSecurity.tip"
          :disabled="loginSecurity.tip === ''"
          placement="right"
          trigger-keys
        >
          <el-switch
            :id="loginSecurity.id"
            v-model="loginSecurity.value"
            class="switchLineHeight"
            :disabled="systemLockDownEnabled || loginSecurity.disabled"
            @change="detectChange()"
          ></el-switch>
        </el-tooltip>
      </el-form-item>
      <!-- 防DNS重绑定 -->
      <el-form-item :label="dnsBinding.label" class="small-item">
        <el-switch
          :id="dnsBinding.id"
          v-model="dnsBinding.value"
          class="switchLineHeight"
          :disabled="systemLockDownEnabled || dnsBinding.disabled"
          @change="detectChange()"
        ></el-switch>
      </el-form-item>
      <!-- TLS版本 -->
      <el-form-item :label="tlsVersion.label">
        <el-tooltip
          v-if="tlsSupported" :content="tlsVersion.tip" :disabled="tlsVersion.tip === ''" placement="right"
          trigger-keys
        >
          <el-checkbox-group :id="tlsVersion.id" v-model="tlsVersion.value" @change="detectChange()">
            <el-checkbox
              v-for="item in tlsVersionOptions" :key="item.label" :label="item.label" :value="item.value"
              :disabled="item.disabled"
            />
          </el-checkbox-group>
        </el-tooltip>
        <el-tooltip
          v-else :content="tlsVersion.tip" :disabled="tlsVersion.tip === ''" placement="right"
          trigger-keys
        >
          <el-select
            v-model="tlsVersion.value"
            v-addId.select="tlsVersion.id"
            :teleported="false"
            :disabled="systemLockDownEnabled || tlsVersion.disabled"
            :suffix-icon="PullDownTriangle"
            @change="detectChange()"
          >
            <el-option
              v-for="item in tlsVersion.options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-tooltip>
      </el-form-item>
      <!-- 不活动期限 -->
      <el-form-item
        :label="inactivity.label"
        class="item"
        :rules="formRules.inactivityValid"
        prop="inactivity.value"
      >
        <el-popover
          v-model:visible="popoverVisible[inactivity.id]"
          popper-class="no-wrap-popover"
          placement="right"
          :content="inactivity.tip"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="inactivity.value"
              v-addId.input="inactivity.id"
              v-clearable
              clearable
              type="text"
              :disabled="inactivity.disabled || systemLockDownEnabled"
              @focus="focus(inactivity.id)"
              @blur="blur(inactivity.id)"
              @input="input(inactivity, $event, 'inactivityValid')"
              @clear="clear(inactivity.id)"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>
      <!-- 紧急登录用户 -->
      <el-form-item v-show="emergencyUser.show" :label="emergencyUser.label">
        <el-tooltip
          :content="emergencyUser.tip"
          :disabled="emergencyUser.tip === ''"
          placement="right"
          trigger-keys
        >
          <el-select
            v-model="emergencyUser.value"
            :empty-values="[null, undefined]"
            v-addId.select="emergencyUser.id"
            :teleported="false"
            :disabled="systemLockDownEnabled || emergencyUser.disabled"
            :suffix-icon="PullDownTriangle"
            @change="emergencyUser.change"
          >
            <el-option
              v-for="item in emergencyUser.options"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            ></el-option>
          </el-select>
        </el-tooltip>
      </el-form-item>
      <div class="form-row" v-if="LDAP_PAGE_ENABLED">
        <!-- 登录失败锁定 -->
        <div class="form-row-item">
          <el-form-item :label="loginFailLockInput.label" class="item loginError" :rules="formRules.loginFailLockValid" prop="loginFailLockInput.value">
            <el-popover
              v-model:visible="popoverVisible[loginFailLockInput.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="loginFailLockInput.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-model="loginFailLockInput.value"
                  v-addId.input="loginFailLockInput.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="systemLockDownEnabled || loginFailLockInput.disabled || loginFailLockInput.locked"
                  @focus="focus(loginFailLockInput.id)"
                  @blur="blur(loginFailLockInput.id)"
                  @input="input(loginFailLockInput, $event, 'loginFailLockValid')"
                  @clear="clear(loginFailLockInput.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
            <el-checkbox
              v-model="loginFailLockInput.locked"
              class="unlimited-tip"
              size="large"
              :label="$t('SECURITY_UNLIMITED')"
              :disabled="systemLockDownEnabled || loginFailLockInput.disabled"
              @change="detectChange()"
            ></el-checkbox>
          <div
            v-if="loginFailLockInput.locked"
            v-t="'SECURITY_LOGIN_FAILED_LOCK_TIP'"
            class="lock-tip"
          ></div>
          </el-form-item>
        </div>
      </div>
      <!-- 锁定时间 -->
      <el-form-item
        :label="loginFailInput.label"
        :rules="formRules.loginFailValid"
        prop="loginFailInput.value"
        class="item"
      >
        <div v-if="loginFailInput.show">
          <el-popover
            v-model:visible="popoverVisible[loginFailInput.id]"
            popper-class="no-wrap-popover"
            placement="right"
            :content="loginFailInput.tip"
            trigger="focus"
            trigger-keys
          >
            <template #reference>
              <el-input
                v-if="!loginFailLockInput.locked"
                v-model="loginFailInput.value"
                v-addId.input="loginFailInput.id"
                v-clearable
                clearable
                type="text"
                :disabled="loginFailInput.disabled || systemLockDownEnabled"
                @focus="focus(loginFailInput.id)"
                @blur="blur(loginFailInput.id)"
                @input="input(loginFailInput, $event, 'loginFailValid')"
                @clear="clear(loginFailInput.id)"
              >
                <template #suffix>
                  <ErrorIcon />
                  <ClearableIcon />
                </template>
              </el-input>
              <el-input v-else v-addId.input="loginFailInput.id" :disabled="true"></el-input>
            </template>
          </el-popover>
        </div>
      </el-form-item>
      <!-- 证书过期提前告警时间 -->
      <el-form-item
        :label="expireWarning.label"
        class="item lastItem"
        :rules="formRules.expiresValid"
        prop="expireWarning.value"
      >
        <el-popover
          v-model:visible="popoverVisible[expireWarning.id]"
          popper-class="no-wrap-popover"
          placement="right"
          :content="expireWarning.tip"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="expireWarning.value"
              v-addId.input="expireWarning.id"
              v-clearable
              clearable
              type="text"
              :disabled="expireWarning.disabled || systemLockDownEnabled"
              @focus="focus(expireWarning.id)"
              @blur="blur(expireWarning.id)"
              @input="input(expireWarning, $event, 'expiresValid')"
              @clear="clear(expireWarning.id)"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>
      <div class="form-row">
        <!-- 吊销列表过期检测模式 -->
        <div class="form-row-item">
          <el-form-item :label="crlOverdueWarningMode.label">
            <el-select
              v-model="crlOverdueWarningMode.value"
              v-addId.select="crlOverdueWarningMode.id"
              :teleported="false"
              :disabled="systemLockDownEnabled || crlOverdueWarningMode.disabled"
              :suffix-icon="PullDownTriangle"
              @change="crlOverdueWarningMode.changeFn()"
            >
              <el-option
                v-for="item in crlOverdueWarningMode.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!-- 吊销列表过期提前告警时间 -->
        <div class="form-row-item">
          <el-form-item
            :label="crlOverdueWarningTime.label"
            class="item lastItem"
            :rules="formRules.revocationValid"
            prop="crlOverdueWarningTime.value"
          >
            <el-popover
              v-model:visible="popoverVisible[crlOverdueWarningTime.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="crlOverdueWarningTime.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-if="crlOverdueWarningMode.value === 'Customized'"
                  v-model="crlOverdueWarningTime.value"
                  v-addId.input="crlOverdueWarningTime.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="crlOverdueWarningTime.disabled || systemLockDownEnabled"
                  @focus="focus(crlOverdueWarningTime.id)"
                  @blur="blur(crlOverdueWarningTime.id)"
                  @input="input(crlOverdueWarningTime, $event, 'revocationValid')"
                  @clear="clear(crlOverdueWarningTime.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
                <el-input v-else v-addId.input="crlOverdueWarningTime.id" :disabled="true"></el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
      </div>
      <div id="passwordTitle" class="password-title">{{ $t('SECURITY_PASSWORD') }}</div>
      <!-- 密码检查 -->
      <el-form-item :label="passwordCheck.label" class="small-item">
        <el-tooltip
          :content="passwordCheck.tip"
          :disabled="passwordCheck.tip === ''"
          placement="right"
          trigger-keys
        >
          <el-switch
            :id="passwordCheck.id"
            v-model="passwordCheck.value"
            class="switchLineHeight"
            :disabled="systemLockDownEnabled || passwordCheck.disabled"
            @change="detectChange('passwordCheck')"
          ></el-switch>
        </el-tooltip>
      </el-form-item>
      <div class="form-row">
        <!-- 密码有效期-->
        <div class="form-row-item">
          <el-form-item
            :label="passwordPeriod.label"
            class="item"
            :rules="formRules.periodValid"
            prop="passwordPeriod.value"
          >
            <el-popover
              v-model:visible="popoverVisible[passwordPeriod.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="passwordPeriod.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-model="passwordPeriod.value"
                  v-addId.input="passwordPeriod.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="passwordPeriod.disabled || systemLockDownEnabled"
                  @focus="focus(passwordPeriod.id)"
                  @blur="blur(passwordPeriod.id)"
                  @input="input(passwordPeriod, $event, 'periodValid')"
                  @clear="clear(passwordPeriod.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>

        <!-- 密码最短使用期 -->
        <div class="form-row-item">
          <el-form-item
            :label="leastPeriod.label"
            class="item"
            :rules="formRules.leastPeriodValid"
            prop="leastPeriod.value"
          >
            <el-popover
              v-model:visible="popoverVisible[leastPeriod.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="leastPeriod.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-model="leastPeriod.value"
                  v-addId.input="leastPeriod.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="leastPeriod.disabled || systemLockDownEnabled"
                  @focus="focus(leastPeriod.id)"
                  @blur="blur(leastPeriod.id)"
                  @input="input(leastPeriod, $event, 'leastPeriodValid')"
                  @clear="clear(leastPeriod.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
      </div>
      <!-- 密码最小长度配置-->
      <el-form-item
        :label="passwordMinLen.label"
        class="item"
        :rules="formRules.passwordMinLen"
        prop="passwordMinLen.value"
      >
        <el-popover
          v-model:visible="popoverVisible[passwordMinLen.id]"
          popper-class="no-wrap-popover"
          placement="right"
          :content="passwordMinLen.tip"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="passwordMinLen.value"
              v-addId.input="passwordMinLen.id"
              v-clearable
              clearable
              type="text"
              :disabled="passwordMinLen.disabled || systemLockDownEnabled"
              @focus="focus(passwordMinLen.id)"
              @blur="blur(passwordMinLen.id)"
              @input="input(passwordMinLen, $event, 'passwordMinLen')"
              @clear="clear(passwordMinLen.id)"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>
      <!-- 禁用历史密码 -->
      <el-form-item :label="banPassword.label" class="item" :rules="formRules.banPasswordValid" prop="banPassword.value">
        <el-popover
          v-model:visible="popoverVisible[banPassword.id]"
          popper-class="no-wrap-popover"
          placement="right"
          :content="banPassword.tip"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="banPassword.value"
              v-addId.input="banPassword.id"
              v-clearable
              clearable
              type="text"
              :disabled="systemLockDownEnabled || banPassword.disabled"
              @focus="focus(banPassword.id)"
              @blur="blur(banPassword.id)"
              @input="input(banPassword, $event, 'banPasswordValid')"
              @clear="clear(banPassword.id)"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>
      <div class="form-row">
        <!-- 本地用户密码校验规则 -->
        <div class="form-row-item">
          <el-form-item :label="localAccountPasswordRulePolicy.label">
            <el-select
              v-model="localAccountPasswordRulePolicy.value"
              v-addId.select="localAccountPasswordRulePolicy.id"
              :teleported="false"
              :disabled="systemLockDownEnabled || localAccountPasswordRulePolicy.disabled"
              :suffix-icon="PullDownTriangle"
              @change="detectChange('localAccountPasswordRulePolicy')"
            >
              <el-option
                v-for="item in localAccountPasswordRulePolicy.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!-- 本地用户密码校验正则表达式 -->
        <div class="form-row-item">
          <el-form-item
            :label="localAccountPasswordPattern.label"
            class="item lastItem"
            :rules="formRules.patternValid"
            prop="localAccountPasswordPattern.value"
          >
            <el-popover
              v-model:visible="popoverVisible[localAccountPasswordPattern.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="localAccountPasswordPattern.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-if="localAccountPasswordRulePolicy.value !== '1'"
                  v-model="localAccountPasswordPattern.value"
                  v-addId.input="localAccountPasswordPattern.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="localAccountPasswordPattern.disabled || systemLockDownEnabled"
                  @focus="focus(localAccountPasswordPattern.id)"
                  @blur="blur(localAccountPasswordPattern.id)"
                  @input="input(localAccountPasswordPattern, $event, 'patternValid')"
                  @clear="clear(localAccountPasswordPattern.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
                <el-input
                  v-else
                  v-addId.input="localAccountPasswordPattern.id"
                  :disabled="true"
                ></el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
      </div>
      <div class="form-row">
        <!-- SNMP团体名校验规则 -->
        <div class="form-row-item">
          <el-form-item :label="snmpCommunityPasswordRulePolicy.label">
            <el-select
              v-model="snmpCommunityPasswordRulePolicy.value"
              v-addId.select="snmpCommunityPasswordRulePolicy.id"
              :teleported="false"
              :disabled="systemLockDownEnabled || snmpCommunityPasswordRulePolicy.disabled"
              :suffix-icon="PullDownTriangle"
              @change="detectChange('snmpCommunityPasswordRulePolicy')"
            >
              <el-option
                v-for="item in snmpCommunityPasswordRulePolicy.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!-- SNMP团体名校验正则表达式 -->
        <div class="form-row-item">
          <el-form-item
            :label="snmpCommunityPasswordPattern.label"
            class="item lastItem"
            :rules="formRules.patternValid"
            prop="snmpCommunityPasswordPattern.value"
          >
            <el-popover
              v-model:visible="popoverVisible[snmpCommunityPasswordPattern.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="snmpCommunityPasswordPattern.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-if="snmpCommunityPasswordRulePolicy.value !== '1'"
                  v-model="snmpCommunityPasswordPattern.value"
                  v-addId.input="snmpCommunityPasswordPattern.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="snmpCommunityPasswordPattern.disabled || systemLockDownEnabled"
                  @focus="focus(snmpCommunityPasswordPattern.id)"
                  @blur="blur(snmpCommunityPasswordPattern.id)"
                  @input="input(snmpCommunityPasswordPattern, $event, 'patternValid')"
                  @clear="clear(snmpCommunityPasswordPattern.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
                <el-input
                  v-else
                  v-addId.input="snmpCommunityPasswordPattern.id"
                  :disabled="true"
                ></el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
      </div>
      <div class="form-row" v-if="LDAP_PAGE_ENABLED">
        <!-- vnc密码校验规则 -->
        <div class="form-row-item">
          <el-form-item :label="vncPasswordRulePolicy.label">
            <el-select
              v-model="vncPasswordRulePolicy.value"
              v-addId.select="vncPasswordRulePolicy.id"
              :teleported="false"
              :disabled="systemLockDownEnabled || vncPasswordRulePolicy.disabled"
              :suffix-icon="PullDownTriangle"
              @change="detectChange('vncPasswordRulePolicy')"
            >
              <el-option
                v-for="item in vncPasswordRulePolicy.options"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              ></el-option>
            </el-select>
          </el-form-item>
        </div>
        <!-- vnc密码校验正则表达式 -->
        <div class="form-row-item">
          <el-form-item
            :label="vncPasswordPattern.label"
            class="item lastItem"
            :rules="formRules.patternValid"
            prop="vncPasswordPattern.value"
          >
            <el-popover
              v-model:visible="popoverVisible[vncPasswordPattern.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="vncPasswordPattern.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-if="vncPasswordRulePolicy.value !== '1'"
                  v-model="vncPasswordPattern.value"
                  v-addId.input="vncPasswordPattern.id"
                  v-clearable
                  clearable
                  type="text"
                  :disabled="vncPasswordPattern.disabled || systemLockDownEnabled"
                  @focus="focus(vncPasswordPattern.id)"
                  @blur="blur(vncPasswordPattern.id)"
                  @input="input(vncPasswordPattern, $event, 'patternValid')"
                  @clear="clear(vncPasswordPattern.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
                <el-input
                  v-else
                  v-addId.input="vncPasswordPattern.id"
                  :disabled="true"
                ></el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
      </div>

      <!-- 保存按钮 -->
      <el-form-item>
        <el-button
          v-if="hasUserConfig || hasSecurityConfig"
          id="authorityButton"
          type="primary"
          :disabled="buttonDisable"
          @click="showMessage()"
        >
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
  <Dialog ref="dialogRef" :config="dialogConfig" @close="dialogClose"></Dialog>
</template>

<style lang="scss" scoped>
#securityEnhance {
  background: var(--o-bg-color-base);
  border-radius: 0 4px 4px;
  padding: 16px 24px 0 24px;

  .el-select {
    width: 264px;
  }

  .input-top-text {
    display: block;
  }

  .margin-text {
    margin-left: 8px;
  }

  .lock-tip {
    color: var(--o-color-major);
    width: 264px;
    word-wrap: break-word;
    line-height: 16px;
  }
  .unlimited-tip {
    margin-left: 32px;
  }
  :deep(.el-form-item__label::before) {
    display: none;
  }
  .password-title{
    font-size: 16px;
    color: var(--o-text-color-primary);
    line-height: 24px;
    font-weight: bold;
    margin-bottom: 16px;
  }
  .el-form .form-row {
    border-radius: 4px;
    display: flex;
    flex-wrap: wrap;
    & .form-row-item {
      margin-right: 32px;
    }
  }
  .loginError{
    :deep(.el-form-item__content){
      display: block !important;
    }
  }
}
</style>
<style lang="scss">
#securityEnhance {
  .small-item {
    height: 16px;
    .el-form-item__label {
      padding-top: 0;
      padding-bottom: 0;
    }

    .el-form-item__content {
      line-height: 16px;
    }
  }

  .item {
    .el-input {
      width: 264px;
    }
  }

}
</style>
