<script setup lang="ts">
import { IconXSolid } from '@computing/opendesign-icons';
import SecurityTips from '../SecurityTips/SecurityTips.vue';
import ModifyPassword from '../ModifyPassword/ModifyPassword.vue';
import Loading from '@/components/Loading/Loading.vue';
import { IconCaretUp } from '@computing/opendesign-icons';
import { onMounted, reactive, ref, watch } from 'vue';
import { LOGIN_TYPE, UserPrivil } from '@/model/base-enum';
import useStore from '@/stores';
import { useRouter } from 'vue-router';
import {
  getKvmHandler,
  getPrivils,
  getPwdCheck,
  getSSOKerberos,
  kvmLogin,
  localLoginSensitive,
} from '../login-service';
import { getLocationSearch, getMessageId, getSsoErrorMsg } from '@/utils/utils';
import { traduction } from '@/utils/language';
import { getStoreData, setStoreData } from '@/utils/composition';
import { IResponse } from '@/model/base-interface';
import { AxiosResponse } from 'axios';
import {
  getLogoImage,
  saveSessionData,
  saveStoreToLocal,
  saveUserPermission,
} from '@/utils/common-service';
import { IconError } from '@computing/opendesign-icons';
import { checkPrivil } from '../../router/routes';
import { MaxLength } from '@/model/base-enum';
import { arrayBufferToHexStr, importRsaPublicKey, rsaEncrypt } from '@/utils/crypto';

/**
 * pageInfo: 查询Login接口得到的基础数据
 * loginInfo: 双因素，SSO登录时传递过来的登录信息
 * loginType: 登录类型（sso, 双因素，账号密码）
 */
const props = defineProps({
  pageInfo: {
    type: Object,
    required: true,
    default: () => {},
  },
  sessionInfo: {
    type: Object,
    requied: false,
    default: () => {},
  },
  loginType: {
    type: Number,
    required: true,
    default: LOGIN_TYPE.undetermined,
  },
  complete: {
    type: Boolean,
    required: false,
    default: false,
  },
  stateMessage: {
    type: String,
    requrie: false,
    default: '',
  },
  restartInfo: {
    type: Object,
    requied: false,
    default: () => {},
  },
});
const store = useStore();
const router = useRouter();

const inputLength = reactive({
  userName: MaxLength.user,
  password: MaxLength.min,
});
// 获取定制信息
const ptcInfo = localStorage.getItem('ptc');
const ptcInfoJson = JSON.parse(ptcInfo as string);
const logoRef = ref(null);
const logoUrl = ref('');
const errorMsg = ref('');
const logoStyle = reactive({});
const textStyle = reactive({});
// 页面的状态，根据页面状态，显示不同的页面信息，0代表账户密码登录界面
const firstLoginPolicy = ref(false);
const passwordExpired = ref(false);
const pageState = ref(0);
const prevPageState = ref(0);
const isLocked = ref(false);
const isPwdChecked = ref(false);
const minPwdLength = ref(8);
const isLogining = ref(false);
const qrCodeShow = ref(false);
const qrCodeImg = ref('');
const webStyle = getStoreData('glob', 'webStyle');
const expireDay = ref();

// 设置logo和二维码
logoUrl.value = getLogoImage();
setQrCode();

let options = reactive([
  {
    label: traduction('LOGIN_DOMAIN_IBMC', { softwareName: store.state.loct.sn }),
    value: 'LocaliBMC',
    type: 'Local',
    show: true,
  },
  {
    label: traduction('LOGIN_DOMAIN_AUTO'),
    value: 'AutomaticMatching',
    type: 'Auto',
    show: false,
  },
]);

let lockDuration = 300;
let selectedDomain = options[0];
const loginInfo = reactive({
  account: '',
  password: '',
  domain: options[0].value,
});
const clearError = () => {
  errorMsg.value = '';
};
const clearUserAndPwd = () => {
  loginInfo.account = '';
  loginInfo.password = '';
};

