<template>
  <div id="trapComponent" class="trap-component">
    <div class="trap-top">
      <h3 class="top-title">{{ traduction('ALARM_REPORT_TRAP_FUNC') }}</h3>
      <el-form
        ref="trpRef"
        :model="formTrapRule"
        :rules="rules"
        label-width="auto"
        label-position="left"
        :validate-on-rule-change="false"
        @validate="validate"
      >
        <!-- trp使能 -->
        <el-form-item
          id="trapState"
          :label="traduction('ALARM_REPORT_TRAP_ENABLE')"
          class="small-item"
        >
          <el-switch
            id="trap"
            v-model="formTrap.trap.state"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            @change="formTrap.trap.change"
          ></el-switch>
        </el-form-item>
        <!-- trp版本 -->
        <el-form-item id="trapVersionItem" :label="traduction('ALARM_REPORT_TRAP_VERSION')">
          <el-select
            v-model="formTrap.trapVersion.value"
            v-addId.select="'trapVersion'"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :teleported="false"
            :suffix-icon="PullDownTriangle"
            @change="formTrap.trapVersion.change"
          >
            <el-option
              v-for="item in formTrap.trapVersion.list"
              :key="item.id"
              :label="item.key"
              :value="item.id"
            ></el-option>
          </el-select>
          <span v-if="formTrap.trapVersion.value !== 'SNMPv3'" id="trapVersionTip">
            {{ traduction('SERVICE_REDUCE_SECURITY') }}
          </span>
        </el-form-item>
        <!-- trp模式 -->
        <el-form-item id="trapMode" :label="traduction('ALARM_REPORT_TRAP_MODE')">
          <el-select
            v-model="formTrap.trapMode.value"
            v-addId.select="'trapMode'"
            :teleported="false"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :suffix-icon="PullDownTriangle"
            @change="formTrap.trapMode.change"
          >
            <el-option
              v-for="item in formTrap.trapMode.list"
              :key="item.id"
              :label="item.key"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- 选择V3用户 -->
        <el-form-item v-show="v3Show" id="v3UserItem" :label="traduction('TRAP_SELECT_V3_USER')">
          <el-select
            v-model="formTrap.v3User.value"
            v-addId.select="'v3User'"
            :teleported="false"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :suffix-icon="PullDownTriangle"
            @change="formTrap.v3User.change"
          >
            <el-option
              v-for="item in formTrap.v3User.list"
              :key="item.id"
              :label="item.key"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- Trap主机标识 -->
        <el-form-item id="trapDomainItem" :label="traduction('ALARM_REPORT_TRAP_DOMIN')">
          <el-select
            v-model="formTrap.trapDomain.value"
            v-addId.select="'trapDomain'"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :teleported="false"
            :suffix-icon="PullDownTriangle"
            @change="formTrap.trapDomain.change"
          >
            <el-option
              v-for="item in formTrap.trapDomain.list"
              :key="item.id"
              :label="item.key"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- 团体名 -->
        <el-form-item
          v-show="groupShow"
          id="trapGroupItem"
          :label="traduction('ALARM_REPORT_TRAP_TEAM_NAME')"
          prop="group"
        >
          <el-popover
            v-model:visible="popoverVisible.group"
            popper-class="no-wrap-popover"
            :placement="'right-start'"
            trigger="focus"
            trigger-keys
          >
            <span v-if="!pwdCheck">{{ traduction('TRAP_COMMUNITY_NAME_TIPS') }}</span>
            <ComplexPopoverContentOfList v-if="pwdCheck" :data="rules.group['verificationList']" />
            <template #reference>
              <el-input
                v-model="formTrapRule.group"
                v-addId.input="'group'"
                v-clearable
                clearable
                type="password"
                autocomplete="new-password"
                maxlength="32"
                :disabled="isSystemLock || !hasBaseConfigPrivil"
                :show-password="isConfigureUser"
                @focus="focus('group')"
                @blur="blur('group')"
                @input="input('group', $event)"
                @clear="clear('group')"
              >
                <template #suffix>
                  <ErrorIcon />
                  <ClearableIcon />
                </template>
              </el-input>
            </template>
          </el-popover>
        </el-form-item>
        <!-- 确认团体名 -->
        <el-form-item
          v-show="groupShow"
          id="trapConfirmGroupItem"
          :label="traduction('ALARM_REPORT_TRAP_TEMA_RENAME')"
          prop="confirmGroupName"
        >
          <el-input
            v-model="formTrapRule.confirmGroupName"
            v-addId.input="'confirmGroupName'"
            v-clearable
            clearable
            type="password"
            autocomplete="new-password"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :show-password="isConfigureUser"
            @focus="focus('confirmGroupName')"
            @blur="blur('confirmGroupName')"
            @input="input('confirmGroupName', $event)"
            @clear="clear('confirmGroupName')"
          >
            <template #suffix>
              <ErrorIcon />
              <ClearableIcon />
            </template>
          </el-input>
        </el-form-item>
        <el-form-item id="sendEmailLevelItem" :label="traduction('ALARM_REPORT_EMAIL_ALARM_LEVEL')">
          <el-select
            v-model="formTrap.sendEmailLevel.value"
            v-addId.select="'sendEmailLevel'"
            :teleported="false"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            :suffix-icon="PullDownTriangle"
            @change="formTrap.sendEmailLevel.change"
          >
            <el-option
              v-for="item in formTrap.sendEmailLevel.list"
              :key="item.id"
              :label="item.label"
              :value="item.id"
            ></el-option>
          </el-select>
        </el-form-item>
        <!-- 告警类型 -->
        <el-form-item
          id="trapAlarmType"
          :label="$t('ALARM_REPORT_SYSLOG_ALARM_TYPE')"
          class="small-item"
        >
          <el-radio-group
            v-model="formTrap.alarmType.value"
            :disabled="isSystemLock || !hasBaseConfigPrivil"
            @change="formTrap.alarmType.change"
          >
            <el-radio
              v-for="item in formTrap.alarmType.list"
              :id="'trap' + item.id"
              :key="item.id"
              :label="item.id"
            >
              {{ $t(item.key) }}
            </el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item class="trap-btns">
          <el-button
            v-if="hasBaseConfigPrivil"
            id="trapSaveBtn"
            type="primary"
            :disabled="btnSaveState || isSystemLock"
            @click="btnSave"
          >
            {{ traduction('COMMON_SAVE') }}
          </el-button>
          <el-button v-show="!btnSaveState" id="trapCancelBtn" @click="trapCancelFun">
            {{ $t('COMMON_CANCEL') }}
          </el-button>
        </el-form-item>
      </el-form>
    </div>
    <div id="trapTableBox" class="trap-table">
      <h3 class="table-title">{{ $t('TRAP_SET_SERVICE_LABEL') }}</h3>
      <TrapTable
        ref="trapTableRef"
        :data="srcData.data"
        :is-i-r-m210="isIRM210"
        :render-data="renderData.data"
        :btn-save-state="btnSaveState"
        :is-system-lock="isSystemLock"
        :has-permission="hasBaseConfigPrivil"
        @operate-change="tableChange"
      ></TrapTable>
    </div>
  </div>
