<template>
  <el-table
    v-addId.table="'trapTable'"
    :data="props.data"
    :expand-row-keys="expand"
    :row-key="(row: any) => row.num"
    @expand-change="expandChange"
  >
    <el-table-column type="expand" width="32px">
      <template #default="scope">
        <el-form
          :ref="setFormRef(scope.$index).option"
          label-width="auto"
          label-position="left"
          :model="scope.row"
          :rules="rules"
          @validate="validate"
        >
          <div class="half-width">
            <el-form-item
              :id="'currentStatus_label' + scope.$index"
              :label="$t('TRAP_CURRENT_STATUS')"
              class="small-item"
            >
              <el-switch
                v-show="scope.row.isShowDetails"
                id="statusEnable"
                v-model="scope.row.status"
              ></el-switch>
              <span
                v-show="!scope.row.isShowDetails"
                class="mt7"
                :class="{ statusTrue: scope.row.status, statusFalse: !scope.row.status }"
              >
                <span v-show="scope.row.status" :id="'trapCurrentEnabled' + scope.$index">
                  {{ $t('ENABLED') }}
                </span>
                <span v-show="!scope.row.status" :id="'trapCurrentDisabled' + scope.$index">
                  {{ $t('DISABLED') }}
                </span>
              </span>
            </el-form-item>

            <el-form-item
              :id="'serveraddr_label' + scope.$index"
              :label="$t('TRAP_SERVER_ADDR')"
              prop="serverAddr"
            >
              <el-popover
                v-model:visible="popoverVisible.serverAddr[scope.row.num]"
                popper-class="no-wrap-popover"
                placement="top"
                :teleported="true"
                :content="$t('COMMON_IPV4_IPV6_DOMIN')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-show="scope.row.isShowDetails"
                    v-model="scope.row.serverAddr"
                    v-addId.input="`serverAddr${scope.row.num}`"
                    v-clearable
                    clearable
                    @focus="focus('serverAddr', scope.row)"
                    @blur="blur('serverAddr', scope.row)"
                    @clear="clear('serverAddr', scope.row)"
                    @input="input('serverAddr', $event, scope.row)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
              <div v-show="!scope.row.isShowDetails" class="mt7 server-addr">
                {{ scope.row.serverAddr }}
              </div>
            </el-form-item>
          </div>
          <div class="half-width">
            <el-form-item
              :id="'trapforward_label' + scope.$index"
              :label="$t('TRAP_FORWARD')"
              class="small-item"
            >
              <el-switch
                v-show="scope.row.isShowDetails"
                id="transEnable"
                v-model="scope.row.trans"
              ></el-switch>
              <span
                v-show="!scope.row.isShowDetails"
                class="mt7"
                :class="{ statusTrue: scope.row.trans, statusFalse: !scope.row.trans }"
              >
                <span v-show="scope.row.trans" :id="'trapForwardEnabled' + scope.$index">
                  {{ $t('ENABLED') }}
                </span>
                <span v-show="!scope.row.trans" :id="'trapForwardDisabled' + scope.$index">
                  {{ $t('DISABLED') }}
                </span>
              </span>
            </el-form-item>
            <el-form-item
              :id="'trapport_label' + scope.$index"
              :label="$t('TRAP_PORT')"
              prop="port"
            >
              <div class="trap-port">
                <el-popover
                  v-model:visible="popoverVisible.port[scope.row.num]"
                  popper-class="no-wrap-popover"
                  placement="top"
                  :teleported="true"
                  :content="$t('VALIDTOR_RANGE')"
                  trigger="focus"
                  trigger-keys
                >
                  <template #reference>
                    <el-input
                      v-show="scope.row.isShowDetails"
                      v-model="scope.row.port"
                      v-addId.input="`port${scope.row.num}`"
                      v-clearable
                      clearable
                      @focus="focus('port', scope.row)"
                      @blur="blur('port', scope.row)"
                      @clear="clear('port', scope.row)"
                      @input="input('port', $event, scope.row)"
                    >
                      <template #suffix>
                        <ErrorIcon />
                        <ClearableIcon />
                      </template>
                    </el-input>
                  </template>
                </el-popover>
                <span
                  v-show="scope.row.isShowDetails"
                  id="TrapResetId"
                  class="restTrapBtn"
                  @click="restTrapFN(scope.row)"
                >
                  {{ $t('ALARM_EVENT_RESET') }}
                </span>
              </div>
              <div v-show="!scope.row.isShowDetails" :id="'exTrapPort' + scope.$index" class="mt7">
                {{ scope.row.port }}
              </div>
            </el-form-item>
          </div>
        </el-form>
      </template>
    </el-table-column>
    <!-- 序号 -->
    <el-table-column :label="traduction('EVENT_ORDER')" type="index" width="50" />
    <!-- Trap服务器地址 -->
    <el-table-column :label="traduction('TRAP_SERVER_ADDR')" prop="serviceAddr">
      <template #default="scope">
        <span :id="'trapServerAddr' + scope.$index">{{ scope.row.serverAddrBak }}</span>
      </template>
    </el-table-column>
    <!-- Trap端口 -->
    <el-table-column :label="traduction('TRAP_PORT')">
      <template #default="scope">
        <span :id="'trapPort' + scope.$index">{{ scope.row.portBak }}</span>
      </template>
    </el-table-column>
    <!-- 带内转发 -->
    <el-table-column v-show="!isIRM210" :label="traduction('TRAP_FORWARD')">
      <template #default="scope">
        <div>
          <span :class="{ statusTrue: scope.row.transBak, statusFalse: !scope.row.transBak }">
            <span v-show="scope.row.transBak" :id="'transBakEnabled' + scope.$index">
              {{ traduction('ENABLED') }}
            </span>
            <span v-show="!scope.row.transBak" :id="'transBakDisabled' + scope.$index">
              {{ traduction('DISABLED') }}
            </span>
          </span>
        </div>
      </template>
    </el-table-column>
    <!-- 当前状态 -->
    <el-table-column :label="traduction('TRAP_CURRENT_STATUS')">
      <template #default="scope">
        <div>
          <span :class="{ statusTrue: scope.row.statusBak, statusFalse: !scope.row.statusBak }">
            <span v-show="scope.row.statusBak" :id="'currentEnabled' + scope.$index">
              {{ traduction('ENABLED') }}
            </span>
            <span v-show="!scope.row.statusBak" :id="'currentDisabled' + scope.$index">
              {{ traduction('DISABLED') }}
            </span>
          </span>
        </div>
      </template>
    </el-table-column>
    <!-- 操作 -->
    <el-table-column :label="traduction('COMMON_OPERATE')" prop="serviceAddr">
      <template #default="scope">
        <div v-if="!scope.row.isEdit">
          <a
            :id="`edit${scope.row.num}`"
            :class="{ 'not-allow': !props.hasPermission || props.isSystemLock }"
            class="operate edit"
            @click="edit(scope.row)"
          >
            {{ $t('COMMON_EDIT') }}
          </a>
          <a
            :id="`test${scope.row.num}`"
            :class="{ 'not-allow': !props.hasPermission }"
            class="operate test"
            @click="test(scope.row)"
          >
            {{ $t('ALARM_REPORT_TEST') }}
          </a>
        </div>
        <div v-if="scope.row.isEdit">
          <a
            :id="`save${scope.row.num}`"
            class="operate save"
            :class="{ 'not-allow': scope.row.disable }"
            @click="save(scope.row)"
          >
            {{ $t('COMMON_SAVE') }}
          </a>
          <a
            :id="`cancel${scope.row.num}`"
            class="operate cancel"
            :class="{ 'not-allow': scope.row.disable }"
            @click="cancel(scope.row)"
          >
            {{ $t('COMMON_CANCEL') }}
          </a>
        </div>
      </template>
    </el-table-column>
    <template #empty>
      <TableNoData />
    </template>
  </el-table>
  <Dialog ref="commonDialogRef" :config="commonDialogConfig" @close="commonDialogClose" />