const selectChange = (item: any) => {
  loginInfo.domain = item.value;
  selectedDomain = item;
  if (item.type !== 'Local') {
    inputLength.userName = MaxLength.max;
    inputLength.password = MaxLength.max;
  } else {
    inputLength.userName = MaxLength.user;
    inputLength.password = MaxLength.min;
  }
  setStoreData('loct', 'pml', inputLength.password);
  saveStoreToLocal();
};

// 清空账号密码
function cleanInput() {
  loginInfo.account = '';
  loginInfo.password = '';
}

function getDefaultLogo() {
  logoUrl.value = '/image/ibmc.png';
}

// 本地登录流程
const login = () => {
  if (isLogining.value === true) {
    return;
  }

  // 检测是否存在KVM直连的场景
  if (sessionStorage.getItem('kvmConnect')) {
    kvmConnect();
    return;
  }

  if (loginInfo.account === '' || loginInfo.password === '') {
    errorMsg.value = traduction('LOGIN_NOT_EMPTY');
    cleanInput();
    return;
  }

  localConnect();
};

// KRB单点登录
function ssoLogin() {
  if (isLogining.value === true) {
    return;
  }
  isLogining.value = true;
  getSSOKerberos().then(
    (rsp: IResponse) => {
      const authorization = rsp.headers['www-authenticate']?.slice(10);
      const paramGen = async (key) => {
        const pubKey = await importRsaPublicKey(key);
        const encryptedUsername = arrayBufferToHexStr(await rsaEncrypt(authorization, pubKey));
        const encryptedPassword = arrayBufferToHexStr(await rsaEncrypt(authorization, pubKey));

        return {
          UserName: encryptedUsername,
          Password: encryptedPassword,
          Type: 'KerberosSSO',
          Domain: 'KerberosSSO',
        };
      };
      localLoginSensitive(paramGen).then(
        (res: IResponse) => {
          setStoreData('loct', 'nopwd', true);
          setStoreData('loct', 'loginType', LOGIN_TYPE.krbsso);
          saveSessionData(res.data.Session);
          savePrevLoginData(res.data);
          getPrivils().then(privils => {
            // Login接口返回数据这里是数组，SSO跳转查询session接口返回的Role是字符串
            saveUserPermission(res.data.Session.Role, privils.data.Members);
            goHome();
          });
        },
        error => {
          isLogining.value = false;
          const errorId = getMessageId(error?.data)?.[0]?.code || '';
          krbSSOErrorHandle(errorId, 'sso');
        },
      );
    },
    () => {
      isLogining.value = false;
      errorMsg.value = traduction('LOGIN_SSO_NOAUTHRIZED');
    },
  );
}

function pwdCheck(): void {
  getPwdCheck().then(
    (res: IResponse) => {
      isLogining.value = false;
      const adcance = res.data;
      isLocked.value = adcance.SystemLockDownEnabled || false;
      isPwdChecked.value = adcance.PasswordComplexityCheckEnabled;
      minPwdLength.value = adcance.MinimumPasswordLength;
      pageState.value = 2;
    },
    () => {
      isLogining.value = false;
      isLocked.value = false;
      isPwdChecked.value = false;
      minPwdLength.value = 8;
      pageState.value = 2;
    },
  );
}