</template>

<script lang="ts" setup>
import { traduction } from '@/utils/language';
import { alertMessage, getPwdCode, getTrapInfoFun, trapSave } from '../report.service';
import { ref, reactive, onMounted, computed, nextTick } from 'vue';
import TrapTable from './TrapTable.vue';
import useStore from '@/stores';
import { loading } from '@/utils/composition';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import ComplexPopoverContentOfList from '@/components/ComplexPopoverContent/ComplexPopoverContentOfList.vue';
import { initRules } from '../trap-rules';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import PullDownTriangle from '@/components/PullDownTriangle/PullDownTriangle.vue';

const pwdCheck = ref(false);

const store = useStore();
let isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const trpRef = ref();
const trapTableRef = ref();

const hasBaseConfigPrivil = checkPrivil(UserPrivil.baseConfig);
const isConfigureUser = checkPrivil(UserPrivil.userConfig);
const popoverVisible = reactive({
  group: false,
  confirmGroupName: false,
});
const formTrapRule = reactive({
  group: '' as any,
  confirmGroupName: '' as any,
});
const rules = reactive({
  group: initRules(true),
  confirmGroupName: {
    trigger: 'change',
    type: 'text',
    message: traduction('TRAP_GROUP_NOEQUAL'),
    validator: (rule: any, value: any, callback: (error?: Error) => void) => {
      if (value !== formTrapRule.group) {
        callback(new Error(traduction('TRAP_GROUP_NOEQUAL')));
        return;
      }
      callback();
    },
  },
});
// 表单校验结果
let validateResult = {};
// 表单校验发生时 - 控制保存按钮状态 state:校验结果
function validate(key: string, state: boolean) {
  validateResult[key] = state;
  nextTick(() => {
    changeBtnState();
  });
}

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

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