</template>

<script lang="ts" setup>
import { getErrorTranslate, traduction } from '@/utils/language';
import { reactive, ref, watch } from 'vue';
import { trapSave, trapSendTest } from '../report.service';
import { DomainValidators } from '@/validators/domain-validators';
import { rangeVerification } from '@/validators/validation-functions';
import { loading, showFailedMessage, showSuccessMessage } from '@/utils/composition';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
const props = defineProps({
  data: {
    required: true,
    type: Object,
    default: () => {
      return {};
    },
  },
  isIRM210: {
    required: true,
    type: Boolean,
  },
  renderData: {
    required: true,
    type: Object,
    default: () => {
      return {};
    },
  },
  btnSaveState: {
    required: true,
    type: Boolean,
  },
  isSystemLock: {
    required: true,
    type: Boolean,
  },
  hasPermission: {
    required: true,
    type: Boolean,
  },
});
const TRAP_PORT = 162;
const expand = ref(<number[]>[]);
const formRefObjs: any = reactive({});

const commonDialogRef = ref();
const commonDialogConfig = reactive({
  id: 'trapTestModel',
  content: traduction('ALARM_REPORT_TRAP_TEST'),
  title: traduction('COMMON_CONFIRM'),
  cancelButton: {
    hide: true,
  },
});