// 本地登录逻辑
function localConnect() {
  isLogining.value = true;
  const paramGen = async (key) => {
    const pubKey = await importRsaPublicKey(key, 'SHA-1');
    const encryptedUsername = arrayBufferToHexStr(await rsaEncrypt(loginInfo.account, pubKey));
    const encryptedPassword = arrayBufferToHexStr(await rsaEncrypt(loginInfo.password, pubKey));

    return {
      UserName: encryptedUsername,
      Password: encryptedPassword,
      Domain: selectedDomain.value,
      Type: selectedDomain.type,
    };
  };

  localLoginSensitive(paramGen).then(
    (res: AxiosResponse) => {
      const data = res.data as any;
      if (data.error) {
        // 需要强制修改密码的场景
        const errorId = data.error?.code || '';
        if (errorId !== 'UserPasswordExpired') {
          firstLoginPolicy.value = true;
        } else {
          passwordExpired.value = true;
        }
        setStoreData('loct', 'uid', data.Session.UserID);
        setStoreData('loct', 'to', data.XCSRFToken);
        saveStoreToLocal();
        pwdCheck();
      } else {
        savePrevLoginData(data);
        saveSessionData(data.Session);

        // 开始查询用户角色对应的权限
        Promise.all([getPrivils(), getPwdCheck()]).then((rsp: IResponse[]) => {
          const privil = rsp[0];
          const adcance = rsp[1];
          isLocked.value = adcance.data.SystemLockDownEnabled || false;
          isPwdChecked.value = adcance.data.PasswordComplexityCheckEnabled;
          minPwdLength.value = adcance.data.MinimumPasswordLength;
          saveUserPermission(data.Session.Role, privil.data.Members);
          const neetResetPwd = checkNeedResetPassword(data);
          if (neetResetPwd) {
            pageState.value = 1;
          } else {
            goHome();
          }
        });
      }
    },
    error => {
      isLogining.value = false;
      clearUserAndPwd();
      const errorId = getMessageId(error?.data)?.[0]?.code || '';
      krbSSOErrorHandle(errorId, 'local');
    },
  );
}

// KVM直连登录
function kvmConnect() {
  const param = {
    check_pwd: loginInfo.password,
    logtype: loginInfo.domain === 'LocaliBMC' ? 0 : 1,
    user_name: loginInfo.account,
    func: 'DirectKVM',
    IsKvmApp: '0',
    KvmMode: '1',
  };
  isLogining.value = true;
  kvmLogin(param)
    .then(
      res => {
        const stateCode = res.data['DirectKVM'][0];
        if (stateCode === 0) {
          const search = parseKvmConnectParams(sessionStorage.getItem('kvmSearch') || '');
          let url = '/UI/Rest/KVMHandler' + search;
          if (search && search.includes('authParam=')) {
            // jumpflag表示是否执行后端跳转，若不执行，则返回的是 json对象，若跳转，则返回的是xml格式的脚本内容
            url += '&jumpflag=notjump';
          }
          if (localStorage.getItem('kvmJava')) {
            self.window.location.href = url;
          } else {
            getKvmHandler(url)
              .then((rsp: AxiosResponse) => {
                if (rsp.data.kvmHtml5Info) {
                  window['kvmHtml5Info'] = { kvmHtml5Info: JSON.stringify(rsp.data.kvmHtml5Info) };
                  router.push({ name: 'KVM' });
                }
              })
              .finally(() => {
                isLogining.value = false;
              });
          }
          clearKvmConnectCache();
          clearUserAndPwd();
        } else {
          clearUserAndPwd();
          const errorCode = getSsoErrorMsg(stateCode);
          errorMsg.value = traduction(errorCode);
        }
      },
      () => {
        clearUserAndPwd();
        errorMsg.value = traduction('LOGING_SSO_ERROR_1');
      },
    )
    .finally(() => {
      isLogining.value = false;
    });
}

// 清除KVM直连所存储的信息
function clearKvmConnectCache() {
  sessionStorage.removeItem('kvmConnect');
  sessionStorage.removeItem('kvmSearch');
  self.localStorage.removeItem('kvmjava');
}