function clear(key: string) {
  // 如果没有focus，那么这个地方需要手动调用一次校验
  if (!popoverVisible[key]) {
    trpRef.value.validateField(key);
  }
}
const formTrap = reactive({
  trap: {
    state: false,
    change: () => {
      changeBtnState();
    },
  },
  trapVersion: {
    value: 'SNMPv1',
    list: [
      {
        id: 'SNMPv1',
        key: traduction('TRAP_SNMP_V1'),
      },
      {
        id: 'SNMPv2c',
        key: traduction('TRAP_SNMP_V2'),
      },
      {
        id: 'SNMPv3',
        key: traduction('TRAP_SNMP_V3'),
      },
    ],
    change: (sel: string) => {
      if (sel === 'SNMPv3') {
        groupShow.value = false;
        v3Show.value = true;
        formTrap.group.value = '';
        formTrap.confirmGroupName.value = '';
      } else {
        groupShow.value = true;
        v3Show.value = false;
      }
      changeBtnState();
    },
  },
  trapMode: {
    value: 'OID',
    list: [
      {
        id: 'OID',
        key: traduction('TRAP_OID_MODE'),
      },
      {
        id: 'PreciseAlarm',
        key: traduction('TRAP_PRECISE_ALARM'),
      },
    ],
    change: () => {
      changeBtnState();
    },
  },
  v3User: {
    value: 'Administrator',
    list: [{ id: 'Administrator', key: 'Administrator' }],
    change: () => {
      changeBtnState();
    },
  },
  trapDomain: {
    value: 'BoardSN',
    list: [
      {
        id: 'BoardSN',
        key: traduction('ALARM_REPORT_EMAIL_SUBJECT_1'),
      },
      {
        id: 'ProductAssetTag',
        key: traduction('ALARM_REPORT_EMAIL_SUBJECT_2'),
      },
      {
        id: 'HostName',
        key: traduction('ALARM_REPORT_EMAIL_SUBJECT_3'),
      },
    ],
    change: () => {
      changeBtnState();
    },
  },
  group: {
    value: '' as any,
    change: () => {
      changeBtnState();
    },
  },
  confirmGroupName: {
    value: '' as any,
    change: () => {
      changeBtnState();
    },
  },
  sendEmailLevel: {
    value: 'None',
    list: [
      {
        id: 'None',
        label: '[NULL]',
      },
      {
        id: 'Critical',
        label: traduction('ALARM_EVENT_CRITICAL'),
      },
      {
        id: 'Major',
        label: traduction('ALARM_EVENT_MAJOR'),
      },
      {
        id: 'Minor',
        label: traduction('ALARM_EVENT_MINOR'),
      },
      {
        id: 'Normal',
        label: traduction('ALARM_EVENT_NORMAL'),
      },
    ],
    change: () => {
      changeBtnState();
    },
  },
  alarmType: {
    value: 'OemEvent',
    list: [
      {
        id: 'OemEvent',
        key: 'ALARM_REPORT_SYSLOG_ALARM_EVENT',
      },
      {
        id: 'SEL',
        key: 'ALARM_REPORT_SYSLOG_ALARM_SEL',
      },
    ],
    change: () => {
      changeBtnState();
    },
  },
});
function input(key: string, value: string) {
  formTrap[key].value = value;
  validateResult[key] = rules[key].validator(rules[key], formTrapRule[key], () => {});
  nextTick(() => {
    if (key === 'group') {
      trpRef.value.validateField('confirmGroupName');
      formTrap.group.value = value;
      validateResult['confirmGroupName'] = rules['confirmGroupName'].validator(
        rules['confirmGroupName'],
        formTrapRule['confirmGroupName'],
        () => {},
      );
    }
    changeBtnState();
  });
}
const srcData = reactive({
  data: <any[]>[],
});
const renderData = reactive({
  data: <any>{},
});

