<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"
      >
        <div v-if="systemIds.length === 2">
          <div class="inline-section">
            <div class="setup-content host1">
              <p class="host-name">{{ $t('HOME_HOST_0') }}</p>
              <el-form-item :label="$t('SERVICE_VMM_LABEL')" class="key-value-item host1">
                <el-switch
                  id="vmmEnable1"
                  v-model="form.vmmEnabbleState1"
                  :disabled="vmmEnableAuthority1"
                  @change="vmmEnabledChange"
                ></el-switch>
              </el-form-item>
              <el-form-item class="vmm-port" :label="$t('SERVICE_PORT')" prop="vmmPortValue1">
                <div class="vmm-port-row">
                  <el-popover
                    v-model:visible="popoverVisible1"
                    popper-class="no-wrap-popover"
                    placement="top"
                    :teleported="false"
                    trigger="focus"
                    trigger-keys
                  >
                    <span id="vmmPortInputTip1">
                      {{ traduction('VALID_VALUE_RANGE_TIP', [1, 65535]) }}
                    </span>
                    <template #reference>
                      <el-input
                        v-model="form.vmmPortValue1"
                        v-addId.input="'vmmPortId'"
                        v-clearable
                        :disabled="vmmPortIdAuthority1"
                        clearable
                        @focus="focus('vmmPortValue1')"
                        @blur="blur('vmmPortValue1')"
                        @input="vmmChangePort('vmmPortValue1', $event)"
                        @clear="clear('vmmPortValue1')"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                  <a
                    v-if="hasSecurityConfigPrivil && !systemLocked"
                    id="vmmResetPort1"
                    class="resetting"
                    @click.prevent="restFN('host1')"
                  >
                    {{ 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="vmmSession1">{{ form.vmmMaxSession1 }}</span>
              </el-form-item>
              <el-form-item
                :label="traduction('SERVICE_ACTIVE_SESSIONS')"
                size="default"
                class="key-value-item"
              >
                <span id="vmmActive1">{{ form.vmmActiveSession1 }}</span>
                <a
                  v-if="form.vmmActiveSession1 === 1 && hasVmmPrivil"
                  id="activeId1"
                  class="labelVmm"
                  @click="logoutFN('host1')"
                >
                  {{ traduction('SERVICE_VMM_LOGOUT_LABEL') }}
                </a>
              </el-form-item>
            </div>
            <div class="setup-content">
              <p class="host-name">{{ $t('HOME_HOST_1') }}</p>
              <el-form-item :label=" $t('SERVICE_VMM_LABEL')" class="key-value-item host2">
                <el-switch
                  id="vmmEnable2"
                  v-model="form.vmmEnabbleState2"
                  :disabled="vmmEnableAuthority2"
                  @change="vmmEnabledChange"
                ></el-switch>
              </el-form-item>
              <el-form-item class="vmm-port" :label="$t('SERVICE_PORT')" prop="vmmPortValue2">
                <div class="vmm-port-row">
                  <el-popover
                    v-model:visible="popoverVisible2"
                    popper-class="no-wrap-popover"
                    placement="top"
                    :teleported="false"
                    trigger="focus"
                    trigger-keys
                  >
                    <span id="vmmPortInputTip2">
                      {{ traduction('VALID_VALUE_RANGE_TIP', [1, 65535]) }}
                    </span>
                    <template #reference>
                      <el-input
                        v-model="form.vmmPortValue2"
                        v-addId.input="'vmmPortId'"
                        v-clearable
                        :disabled="vmmPortIdAuthority2"
                        clearable
                        @focus="focus('vmmPortValue2')"
                        @blur="blur('vmmPortValue2')"
                        @input="vmmChangePort('vmmPortValue2', $event)"
                        @clear="clear('vmmPortValue2')"
                      >
                        <template #suffix>
                          <ErrorIcon />
                          <ClearableIcon />
                        </template>
                      </el-input>
                    </template>
                  </el-popover>
                  <a
                    v-if="hasSecurityConfigPrivil && !systemLocked"
                    id="vmmResetPort2"
                    class="resetting"
                    @click.prevent="restFN('host2')"
                  >
                    {{ 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="vmmSession2">{{ form.vmmMaxSession2 }}</span>
              </el-form-item>
              <el-form-item
                :label="traduction('SERVICE_ACTIVE_SESSIONS')"
                size="default"
                class="key-value-item"
              >
                <span id="vmmActive2">{{ form.vmmActiveSession2 }}</span>
                <a
                  v-if="form.vmmActiveSession2 === 1 && hasVmmPrivil"
                  id="activeId2"
                  class="labelVmm"
                  @click="logoutFN('host2')"
                >
                  {{ traduction('SERVICE_VMM_LOGOUT_LABEL') }}
                </a>
              </el-form-item>
            </div>
          </div>
        </div>
        <!-- vmm使能 -->
        <el-form-item v-if="systemIds.length !== 2" :label="$t('SERVICE_VMM_LABEL')" class="key-value-item">
          <el-switch
            id="vmmEnable"
            v-model="form.vmmEnabbleState1"
            :disabled="vmmEnableAuthority1"
            @change="vmmEnabledChange"
          ></el-switch>
        </el-form-item>
        <!-- 端口 -->
        <el-form-item v-if="systemIds.length !== 2" class="vmm-port" :label="$t('SERVICE_PORT')" prop="vmmPortValue1">
          <div class="vmm-port-row">
            <el-popover
              v-model:visible="popoverVisible1"
              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.vmmPortValue1"
                  v-addId.input="'vmmPortId'"
                  v-clearable
                  :disabled="vmmPortIdAuthority1"
                  clearable
                  @focus="focus('vmmPortValue1')"
                  @blur="blur('vmmPortValue1')"
                  @input="vmmChangePort('vmmPortValue1', $event)"
                  @clear="clear('vmmPortValue1')"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
            <a
              v-if="hasSecurityConfigPrivil && !systemLocked"
              id="vmmResetPort"
              class="resetting"
              @click.prevent="restFN('host1')"
            >
              {{ traduction('SERVICE_DEFAULT_VALUE') }}
            </a>
          </div>
        </el-form-item>
        <!-- 最大会话 -->
        <el-form-item
          v-if="systemIds.length !== 2"
          :label="traduction('SERVICE_VNC_MAX_SESSION')"
          size="default"
          class="key-value-item"
        >
          <span id="vmmSession">{{ form.vmmMaxSession1 }}</span>
        </el-form-item>
        <!-- 活跃会话 -->
        <el-form-item
          v-if="systemIds.length !== 2"
          :label="traduction('SERVICE_ACTIVE_SESSIONS')"
          size="default"
          class="key-value-item"
        >
          <span id="vmmActive">{{ form.vmmActiveSession1 }}</span>
          <a
            v-if="form.vmmActiveSession1 === 1 && hasVmmPrivil"
            id="activeId"
            class="labelVmm"
            @click="logoutFN('host1')"
          >
            {{ 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, deepClone } 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';
import { getStoreData } from '@/utils/composition';
let virtualMediaConfig = ref(0);
const popoverVisible1 = ref(false);
const popoverVisible2 = 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 vmmEnableAuthority1 = ref(false);
const vmmEnableAuthority2 = ref(false);
const vmmPortIdAuthority1 = ref(false);
const vmmPortIdAuthority2 = ref(false);
const vmmEncryStateAuthority = ref(false);
const systemIds = computed(() => getStoreData('loct', 'systemIds'));
const form = reactive({
  vmmEnabbleState1: false,
  vmmEnabbleState2: false,
  vmmPortValue1: 0,
  vmmPortValue2: 0,
  systemId1: 0,
  systemId2: 0,
  vmmMaxSession1: 1,
  vmmMaxSession2: 1,
  vmmActiveSession1: 0,
  vmmActiveSession2: 0,
});
// 保存初始值
let oldData: any;
const rules = reactive({
  vmmPortValue1: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 1,
    max: 65535,
    message: traduction('SERVICE_PORT_RANGES'),
    validator: rangeVerification,
    trigger: 'blur',
  },
  vmmPortValue2: {
    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) => {
    virtualMediaConfig.value = rsp.data.VirtualMediaConfig.length;
    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 deepEqual(obj1: any, obj2: any) {
  // 获取对象的键
  const keys1 = Object.keys(obj1);
  const keys2 = Object.keys(obj2);
  // 如果键的数量不同，对象不同
  if (keys1.length !== keys2.length) {
    return false;
  }
  // 检查每个键值对
  for (let key of keys1) {
    const val1 = obj1[key];
    const val2 = obj2[key];
    // 如果值是对象，递归比较
    let flag = typeof val1 === 'object' && val1 !== null && typeof val2 === 'object' && val2 !== null;
    if (flag) {
      if (!deepEqual(val1, val2)) {
        return false;
      }
    } else if (val1 != val2) {
      return false;
    }
  }
  return true;
}
// 设置保存按钮状态&存储参数
function setSaveBtnState() {
  queryParams = {};
  for (let key in validateResult) {
    // 任意一个校验失败
    if (!validateResult[key]) {
      buttonDisabled.value = true;
      return;
    }
  }
  const compareRes = deepEqual(form,oldData);
  // 校验成功后，进行初始值和修改值的对比，看是否发生修改
  let flag = false;
  if (virtualMediaConfig.value !== 2) {
    flag = form.vmmEnabbleState1 !== tempData.VirtualMediaConfig[0].Enabled || form.vmmPortValue1 !== tempData.VirtualMediaConfig[0].Port.toString();
  } else {
    flag = form.vmmEnabbleState1 !== tempData.VirtualMediaConfig[0].Enabled || form.vmmPortValue1 !== tempData.VirtualMediaConfig[0].Port.toString() || form.vmmEnabbleState2 !== tempData.VirtualMediaConfig[1].Enabled || form.vmmPortValue2 !== tempData.VirtualMediaConfig[1].Port.toString();
  }
  if (flag) {
    if (virtualMediaConfig.value !== 2) {
      queryParams['VirtualMediaConfig'] = [
        {
          Enabled: form.vmmEnabbleState1,
          Port: getPort(form.vmmPortValue1),
          SystemId: form.systemId1,
        },
      ];
    } else {
      queryParams['VirtualMediaConfig'] = [
        {
          Enabled: form.vmmEnabbleState1,
          Port: getPort(form.vmmPortValue1),
          SystemId: form.systemId1,
        },
        {
          Enabled: form.vmmEnabbleState2,
          Port: getPort(form.vmmPortValue2),
          SystemId: form.systemId2,
        },
      ];
    }
  }
  buttonDisabled.value = JSON.stringify(queryParams) === '{}' || compareRes;
}

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

  nextTick(() => {
    setSaveBtnState();
  });
}
function restFN(host: string) {
  if (host === 'host1') {
    form.vmmPortValue1 = 8208;
    vmmForm.value.validateField('vmmPortValue1');
  } else {
    form.vmmPortValue2 = 8308;
    vmmForm.value.validateField('vmmPortValue2');
  }
}

function logoutFN(type: string) {
  getVmmActiveSession(type)
    .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;
  VirtualMediaConfig: any;
}
function initData(vmmData1: vmmData) {
  if (virtualMediaConfig.value !== 2) {
    form.vmmEnabbleState1 = vmmData1.VirtualMediaConfig[0].Enabled;
    form.vmmPortValue1 = vmmData1.VirtualMediaConfig[0].Port;
    form.systemId1 = vmmData1.VirtualMediaConfig[0].SystemId;
    form.vmmMaxSession1 = vmmData1.VirtualMediaConfig[0].MaximumNumberOfSessions;
    form.vmmActiveSession1 = vmmData1.VirtualMediaConfig[0].NumberOfActiveSessions;
  } else {
    form.vmmEnabbleState1 = vmmData1.VirtualMediaConfig[0].Enabled;
    form.vmmEnabbleState2 = vmmData1.VirtualMediaConfig[1].Enabled;
    form.vmmPortValue1 = vmmData1.VirtualMediaConfig[0].Port;
    form.vmmPortValue2 = vmmData1.VirtualMediaConfig[1].Port;
    form.systemId1 = vmmData1.VirtualMediaConfig[0].SystemId;
    form.systemId2 = vmmData1.VirtualMediaConfig[1].SystemId;
    form.vmmMaxSession1 = vmmData1.VirtualMediaConfig[0].MaximumNumberOfSessions;
    form.vmmMaxSession2 = vmmData1.VirtualMediaConfig[1].MaximumNumberOfSessions;
    form.vmmActiveSession1 = vmmData1.VirtualMediaConfig[0].NumberOfActiveSessions;
    form.vmmActiveSession2 = vmmData1.VirtualMediaConfig[1].NumberOfActiveSessions;
  }
  tempData = { ...vmmData1 };
  // 复制初始数据用于比较
  oldData = deepClone(form);
  buttonDisabled.value = true;
  vmnAuthority();
}
function vmnAuthority() {
  // 权限控制具有安全配置权限可以设置vmm使能、端口
  if (hasSecurityConfigPrivil && !systemLocked.value) {
    vmmEnableAuthority1.value = false;
    vmmEnableAuthority2.value = false;
    vmmPortIdAuthority1.value = false;
    vmmPortIdAuthority2.value = false;
  } else {
    vmmEnableAuthority1.value = true;
    vmmEnableAuthority2.value = true;
    vmmPortIdAuthority1.value = true;
    vmmPortIdAuthority2.value = true;
  }
  // 具有远程媒体权限可以设置通信加密、注销会话
  if (hasVmmPrivil && !systemLocked.value) {
    vmmEncryStateAuthority.value = false;
  } else {
    vmmEncryStateAuthority.value = true;
  }
  loading(false);
}
function focus(key: string) {
  if (key === 'vmmPortValue1') {
    popoverVisible1.value = true;
  } else {
    popoverVisible2.value = true;
  }
}

function blur(key: string) {
  if (key === 'vmmPortValue1') {
    popoverVisible1.value = false;
  } else {
    popoverVisible2.value = false;
  }
}

function clear(key: string) {
  // 如果没有focus，那么这个地方需要手动调用一次校验
  if (key === 'vmmPortValue1') {
    if (!popoverVisible1.value) {
      vmmForm.value.validateField(key);
    }
  } else {
    if (!popoverVisible2.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, #vmmResetPort1, #vmmResetPort2 {
      margin-left: 8px;
      cursor: pointer;
      color: var(--o-color-primary);
    }
    #activeId, #activeId1, #activeId2 {
      margin-left: 16px;
    }
    #encryptionAlert {
      margin-left: 8px;
      color: var(--o-color-major);
      vertical-align: middle;
    }
    .inline-section {
      display: flex;
      flex-wrap: wrap;
      align-items: flex-start;
      margin: 16px 0 24px 0;
      .setup-content {
        flex: 1;
        width: 50%;
        padding: 16px;
        border-radius: 4px;
        background: #f4f6fa;
        &.host1 {
          margin-right: 16px;
        }
        .host-name {
          font-size: 14px;
          color: #000000;
          font-weight: 500;
          line-height: 22px;
          margin-bottom: 16px;
        }
      }
    }

    :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, #activeId1, #activeId2 {
  color: var(--o-color-primary);
  cursor: pointer;
  &:hover {
    color: var(--o-color-primary-secondary);
  }
}
</style>