// 过滤KVMHandler的search值
function parseKvmConnectParams(search: string) {
  const _search = getLocationSearch(search);
  if (Object.keys(_search).length > 0) {
    let tempStr = '';
    Object.keys(_search).forEach(key => {
      const value = _search[key];
      if (key === 'openway' || key === 'openWay') {
        if (value === 'html5' || value === 'jre') {
          tempStr += `openWay=${value}&`;
        }
        if (value === 'java') {
          tempStr += 'openWay=jre&';
        }
      }
      if (key === 'authParam' && /^[0-9a-fA-f]+$/.test(value)) {
        tempStr += `${key}=${value}&`;
      }
      if (key === 'lp' && /^[a-z]{2,10}$/.test(value)) {
        tempStr += `${key}=${value}&`;
      }
      if (key === 'lang' && /^[a-z]{2,10}$/.test(value)) {
        tempStr += `${key}=${value}&`;
      }
    });
    tempStr = tempStr.substring(0, tempStr.length - 1);
    if (tempStr !== '') {
      tempStr = '?' + tempStr;
    }
    return tempStr;
  }
  return '';
}

// 保存上一次登录数据
function savePrevLoginData(result: any) {
  setStoreData('loct', 'to', result.XCSRFToken);
  setStoreData('loct', 'lip', result.LastLoginIP);
  setStoreData(
    'loct',
    'ltime',
    result.LastLoginTime ? result.LastLoginTime.substr(0, 19).replace('T', ' ') : '',
  );
  saveStoreToLocal();
}

/**
 * 根据登录信息，判断是否需要修改密码
 * 1. SSO跳转, 双因素，krbsso登录不需要修改密码
 * 2. 无配置自身权限用户无法修改密码
 * 3. 非初始密码，且密码有效期大于10天
 */
function checkNeedResetPassword(lInfo: any) {
  // DaysBeforeExpiration取值：0（已过期），null(无限期)，0-30(剩余有效期)
  const expireDays = lInfo.DaysBeforeExpiration === null ? 30 : lInfo.DaysBeforeExpiration;
  const isInitialPwd = lInfo.InsecurePromptEnabled === 'On';

  // 满足1.账号密码登录 2.有修改密码的权限 3.（是初始密码或者密码有效期小于等于10天）
  if (
    props.loginType === LOGIN_TYPE.common &&
    checkPrivil(UserPrivil.configSelf) &&
    (isInitialPwd || expireDays <= 10)
  ) {
    if (expireDays <= 10 && expireDays > 0) {
      expireDay.value = expireDays;
    }
    return true;
  }
  return false;
}

// 跳转到Home操作
function goHome() {
  router.push('/navigate/home');
}

function jumpToModifyPwd() {
  pageState.value = 2;
  prevPageState.value = 1;
}

// 根据错误ID提示错误信息
function krbSSOErrorHandle(errorId: string, type: 'local' | 'sso') {
  switch (errorId) {
    case '':
      errorMsg.value = traduction('LOGIN_FAILED');
      break;
    case 'AuthorizationFailed':
      if (type === 'sso') {
        errorMsg.value = traduction('LOGIN_SSO_NOAUTHRIZED');
      } else {
        const duration = props.pageInfo.lockDuration;
        if (duration && duration > 0) {
          errorMsg.value = traduction('LOGIN_FAILED_ERR', { lockDuration: duration / 60 });
        } else {
          errorMsg.value = traduction('LOGING_SSO_ERROR_130');
        }
      }
      break;
    case 'LoginFailed':
      errorMsg.value = traduction('LOGING_SSO_ERROR_1');
      break;
    case 'NoAccess':
      errorMsg.value = traduction('LOGING_SSO_ERROR_136');
      break;
    case 'UserLocked':
      if (type === 'sso') {
        errorMsg.value = traduction('LOGING_SSO_ERROR_131');
      } else {
        errorMsg.value = traduction('LoginUserLocked' + '.errorMessage');
      }
      break;
    case 'UserPasswordExpired':
      errorMsg.value = traduction('LOGING_SSO_ERROR_137');
      break;
    case 'UserLoginRestricted':
      errorMsg.value = traduction('LOGING_SSO_ERROR_144');
      break;
    case 'SessionLimitExceeded':
      errorMsg.value = traduction('LOGING_SSO_ERROR_4096');
      break;
    default:
      errorMsg.value = traduction('LOGIN_FAILED');
  }
}