// 点击编辑的数据行序号
let editIndex: number = -1;
interface IRowType {
  disable: boolean;
  isEdit: boolean;
  isShowDetails: boolean;
  num: number;
  port: number;
  portBak: number;
  result: string;
  serverAddr: string;
  serverAddrBak: string;
  status: boolean;
  statusBak: boolean;
  trans: boolean;
  transBak: boolean;
  showDetails: boolean;
}

const emits = defineEmits(['operateChange']);
function closeTable() {
  expand.value = [];
}
defineExpose({
  closeTable,
});
function edit(row: IRowType) {
  if (!props.hasPermission || props.isSystemLock) {
    return;
  }
  if (!expand.value.includes(row.num)) {
    expand.value.push(row.num);
  }
  editIndex = row.num;
  row.showDetails = true;
  row.isEdit = true;
  row.isShowDetails = true;
}
function cancel(row: IRowType) {
  row.showDetails = !row.showDetails;
  row.isShowDetails = false;
  row.isEdit = false;
  row.status = row.statusBak;
  row.port = row.portBak;
  row.serverAddr = row.serverAddrBak;
  row.trans = row.transBak;
}
function getPort(port: string | number): number | null {
  if (port === '') {
    return null;
  }
  if (typeof port === 'number') {
    return port;
  }
  return parseInt(port, 10);
}
function save(row: IRowType) {
  if (JSON.stringify(validateResult).includes('false')) {
    return;
  }
  loading(true);
  row.disable = true;
  const obj = {
    ID: row.num - 1,
    Enabled: row.status,
    IPAddress: row.serverAddr,
    Port: getPort(row.port),
    BobEnabled: row.trans,
  };
  const params = {
    TrapServerList: [obj],
  };
  trapSave(params)
    .then(res => {
      const response = res['data'] as any;
      loading(false);
      if (response.error) {
        showFailedMessage();
        cancel(row);
        row.disable = false;
      } else {
        row.showDetails = false;
        row.isEdit = false;
        row.disable = false;
        showSuccessMessage();
        emits('operateChange', {
          key: 'save',
          value: {
            TrapMode: response.Mode,
            TrapServer: response.TrapServerList,
          },
        });
      }
    })
    .catch(error => {
      loading(false);
      const errorCode = error?.data.error[0].code;
      showFailedMessage(getErrorTranslate(errorCode));
      cancel(row);
      row.disable = false;
    });
}