const v3Show = ref(true);
const groupShow = ref(true);
const v3Info = ref('');
const isIRM210 = ref(true);
const btnSaveState = ref(true);
let defaultData: any;

interface resData {
  AlarmSeverity: string;
  AvailableUsers: string[];
  Enabled: boolean;
  Mode: string;
  SNMPv3User: string;
  ServerIdentity: string;
  TrapServerList: any[];
  Version: string;
  CommunityName?: string;
  ReportType: string;
}
// 获取trap初始信息
function getTrapInfo() {
  loading(true);
  getTrapInfoFun().then(res => {
    if (JSON.stringify(res['data']) !== '{}') {
      initData(res['data'] as resData);
    }
    loading(false);
  });
}
function initData(response: resData) {
  defaultData = response;
  if (response.Version === 'SNMPv3') {
    v3Show.value = true;
    groupShow.value = false;
  } else {
    v3Show.value = false;
    groupShow.value = true;
  }
  v3Info.value = response.SNMPv3User;
  formTrap.v3User.list = _extendV3(response.AvailableUsers);
  formTrap.trap.state = response.Enabled;
  formTrap.trapVersion.value = response.Version;
  formTrap.trapMode.value = response.Mode;
  formTrap.v3User.value = response.SNMPv3User;
  formTrap.trapDomain.value = response.ServerIdentity;
  formTrap.sendEmailLevel.value = response.AlarmSeverity;
  formTrap.alarmType.value = response.ReportType;
  renderData.data = {
    enable: response.Enabled,
    version: _filter(response.Version, formTrap.trapVersion.list),
    domin: _filter(response.ServerIdentity, formTrap.trapDomain.list),
    groupName: '',
    groupReName: '',
    level: _filter(response.AlarmSeverity, formTrap.sendEmailLevel.list),
    type: _filter(response.ReportType, formTrap.alarmType.list),
  };
  if (isConfigureUser) {
    formTrap.group.value = response.CommunityName;
    formTrapRule.group = response.CommunityName;
    formTrap.confirmGroupName.value = response.CommunityName;
    formTrapRule.confirmGroupName = response.CommunityName;
  }
  const trapData = response.TrapServerList;
  if (trapData && Array.isArray(trapData)) {
    setTrapTable(trapData);
  }
}
function trapCancelFun() {
  initData(defaultData);
  if (!isConfigureUser) {
    formTrapRule.group = '';
    formTrapRule.confirmGroupName = '';
    formTrap.group.value = '';
    formTrap.confirmGroupName.value = '';
  }
  btnSaveState.value = true;
}
interface IRowType {
  isEdit: boolean;
  isShowDetails: boolean;
  disable: boolean;
  num: number;
  serverAddr: string;
  serverAddrBak: string;
  port: string;
  portBak: string;
  trans: string;
  status: boolean;
  transBak: boolean;
  statusBak: boolean;
  showDetails: boolean;
}