/**
 * 组件挂载后，检查是否session信息传递进来, 只有以下2种情况，会有sessionInfo传进来。
 * 1. SSO跳转登录查询得到
 * 2. 双因素登录时查询得到
 * 若有sessionInfo信息，则查询session会话对应的权限。然后跳转到首页
 */
onMounted(() => {
  if (props.loginType === LOGIN_TYPE.sso || props.loginType === LOGIN_TYPE.twoFactor) {
    // 查询该session会话对应的权限
    getPrivils().then((res: IResponse) => {
      let roles = props.sessionInfo.Role;
      if (typeof roles === 'string') {
        roles = roles.split(',');
      }

      if (props.loginType === LOGIN_TYPE.twoFactor) {
        setStoreData('loct', 'twofac', true);
        setStoreData('loct', 'nopwd', true);
      }

      saveSessionData(props.sessionInfo);
      saveUserPermission(roles, res.data.Members);

      goHome();
    });
  }
});

// 监听pageInfo数据变化
watch(
  props,
  (newVal: any) => {
    const data = newVal.pageInfo;
    options[0].label = traduction('LOGIN_DOMAIN_IBMC', { softwareName: data.SoftwareName });
    //  只要KRB使能和LDAP使能开启一个，则显示自动匹配
    options[1].show = false;
    if (
      data.KerberosDomain !== undefined ||
      (data.ldapDomains !== undefined && data.ldapDomains !== null)
    ) {
      options[1].show = true;
    }

    // 追加KRB域名数据;
    if (
      data.KerberosDomain !== undefined &&
      data.KerberosDomain !== '' &&
      !isContainKey(data.KerberosDomain)
    ) {
      options.push({
        label: data.KerberosDomain,
        value: data.KerberosDomain,
        type: 'Kerberos',
        show: true,
      });
    }

    // 追加域名数据;
    if (data.ldapDomains !== undefined && data.ldapDomains !== null) {
      const ldapDomains = data.ldapDomains.map((item: string) => {
        const temp = {
          label: item,
          value: item,
          type: 'Ldap',
          show: true,
        };
        if (!isContainKey(item)) {
          options.push(temp);
        }
      });
    }
    // 监听重启状态
    if (newVal.restartInfo?.reset) {
      pageState.value = 3;
    }
  },
  { deep: true },
);

function isContainKey(key: string) {
  let result = false;
  for (let i = 0; i < options.length; i++) {
    if (options[i].value === key) {
      result = true;
      break;
    }
  }
  return result;
}

function loadSuccess(ev: Event) {
  const width = (ev.target as HTMLElement)?.offsetWidth;
  logoStyle['width'] = `${width}px`;
  textStyle['width'] = `${
    ((ev.target as HTMLElement).parentNode?.parentNode as HTMLElement).offsetWidth - width - 30
  }px`;
}

/** 获取二维码逻辑
 *  1. 预览的二维码优先级为0（最高）
 *  2. code1表示定制的二维码，优先级为1.(注：原V2版本中有code2，但经确认后，code2并不存在与主要版本分支中，故V3版本直接删除，若基本V3版本的分支版本有需求code2，自行修改逻辑)
 *  3. 默认的二维码（中文状态下使用helpdoc_zh.png，非中文状态下使用helpdoc_en.png）
 */
function setQrCode() {
  // 若有定制二维码，则以定制logo为准，否则以H3C的定制模式为准
  if (ptcInfoJson && ptcInfoJson.qrCode !== undefined && ptcInfoJson.qrCode !== '') {
    qrCodeImg.value = ptcInfoJson.qrCode;
  } else {
    qrCodeImg.value = 'code1.png';
  }
}

function getDefaultQrCode() {
  const locale = getStoreData('loct', 'locale');
  if (locale === 'zh') {
    qrCodeImg.value = '/image/helpdoc_zh.png';
  } else {
    qrCodeImg.value = '/image/helpdoc_en.png';
  }
}
</script>

