<script lang="ts" setup>
import { reactive, ref, watch, nextTick, computed } from 'vue';
import { reqPath } from '@/api/reqPath';
import $http from '@/utils/http-service';
import { showElMessage, deepClone, compareObjectEqual } from '@/utils/utils';
import { traduction } from '@/utils/language';
import GlobalStoreService from '@/services/gloabal-store-service';
import { rangeVerification } from '@/validators/validation-functions';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';

const globalStoreService = new GlobalStoreService();

const props = defineProps({
  data: {
    type: Object,
    default: () => {
      return {};
    },
    required: true,
  },
  lock: {
    type: Boolean,
    default: false,
    required: false,
  },
  permission: {
    type: Boolean,
    default: false,
    required: false,
  },
});
const emits = defineEmits(['initShowData']);
// 保存按钮的状态值
let saveBtnStateLock = ref(false);

const disabledState = computed(() => {
  return props.lock || !props.permission;
});

const popoverVisible = reactive({
  txDelaySeconds: false,
  txIntervalSeconds: false,
  txHold: false,
});
const ruleFormRef = ref();

// 记录原始数据
let preLldpData: any = {};

// 工作模式字段
let lldpWorkModelStr = ref('');

// 展示数据
let netLldpForm: any = reactive({});

// 记录校验结果
let validateResult: any = {};

// 记录最终保存数据,保存按钮需要传的参数
let queryParams: any = {};

// 端口校验规则 1.必填 2.数字 3.整型 4.范围1-4094
let rules = reactive({
  txDelaySeconds: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 1,
    max: 8192,
    message: traduction('VALID_VALUE_RANGE_TIP', [1, 8192]),
    validator: rangeVerification,
    trigger: 'blur',
  },
  txIntervalSeconds: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 5,
    max: 32768,
    message: traduction('VALID_VALUE_RANGE_TIP', [5, 32768]),
    validator: rangeVerification,
    trigger: 'blur',
  },
  txHold: {
    type: 'number',
    required: true,
    isInteger: true,
    min: 2,
    max: 10,
    message: traduction('VALID_VALUE_RANGE_TIP', [2, 10]),
    validator: rangeVerification,
    trigger: 'blur',
  },
});
watch(
  () => props.data,
  (val: any) => {
    lldpInit(val);
  },
  { deep: true },
);

// 数据初始化
function lldpInit(lldpData: any) {
  if (lldpData.txDelaySeconds || lldpData.txDelaySeconds === 0) {
    lldpData.txDelaySeconds = lldpData.txDelaySeconds.toString();
  }

  if (lldpData.txHold || lldpData.txHold === 0) {
    lldpData.txHold = lldpData.txHold.toString();
  }

  if (lldpData.txIntervalSeconds || lldpData.txIntervalSeconds === 0) {
    lldpData.txIntervalSeconds = lldpData.txIntervalSeconds.toString();
  }

  const valueList = {
    Tx: traduction('IBMC_LLDP_TX_1'),
    RX: traduction('IBMC_LLDP_TX_2'),
    TxRx: traduction('IBMC_LLDP_TX_3'),
    Disabled: traduction('IBMC_LLDP_TX_0'),
  };
  // 保存原始数据
  preLldpData = deepClone(lldpData);

  // 初始化展示数据
  Object.assign(netLldpForm, deepClone(lldpData));
  // 工作模式字段显示值
  lldpWorkModelStr.value = valueList[netLldpForm.lldpWorkMode];
  saveBtnStateLock.value = true;
}

// lldp开关
function lldpEnableChange(value: any) {
  setsaveBtnStateLock();
}

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

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

// 设置保存按钮状态
function setsaveBtnStateLock() {
  for (let key in validateResult) {
    // 任意一个校验失败
    if (!validateResult[key]) {
      saveBtnStateLock.value = true;
      return;
    }
  }
  // 校验成功后，进行初始值和修改值的对比，看是否发生修改,从而判断提交按钮的锁定状态
  saveBtnStateLock.value = compareObjectEqual(preLldpData, netLldpForm);
}

// 保存
function lldpButton() {
  queryParams = { LLDP: {} };
  checkDataState();
  $http
    .patch(reqPath.manager.networkSettings, queryParams)
    .then((res: any) => {
      emits('initShowData', res.data);
      showElMessage('success', traduction('COMMON_SUCCESS'));
      saveBtnStateLock.value = true;
    })
    .catch(err => {
      showElMessage('error', traduction('COMMON_FAILED'));
    });
}

// 数据是否发生变化,入参赋值
function checkDataState() {
  if (preLldpData.lldpEnabled !== netLldpForm.lldpEnabled) {
    queryParams.LLDP['Enabled'] = netLldpForm.lldpEnabled;
  }
  if (preLldpData.txDelaySeconds !== netLldpForm.txDelaySeconds) {
    queryParams.LLDP['TxDelaySeconds'] = Number(netLldpForm.txDelaySeconds);
  }
  if (preLldpData.txIntervalSeconds !== netLldpForm.txIntervalSeconds) {
    queryParams.LLDP['TxIntervalSeconds'] = Number(netLldpForm.txIntervalSeconds);
  }
  if (preLldpData.txHold !== netLldpForm.txHold) {
    queryParams.LLDP['TxHold'] = Number(netLldpForm.txHold);
  }
}

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

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

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