interface IMessageContent {
  TimeEnabled: boolean;
  SensorNameEnabled: boolean;
  SeverityEnabled: boolean;
  EventCodeEnabled: boolean;
  EventDescriptionEnabled: boolean;
}
interface ITableData {
  BobEnabled: boolean;
  DisplayKeywords: boolean;
  Enabled: boolean;
  ID: number;
  IPAddress: string;
  MessageContent: IMessageContent;
  MessageDelimiter: string;
  Port: number;
}

function setTableData(item: any, arr: any[]) {
  const obj = {} as IRowType;
  obj['isEdit'] = false;
  obj['isShowDetails'] = false;
  obj['disable'] = false;
  obj['num'] = Number(item.ID) + 1;
  obj['serverAddr'] = item.IPAddress;
  obj['serverAddrBak'] = item.IPAddress;
  obj['port'] = item.Port;
  obj['portBak'] = item.Port;
  obj['trans'] = item.BobEnabled;
  obj['status'] = item.Enabled;
  obj['transBak'] = item.BobEnabled;
  obj['statusBak'] = item.Enabled;
  obj['showDetails'] = false;
  if (item.BobEnabled === undefined) {
    isIRM210.value = true;
  } else {
    isIRM210.value = false;
  }
  arr.push(obj);
}
function isShowTempArr(
  tempArr: any,
  timeSel: boolean,
  sensorSel: boolean,
  serverSel: boolean,
  eventSel: boolean,
  descSel: boolean,
) {
  if (timeSel) {
    tempArr.push('Time:1970-01-01 01:52:00');
  }
  if (sensorSel) {
    tempArr.push('Sensor:test sensor');
  }
  if (serverSel) {
    tempArr.push('Severity:Assertion Normal');
  }
  if (eventSel) {
    tempArr.push('Code:0x00000001');
  }
  if (descSel) {
    tempArr.push('Description:sensor test event');
  }
}
// 设置表格数据
function setTrapTable(trapData: ITableData[]) {
  const arr: any[] = [];
  for (const item of trapData) {
    setTableData(item, arr);
  }
  srcData.data = arr;
  trapTableRef.value.closeTable();
}
function _extendV3(v3List: string[]) {
  const tmpArr: { key: string; id: string }[] = [];
  v3List?.forEach(item => {
    tmpArr.push({
      key: item,
      id: item,
    });
  });
  return tmpArr;
}
function _filter(id: string, arr: any[]) {
  for (const item of arr) {
    if (item['id'] === id) {
      return item;
    }
  }
  return {};
}
function changeBtnState() {
  if (Object.values(validateResult).includes(false)) {
    btnSaveState.value = true;
    return;
  }
  const isEqul =
    formTrap.trap.state === defaultData.Enabled &&
    formTrap.trapVersion.value === defaultData.Version &&
    formTrap.trapMode.value === defaultData.Mode &&
    formTrap.sendEmailLevel.value === defaultData.AlarmSeverity &&
    formTrap.alarmType.value === defaultData.ReportType;
  const hasV3 = formTrap.v3User.value === v3Info.value;
  let hasGroup = formTrap.group.value === '';
  let trapFlag =
    formTrap.trapDomain.value === defaultData.ServerIdentity &&
    formTrap.confirmGroupName.value === '';
  if (isConfigureUser) {
    hasGroup = formTrap.group.value === defaultData.CommunityName;
    trapFlag = formTrap.trapDomain.value === defaultData.ServerIdentity && hasGroup;
  }
  // v3用户不用校验团体名
  if (formTrap.trapVersion.value === 'SNMPv3') {
    hasGroup = true;
  }
  const condation = isEqul && trapFlag && hasGroup;
  if (v3Show.value) {
    if (condation && hasV3) {
      btnSaveState.value = true;
    } else {
      btnSaveState.value = false;
    }
  } else {
    if (condation) {
      btnSaveState.value = true;
    } else {
      btnSaveState.value = false;
    }
  }
}
function btnSave() {
  loading(true);
  const params = {};
  if (groupShow.value && formTrap.confirmGroupName.value !== '' && !isConfigureUser) {
    params['CommunityName'] = formTrap.confirmGroupName.value;
  }
  if (groupShow.value && formTrap.confirmGroupName.value !== defaultData.CommunityName && isConfigureUser) {
    params['CommunityName'] = formTrap.confirmGroupName.value;
  }
  if (formTrap.trapDomain.value !== defaultData.ServerIdentity) {
    params['ServerIdentity'] = formTrap.trapDomain.value;
  }
  if (formTrap.trapMode.value !== defaultData.Mode) {
    params['Mode'] = formTrap.trapMode.value;
  }
  if (formTrap.v3User.value !== v3Info.value) {
    params['SNMPv3User'] = formTrap.v3User.value;
  }
  if (formTrap.trap.state !== defaultData.Enabled) {
    params['Enabled'] = formTrap.trap.state;
  }
  if (formTrap.trapVersion.value !== defaultData.Version) {
    params['Version'] = formTrap.trapVersion.value;
  }
  if (formTrap.sendEmailLevel.value !== defaultData.AlarmSeverity) {
    params['AlarmSeverity'] = formTrap.sendEmailLevel.value;
  }
  if (formTrap.alarmType.value !== defaultData.ReportType) {
    params['ReportType'] = formTrap.alarmType.value;
  }
  trapSave(params)
    .then(res => {
      loading(false);
      const response = res['data'] as any;
      btnSaveState.value = true;
      if (response.error) {
        alertMessage({ type: 'error', label: 'COMMON_FAILED' });
      } else {
        if (!isConfigureUser) {
          // 团体名设置成功要清空
          formTrap.group.value = '';
          formTrapRule.group = '';
          formTrap.confirmGroupName.value = '';
          formTrapRule.confirmGroupName = '';
        }
        initData(response);
        getTrapInfo();
        alertMessage({ type: 'success', label: 'COMMON_SUCCESS' });
      }
    })
    .catch(error => {
      loading(false);
      btnSaveState.value = true;
      alertMessage({ type: 'error', label: 'COMMON_FAILED' });
    });
}
function tableChange(event: { key: string; value: any }) {
  if (event.key === 'save') {
    setTrapTable(event.value.TrapServer);
  }
}
function getPwdCheck() {
  getPwdCode().then(res => {
    const response = res['data'];
    pwdCheck.value = response.PasswordComplexityCheckEnabled;
    rules.group = initRules(response.PasswordComplexityCheckEnabled);
  });
}