<template>
  <div class="login-content-op">
    <div
      id="login-input"
      :class="{
        center: ptcInfoJson?.position === 'center',
        large: ptcInfoJson?.size === 'large',
        tip: pageState === 1,
        modify: pageState === 2
      }"
    >
      <!-- 单板信息 -->
      <div v-if="pageState !== 2" class="login-input-header">
        <p v-if="webStyle === 'default'" class="welcome">{{ $t('LOGIN_WELCOME') }}</p>
        <div class="pro-container">
          <div class="logo" :style="logoStyle">
            <img ref="logoRef" :src="logoUrl" @load="loadSuccess($event)" @error="getDefaultLogo" />
          </div>
          <div v-if="webStyle === 'default'" class="text" :style="textStyle">
            <p id="productName">{{ props.pageInfo.ProductName }}</p>
            <p id="softwareName">{{ props.pageInfo.FQDN }}</p>
          </div>
          <span v-if="webStyle && webStyle !== 'default'" class="login-simple-text">
            {{ $t('LOGIN_LABEL') }}
          </span>
          <div
            v-if="props.pageInfo.showCode && pageState === 0 && webStyle === 'default'"
            class="ico"
          >
            <span id="iconCode" @click="qrCodeShow = !qrCodeShow"></span>
          </div>
        </div>
      </div>
      <!-- 账号密码登录 -->
      <div
        v-if="qrCodeShow === false && (props.loginType === 0 || props.loginType === 3)"
        class="common"
      >
        <div v-if="pageState === 0">
          <!-- 登录报错提示 -->
          <div class="error-container">
            <div v-if="errorMsg !== ''" class="error">
              <el-icon :size="16">
                <IconError />
              </el-icon>
              <span>{{ errorMsg }}</span>
            </div>
          </div>

          <!-- 输入框 -->
          <div class="login-input-body">
            <!-- 账号 -->
            <div class="login-item">
              <el-input
                :id="'account'"
                v-model="loginInfo.account"
                :maxlength="inputLength.userName"
                :placeholder="$t('LOGIN_USER_TIP')"
                @input="clearError()"
              ></el-input>
              <el-icon
                v-if="loginInfo.account.length > 0"
                class="icon-clear"
                @click="loginInfo.account = ''"
              >
                <IconXSolid />
              </el-icon>
            </div>
            <!-- 密码 -->
            <div class="login-item">
              <el-input
                :id="'loginPwd'"
                v-model="loginInfo.password"
                type="password"
                autocomplete="new-password"
                :maxlength="inputLength.password"
                :placeholder="$t('LOGIN_PASSWORD_TIP')"
                @input="clearError()"
                @keyup.enter="login()"
              ></el-input>
              <el-icon
                v-if="loginInfo.password.length > 0"
                class="icon-clear"
                @click="loginInfo.password = ''"
              >
                <IconXSolid />
              </el-icon>
            </div>

            <!-- 域名 -->
            <el-select
              v-model="loginInfo.domain"
              v-addId.select="'ulDomain'"
              popper-class="login-select"
              :teleported="false"
              :suffix-icon="IconCaretUp"
              @change="cleanInput"
            >
              <template v-for="item in options" :key="item.value">
                <el-option
                  v-if="item.show"
                  :label="item.label"
                  :value="item.value"
                  @click="selectChange(item)"
                >
                  <el-tooltip
                    placement="left"
                    :content="item.label"
                    :hide-after="props.pageInfo.afterHide"
                    popper-class="domain-tip"
                    trigger-keys
                  >
                    <div class="domain-item">{{ item.label }}</div>
                  </el-tooltip>
                </el-option>
              </template>
            </el-select>
          </div>
          <!-- 登录按钮 -->
          <div class="login-input-footer">
            <el-button :id="'btLogin'" :type="'primary'" :disabled="isLogining" @click="login()">
              {{ $t('LOGIN_LABEL') }}
            </el-button>
            <div v-if="props.pageInfo.KerberosDomain !== undefined" class="others">
              {{ $t('LOGIN_OTHER_WAY') }}
              <span v-if="false" id="btSso" @click="ssoLogin()">{{ $t('LOGIN_SSO') }}</span>
            </div>
          </div>
        </div>

        <!-- 温馨提示修改密码 -->
        <SecurityTips
          v-if="pageState === 1"
          :locked="isLocked"
          :password="loginInfo.password"
          :expireDay="expireDay"
          @jump="goHome"
          @modify="jumpToModifyPwd()"
        />

        <!-- 修改密码 -->
        <ModifyPassword
          v-if="pageState === 2"
          :pwd-checked="isPwdChecked"
          :min-pwd-length="minPwdLength"
          :account="loginInfo.account"
          :first-login-policy="firstLoginPolicy"
          :password-expired="passwordExpired"
          @back="pageState = prevPageState"
        />

        <!-- 系统重启中 -->
        <div v-if="pageState === 3" class="login-twofac">
          <div class="login-state">
            <Loading :state="true" />
            <svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="gray-circle">
              <circle
                cx="40"
                cy="40"
                r="32"
                stroke="var(--o-border-color-base)"
                stroke-width="6"
                fill="none"
              />
            </svg>
          </div>
          <p class="login-state-text">{{ props.restartInfo?.errorMessage }}</p>
        </div>
      </div>

      <!-- 二维码 -->
      <div v-if="qrCodeShow" class="qr-code">
        <div class="qr-img">
          <img :src="qrCodeImg" alt="" @error="getDefaultQrCode" />
        </div>
        <div>{{ $t('LOGIN_SCAN_CODE') }}</div>
      </div>

      <!-- 双因素或SSO登录界面 -->
      <div v-if="loginType === 1 || loginType === 2" class="login-twofac">
        <div class="no-pwd-container">
          <div id="loadingState" class="login-state">
            <Loading :state="!props.complete" />
            <el-icon v-if="props.complete" class="login-error" :size="80"><IconError /></el-icon>
            <svg
              v-if="!props.complete"
              xmlns="http://www.w3.org/2000/svg"
              version="1.1"
              class="gray-circle"
            >
              <circle
                cx="40"
                cy="40"
                r="32"
                stroke="var(--o-border-color-base)"
                stroke-width="6"
                fill="none"
              />
            </svg>
          </div>
          <p class="login-state-text">{{ props.stateMessage }}</p>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import '../login.scss';
