<template>
  <!-- 提示安全增强 -->
  <div id="vmmView">
    <div class="vmm-content">
      <el-form
        ref="vmmForm"
        :model="form"
        :rules="rules"
        label-width="auto"
        :inline="false"
        size="default"
        label-position="left"
        @validate="validate"
      >
        <!-- vmm使能 -->
        <el-form-item :label="traduction('SERVICE_VMM_LABEL')" class="key-value-item">
          <el-switch
            id="vmmEnable"
            v-model="form.vmmEnabbleState"
            :disabled="vmmEnableAuthority"
            @change="vmmEnabledChange"
          ></el-switch>
        </el-form-item>
        <!-- 端口 -->
        <el-form-item class="vmm-port" :label="traduction('SERVICE_PORT')" prop="vmmPortValue">
          <div class="vmm-port-row">
            <el-popover
              v-model:visible="popoverVisible"
              popper-class="no-wrap-popover"
              placement="top"
              :teleported="false"
              trigger="focus"
              trigger-keys
            >
              <span id="vmmPortInputTip">
                {{ traduction('VALID_VALUE_RANGE_TIP', [1, 65535]) }}
              </span>
              <template #reference>
                <el-input
                  v-model="form.vmmPortValue"
                  v-addId.input="'vmmPortId'"
                  v-clearable
                  :disabled="vmmPortIdAuthority"
                  clearable
                  @focus="focus()"
                  @blur="blur()"
                  @input="vmmChangePort('vmmPortValue', $event)"
                  @clear="clear('vmmPortValue')"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
            <a
              v-if="hasSecurityConfigPrivil && !systemLocked"
              id="vmmResetPort"
              class="resetting"
              @click.prevent="restFN()"
            >
              {{ traduction('SERVICE_DEFAULT_VALUE') }}
            </a>
          </div>
        </el-form-item>
        <!-- 最大会话 -->
        <el-form-item
          :label="traduction('SERVICE_VNC_MAX_SESSION')"
          size="default"
          class="key-value-item"
        >
          <span id="vmmSession">{{ form.vmmMaxSession }}</span>
        </el-form-item>
        <!-- 活跃会话 -->
        <el-form-item
          :label="traduction('SERVICE_ACTIVE_SESSIONS')"
          size="default"
          class="key-value-item"
        >
          <span id="vmmActive">{{ form.vmmActiveSession }}</span>
          <a
            v-if="form.vmmActiveSession === 1 && hasVmmPrivil"
            id="activeId"
            class="labelVmm"
            @click="logoutFN()"
          >
            {{ traduction('SERVICE_VMM_LOGOUT_LABEL') }}
          </a>
        </el-form-item>
        <el-form-item class="save-item" label=" ">
          <el-button
            v-if="hasSecurityConfigPrivil || hasVmmPrivil"
            id="vmmButton"
            type="primary"
            :disabled="buttonDisabled"
            @click="onSubmit"
          >
            {{ traduction('COMMON_SAVE') }}
          </el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, nextTick, computed, onUnmounted } from 'vue';
import useStore from '@/stores';
import { traduction } from '@/utils/language';
import { getVmm, getVmmActiveSession, queryTask, setVmmService } from './vmm.services';
import { getMessageId } from '@/utils/utils';
import { rangeVerification } from '@/validators/validation-functions';
import { loading, showFailedMessage, showSuccessMessage } from '@/utils/composition';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';

import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';

const popoverVisible = ref(false);
const vmmForm = ref();
const store = useStore();
let timeout = null as any;
let systemLocked = computed(() => {
  return store.state.glob.systemLocked;
});

const hasSecurityConfigPrivil = checkPrivil(UserPrivil.securityConfig);
const hasVmmPrivil = checkPrivil(UserPrivil.vmm);

const vmmEnableAuthority = ref(false);
const vmmPortIdAuthority = ref(false);
const vmmEncryStateAuthority = ref(false);

const form = reactive({
  vmmEnabbleState: false,
  vmmPortValue: 0,
  vmmMaxSession: 1,
  vmmActiveSession: 0,
});
const rules = reactive({
  vmmPortValue: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 1,
    max: 65535,
    message: traduction('SERVICE_PORT_RANGES'),
    validator: rangeVerification,
    trigger: 'blur',
  },
});
// 保存按钮状态
const buttonDisabled = ref(true);
// 保存原始数据
let tempData: vmmData;
// 表单校验结果
let validateResult = {};
// 存储参数
let queryParams = {};

onMounted(() => {
  loading(true);
  getVmm().then((rsp: any) => {
    initData(rsp.data);
  });
});

function validate(key: string, state: boolean) {
  validateResult[key] = state;
  nextTick(() => {
    setSaveBtnState();
  });
}
function getPort(port: string | number): number | null {
  if (port === '') {
    return null;
  }
  if (typeof port === 'number') {
    return port;
  }
  return parseInt(port, 10);
}
// 设置保存按钮状态&存储参数
function setSaveBtnState() {
  queryParams = {};
  for (let key in validateResult) {
    // 任意一个校验失败
    if (!validateResult[key]) {
      buttonDisabled.value = true;
      return;
    }
  }
  // 校验成功后，进行初始值和修改值的对比，看是否发生修改
  if (form.vmmEnabbleState !== tempData.Enabled) {
    queryParams['Enabled'] = form.vmmEnabbleState;
  }
  if (form.vmmPortValue !== tempData.Port) {
    queryParams['Port'] = getPort(form.vmmPortValue);
  }
  buttonDisabled.value = JSON.stringify(queryParams) === '{}';
}