onMounted(() => {
  getTrapInfo();
  getPwdCheck();
});
</script>

<style lang="scss" scoped>
#trapComponent {
  margin-right: 24px;
  height: calc(100% - 104px);
}
.trap-top {
  padding: 24px;
  border-radius: 4px;
  background-color: var(--o-bg-color-base);
  margin-bottom: 16px;
  .el-input,
  .el-select {
    width: 320px;
  }
}
.top-title {
  font-size: 16px;
  margin-bottom: 16px;
}
#snmpAlertTrap {
  color: var(--o-color-major);
  margin-left: 8px;
}
.trap-table {
  padding: 24px;
  border-radius: 4px;
  background-color: var(--o-bg-color-base);
}
#trapVersionTip {
  margin-left: 8px;
  color: var(--o-color-major);
}
.table-title {
  font-size: 16px;
  color: var(--o-text-color-primary);
  line-height: 24px;
  margin-bottom: 16px;
}
.trap-btns {
  margin-bottom: 0;
}
:deep(.small-item) {
  height: 16px;
  .el-form-item__label {
    padding-top: 0;
    padding-bottom: 0;
  }
  .el-form-item__content {
    line-height: 16px;
  }
  .el-radio {
    height: 16px;
  }
  .el-radio__label {
    color: var(--o-text-color-secondary);
  }
}
#trapGroupItem,#trapConfirmGroupItem{
  :deep(.el-input__suffix-inner){
    .el-input__password{
      margin-right: 40px;
    }
  }
  :deep(.el-input__inner){
    padding-right: 40px !important;
  }
}
</style>