.login-twofac {
  margin-top: 80px;
}
.login-error {
  margin-top: 10px;
}
.login-state {
  position: relative;
  height: 100px;
  text-align: center;
}
p.login-state-text {
  text-align: center;
  font-size: 16px;
  color: var(--o-text-color-secondary);
  margin-top: 14px;
}
.gray-circle {
  position: absolute;
  left: 50%;
  top: 50%;
  width: 80px;
  height: 80px;
  margin-top: -40px;
  margin-left: -40px;
}
.qr-code {
  text-align: center;
  padding-top: 48px;
  .qr-img {
    display: inline-block;
    padding: 8px;
    background-color: #fff;
    img {
      display: block;
      width: 200px;
      height: 200px;
    }
  }

  div {
    margin-top: 24px;
    font-size: 16px;
    text-align: center;
  }
}

.pro-container {
  display: flex;
  align-items: center;
  .ico {
    flex-shrink: 0;
    width: 30px;
  }
  .logo {
    flex-shrink: 0;
    width: auto !important;
    img {
      display: block;
      max-width: 178px;
      max-height: 32px;
    }
  }
  .text {
    flex-shrink: 10;
    padding: 0 8px;
    width: 100%;
    p {
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      color: var(--o-text-color-secondary);
    }
  }
}

:deep(.loading) {
  .circular {
    width: 80px;
    height: 80px;
    margin-top: -40px;
    margin-left: -40px;
    .path {
      stroke-width: 4px;
    }
  }
}

#ulDomain{
  :deep(.el-select__wrapper){
    height: 48px;
    font-size: 16px !important;
  }
}
</style>