// 表格测试
function test(row: IRowType) {
  if (!props.hasPermission) {
    return;
  }
  if (!props.btnSaveState) {
    commonDialogRef.value.show();
    return;
  }
  loading(true);
  const queryData = {
    ID: row.num - 1,
  };
  trapSendTest(queryData)
    .then((res: any) => {
      loading(false);
      showSuccessMessage(traduction('ALARM_REPORT_TEST_MESSAGE'));
    })
    .catch(error => {
      loading(false);
      const code = error?.data?.error[0]?.code;
      showFailedMessage(getErrorTranslate(code));
    });
}

// Trap端口重置
function restTrapFN(row: IRowType) {
  row.port = TRAP_PORT;
}

const validateResult = {};
const popoverVisible = reactive({
  serverAddr: {},
  port: {},
});
const rules = {
  serverAddr: DomainValidators.ipv46AndDomin(),
  port: {
    trigger: 'change',
    type: 'number',
    min: 1,
    max: 65535,
    isInteger: true,
    required: true,
    message: traduction('VALIDTOR_RANGE'),
    validator: rangeVerification,
  },
};
function input(key: string, value: string, row: IRowType) {
  validateResult[key] = rules[key].validator(rules[key], value, () => {});
  row[key] = value;
}
function validate(key: string, state: boolean) {
  validateResult[key] = state;
}
function focus(key: string, row: IRowType) {
  popoverVisible[key][row.num] = true;
}

function blur(key: string, row: IRowType) {
  popoverVisible[key][row.num] = false;
}

function clear(key: string, row: IRowType) {
  // 如果没有focus，那么这个地方需要手动调用一次校验
  if (!popoverVisible[key][row.num]) {
    formRefObjs[editIndex].validateField(key);
  }
}
function setFormRef(index: number): any {
  return function option(el: any) {
    if (!formRefObjs[index]) {
      formRefObjs[index] = {};
    }
    formRefObjs[index] = el;
  };
}

function expandChange(row: IRowType, expandedRows: any) {
  if (expandedRows.length > 0) {
    expand.value = expandedRows.map((item: IRowType) => {
      return item.num;
    });
    if (
      !expandedRows.find((item: IRowType) => {
        item.num === row.num;
      })
    ) {
      row.isEdit = false;
      row.isShowDetails = false;
    }
  } else {
    row.isEdit = false;
    row.isShowDetails = false;
    expand.value = [];
  }
}
watch(
  () => props.data,
  val => {
    val.map((item: any) => {
      popoverVisible.serverAddr[item.num] = false;
      popoverVisible.port[item.num] = false;
    });
  },
);

function commonDialogClose(reason: boolean) {
  commonDialogRef.value.hide();
}
</script>

<style lang="scss" scoped>
.operate {
  cursor: pointer;
  color: var(--o-color-primary);
  &.not-allow {
    color: #b8becc !important;
    cursor: not-allowed !important;
  }
  &:hover {
    color: var(--o-color-primary-secondary);
  }
}
.edit {
  margin-right: 8px;
}
.save {
  margin-right: 8px;
}
.half-width {
  width: 50%;
  display: inline-block;
  .el-input {
    width: 240px;
  }
  .el-form-item {
    margin-bottom: 16px;
    margin-left: 40px;
  }
}
.trap-port {
  display: flex;
}
#TrapResetId {
  margin-left: 8px;
  cursor: pointer;
  color: var(--o-color-primary);
}
.statusFalse {
  & > span {
    font-size: 12px;
    color: #ffffff;
    display: inline-block;
    background: var(--o-text-color-tertiary);
    border-radius: var(--i-button-border-radius);
    padding: 0 14px;
    line-height: 16px;
  }
}
.statusTrue {
  & > span {
    font-size: 12px;
    color: #ffffff;
    display: inline-block;
    background: var(--o-color-success);
    border-radius: var(--i-button-border-radius);
    padding: 0 14px;
    line-height: 16px;
  }
}
: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);
  }
  .el-checkbox-group {
    .el-checkbox {
      height: auto;
    }
  }
}
.server-addr {
  max-width: 100%;
  padding-right: 12px;
  word-break: break-word;
  line-height: 16px;
}

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

:deep(.el-table__expanded-cell) {
  padding-bottom: 0px;
}
</style>