lldpInit(props.data);
</script>

<template>
  <!-- LLDP -->
  <div id="netwotkLldp" class="box">
    <div class="part-title">{{ $t('IBMC_LLDP') }}</div>
    <el-form 
      ref="ruleFormRef" 
      :model="netLldpForm"
      :rules="rules"
      label-position="left"
      label-width="auto"
      :validate-on-rule-change="false"
      @validate="validate"
    >
      <!-- LLDP使能 -->
      <el-form-item :label="$t('IBMC_LLDP_FUNCTION')" class="switch-item network-page-label">
        <el-switch
          id="lldpEnable"
          v-model="netLldpForm.lldpEnabled"
          :disabled="disabledState"
          @change="lldpEnableChange"
        ></el-switch>
      </el-form-item>

      <!-- 工作模式 -->
      <el-form-item :label="$t('COMMON_WORKING_MODE')" class="switch-item network-page-label">
        <span id="lldpWork">{{ lldpWorkModelStr }}</span>
      </el-form-item>

      <!-- 发送延迟 -->
      <el-form-item :label="$t('IBMC_LLDP_SEND_DELAY')" prop="txDelaySeconds" class="network-page-label">
        <el-popover
          v-model:visible="popoverVisible.txDelaySeconds"
          popper-class="no-wrap-popover"
          placement="right"
          :teleported="false"
          :content="traduction('VALID_VALUE_RANGE_TIP', [1, 8192])"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="netLldpForm.txDelaySeconds"
              v-addId.input="'txDelaySeconds'"
              v-clearable
              clearable
              :disabled="disabledState"
              type="text"
              @focus="focus('txDelaySeconds')"
              @blur="blur('txDelaySeconds')"
              @input="input('txDelaySeconds', $event)"
              @clear="clear('txDelaySeconds')"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>

      <!-- 发送周期 -->
      <el-form-item :label="$t('IBMC_LLDP_SEND_PERIOD')" prop="txIntervalSeconds" class="network-page-label">
        <el-popover
          v-model:visible="popoverVisible.txIntervalSeconds"
          popper-class="no-wrap-popover"
          placement="right"
          :teleported="false"
          :content="traduction('VALID_VALUE_RANGE_TIP', [5, 32768])"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="netLldpForm.txIntervalSeconds"
              v-addId.input="'txIntervalSeconds'"
              v-clearable
              clearable
              :disabled="disabledState"
              type="text"
              @focus="focus('txIntervalSeconds')"
              @blur="blur('txIntervalSeconds')"
              @input="input('txIntervalSeconds', $event)"
              @clear="clear('txIntervalSeconds')"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>

      <!-- 邻居节点时间保持倍数 -->
      <el-form-item :label="$t('IBMC_LLDP_KEEP_MUTIPLY')" prop="txHold" class="network-page-label">
        <el-popover
          v-model:visible="popoverVisible.txHold"
          popper-class="no-wrap-popover"
          placement="right"
          :teleported="false"
          :content="traduction('VALID_VALUE_RANGE_TIP', [2, 10])"
          trigger="focus"
          trigger-keys
        >
          <template #reference>
            <el-input
              v-model="netLldpForm.txHold"
              v-addId.input="'txHold'"
              v-clearable
              clearable
              :disabled="disabledState"
              type="text"
              @focus="focus('txHold')"
              @blur="blur('txHold')"
              @input="input('txHold', $event)"
              @clear="clear('txHold')"
            >
              <template #suffix>
                <ErrorIcon />
                <ClearableIcon />
              </template>
            </el-input>
          </template>
        </el-popover>
      </el-form-item>
      <el-form-item class="button-class network-page-label">
        <el-button
          v-if="permission"
          id="lldpButton"
          :disabled="saveBtnStateLock"
          type="primary"
          @click="lldpButton"
        >
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </el-form-item>
    </el-form>
  </div>
</template>

<style lang="scss" scoped>
#netwotkLldp {
  margin-top: 8px;
  padding: 24px;
  background-color: var(--o-bg-color-base);
  border-radius: 4px;
  :deep(.have-right-text-item) {
    .el-form-item__content {
      display: flex;
      align-items: center;
    }
  }
  :deep(.el-form-item__label) {
    text-align: left;
  }
  :deep(.el-form-item__content) {
    margin-left: 18px !important;
  }
  :deep(.el-input) {
    width: 320px;
  }

  .part-title {
    font-size: 16px;
    font-weight: bold;
    color: var(--o-text-color-primary);
    line-height: 24px;
    margin-bottom: 16px;
  }

  :deep(.el-form) {
    .el-form-item {
      margin-bottom: 24px;
    }

    .button-class {
      margin-bottom: 0;
    }

    .switch-item {
      height: 16px;
      .el-form-item__label-wrap {
        .el-form-item__label {
          padding: 0 24px 0 0;
        }
      }

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

  :deep(.el-dialog) {
    width: 432px;

    .content {
      display: flex;
      align-items: center;

      .el-icon {
        margin-right: 16px;
        font-size: 28px;
      }
    }
  }
  :deep(.el-form-item.is-required):not(.is-no-asterisk)>.el-form-item__label-wrap>.el-form-item__label:before{
    display: none;
  }
}
</style>