function vmmEnabledChange() {
  setSaveBtnState();
}
function vmmChangePort(key: string, value: number) {
  form.vmmPortValue = value;
  // 调用校验方法校验数据是否能通过，因为当前校验方式是blur，在input事件触发时不会触发校验，
  // 但是为了在输入的时候控制保存按钮的状态，需要手动去触发校验函数获取校验结果，进而控制保存按钮状态
  validateResult[key] = rules[key].validator(rules[key], form.vmmPortValue, () => {});

  nextTick(() => {
    setSaveBtnState();
  });
}
function restFN() {
  form.vmmPortValue = 8208;
  vmmForm.value.validateField('vmmPortValue');
}

function logoutFN() {
  getVmmActiveSession()
    .then(res => {
      if (res.data !== undefined && res.data !== null) {
        taskFn(res.data.url);
      }
    })
    .catch(error => {
      const errors = getMessageId(error.data);
      const errorMessage = 'COMMON_FAILED';
      store.state.event.setEventState({
        type: 'alertMessage',
        value: { type: 'error', message: errorMessage },
      });
    });
}
function taskFn(url: string) {
  queryTask(url).then(
    (res: any) => {
      const taskData = res.data;
      if (taskData !== undefined) {
        if (taskData.state === 'Completed') {
          store.state.event.setEventState({
            type: 'alertMessage',
            value: { type: 'success', message: traduction('SERVICE_DELETE_SESSION_SUCCESS') },
          });
          getVmm().then((rsp: any) => {
            initData(rsp.data);
          });
        } else {
          timeout = setTimeout(() => {
            taskFn(url);
          }, 3000);
        }
      }
    },
    error => {
      store.state.event.setEventState({
        type: 'alertMessage',
        value: { type: 'error', message: traduction(traduction('COMMON_FAILED')) },
      });
    },
  );
}
function onSubmit() {
  loading(true);
  setVmmService(queryParams)
    .then((res: any) => {
      showSuccessMessage();
      initData(res.data);
    })
    .catch(error => {
      loading(false);
      const errorCode = error.data.error[0].code;
      showFailedMessage(traduction(errorCode + '.errorMessage'));
    });
}
interface vmmData {
  Enabled: boolean;
  EncryptionConfigurable: boolean;
  EncryptionEnabled: boolean;
  MaximumNumberOfSessions: number;
  NumberOfActiveSessions: number;
  Port: number;
}
function initData(vmmData1: vmmData) {
  form.vmmEnabbleState = vmmData1.Enabled;
  form.vmmPortValue = vmmData1.Port;
  form.vmmMaxSession = vmmData1.MaximumNumberOfSessions;
  form.vmmActiveSession = vmmData1.NumberOfActiveSessions;
  tempData = { ...vmmData1 };
  buttonDisabled.value = true;
  vmnAuthority();
}
function vmnAuthority() {
  // 权限控制具有安全配置权限可以设置vmm使能、端口
  if (hasSecurityConfigPrivil && !systemLocked.value) {
    vmmEnableAuthority.value = false;
    vmmPortIdAuthority.value = false;
  } else {
    vmmEnableAuthority.value = true;
    vmmPortIdAuthority.value = true;
  }
  // 具有远程媒体权限可以设置通信加密、注销会话
  if (hasVmmPrivil && !systemLocked.value) {
    vmmEncryStateAuthority.value = false;
  } else {
    vmmEncryStateAuthority.value = true;
  }
  loading(false);
}
function focus() {
  popoverVisible.value = true;
}

function blur() {
  popoverVisible.value = false;
}

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

onUnmounted(() => {
  if (timeout !== null) {
    clearTimeout(timeout);
  }
});
</script>

<style lang="scss" scoped>
#vmmView {
  .vmm-content {
    background-color: var(--o-bg-color-base);
    border-radius: 4px;
    padding: 24px;
    .vmm-port .el-input {
      width: 320px;
    }
    #vmmResetPort {
      margin-left: 8px;
      cursor: pointer;
      color: var(--o-color-primary);
    }
    #activeId {
      margin-left: 16px;
    }
    #encryptionAlert {
      margin-left: 8px;
      color: var(--o-color-major);
      vertical-align: middle;
    }

    :deep(.el-form-item .el-form-item__label::before) {
      display: none;
    }

    :deep(.key-value-item) {
      height: 16px;
      .el-form-item__label {
        padding-top: 0;
        padding-bottom: 0;
      }
    }

    :deep(.save-item) {
      margin-bottom: 0;
    }
  }
  .vmm-port-row {
    display: flex;
    align-items: center;
  }
}
#lock {
  margin-right: 0;
}
#activeId {
  color: var(--o-color-primary);
  cursor: pointer;
  &:hover {
    color: var(--o-color-primary-secondary);
  }
}
</style>
