<template>
  <el-table id="obTable" v-addId.table="'obServerTable'" :data="props.data" border>
    <!-- 序号 -->
    <el-table-column :label="traduction('EVENT_ORDER')" type="index" width="100" />
    <!-- 服务器地址 -->
    <el-table-column
      :label="traduction('TELEMETRY_RECEIVER_ADDRESS')"
      prop="serviceAddr"
      class="service-addr-column"
      min-width="40"
    >
      <template #default="scope">
        <div v-show="!scope.row.isEdit">
          <span :id="'serviceAddr' + scope.$index">{{ scope.row.serviceAddr }}</span>
        </div>
        <div v-show="scope.row.isEdit">
          <el-form
            :ref="setAddrFormRef"
            class="ob-form"
            :class="{ 'has-error': scope.row.disabled }"
            :model="scope.row"
            :rules="formRules"
            :validate-on-rule-change="false"
            @validate="validateAction(scope.row).action"
          >
            <el-form-item prop="serviceAddr">
              <el-popover
                v-model:visible="popoverVisible.serviceAddr[scope.row.num]"
                popper-class="no-wrap-popover"
                placement="top"
                :teleported="true"
                :content="scope.row.validationAddr.tip"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="scope.row.serviceAddr"
                    v-addId.input="'addrSection'"
                    class="addrSection"
                    v-clearable
                    clearable
                    @focus="focus('serviceAddr', scope.row)"
                    @blur="blur('serviceAddr', scope.row)"
                    @clear="clear('serviceAddr', scope.row)"
                    @input="change('serviceAddr', $event, scope.row)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </el-form>
        </div>
      </template>
    </el-table-column>
    <!-- 端口 -->
    <el-table-column :label="traduction('SERVICE_PORT')" class="port-column" min-width="30">
      <template #default="scope">
        <div v-show="!scope.row.isEdit">
          <span :id="'port' + scope.$index">{{ scope.row.port }}</span>
        </div>
        <div v-show="scope.row.isEdit">
          <el-form
            :ref="setPortFormRef"
            class="ob-form"
            :class="{ 'has-error': scope.row.disabled }"
            :model="scope.row"
            :rules="formRules"
            :validate-on-rule-change="false"
            @validate="validateAction(scope.row).action"
          >
            <el-form-item prop="port">
              <el-popover
                v-model:visible="popoverVisible.port[scope.row.num]"
                popper-class="no-wrap-popover"
                placement="top"
                :teleported="true"
                :content="scope.row.validationPort.tip"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="scope.row.port"
                    v-addId.input="'portSection' + scope.row.num"
                    v-clearable
                    clearable
                    class="portSection"
                    @focus="focus('port', scope.row)"
                    @blur="blur('port', scope.row)"
                    @clear="clear('port', scope.row)"
                    @input="change('port', $event, scope.row)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </el-form>
        </div>
      </template>
    </el-table-column>
    <!-- 当前状态 -->
    <el-table-column :label="traduction('ALARM_REPORT_CURRENT_STATUS')" class="status-column" min-width="30">
      <template #default="scope">
        <div v-if="scope.row.isEdit" class="switch">
          <el-switch id="enabled" v-model="scope.row.enabled"></el-switch>
        </div>
        <span
          v-if="!scope.row.isEdit"
          :class="{ statusTrue: scope.row.enabled, statusFalse: !scope.row.enabled }"
        >
          <span v-if="scope.row.enabled" :id="'currentEnabled' + scope.$index">
            {{ $t('ENABLED') }}
          </span>
          <span v-if="!scope.row.enabled" :id="'currentDisabled' + scope.$index">
            {{ $t('DISABLED') }}
          </span>
        </span>
      </template>
    </el-table-column>
    <!-- 操作 -->
    <el-table-column :label="traduction('COMMON_OPERATE')" class="operate-column" width="317">
      <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 || !scope.row.enabled || !props.enabled }"
            class="operate test"
            @click="test(scope.row)"
          >
            {{ $t('ALARM_REPORT_TEST') }}
          </a>
        </div>
        <div v-if="scope.row.isEdit">
          <a
            v-if="scope.row.canSave"
            :id="`save${scope.row.num}`"
            class="operate save"
            @click="save(scope.row)"
          >
            {{ $t('COMMON_SAVE') }}
          </a>
          <a v-else :id="`save${scope.row.num}`" class="operate save not-allow">
            {{ $t('COMMON_SAVE') }}
          </a>
          <a :id="`cancel${scope.row.num}`" class="operate cancel" @click="cancel(scope.row)">
            {{ $t('COMMON_CANCEL') }}
          </a>
        </div>
      </template>
    </el-table-column>
    <template #empty>
      <TableNoData />
    </template>
  </el-table>
</template>

<script lang="ts" setup>
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import { traduction } from '@/utils/language';
import { DomainValidators } from '@/validators/domain-validators';
import { rangeVerification } from '@/validators/validation-functions';
import { nextTick, onMounted, reactive, ref, watch } from 'vue';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';
import { DOMAIN_NAME, IPV4, IPV6 } from '@/utils/regular';
const props = defineProps({
  data: {
    required: true,
    type: Object,
    default: () => {
      return {};
    },
  },
  isSystemLock: {
    required: true,
    type: Boolean,
  },
  hasPermission: {
    required: true,
    type: Boolean,
  },
  enabled: {
    required: true,
    type: Boolean,
  }
});
const emits = defineEmits(['operateChange']);
const popoverVisible = reactive({
  serviceAddr: {},
  port: {},
});
const formRefObjs: any = reactive({});
const formRefObjsPort: any = reactive({});
const protocolType = ref('');
// 点击编辑的数据行序号
let editIndexTemp: number = -1;
function edit(row: any) {
  if (!props.hasPermission || props.isSystemLock) {
    return;
  }
  editIndexTemp = row.num;
  const params = {
    key: 'edit',
    value: row,
  };
  row.disabled = false;
  emits('operateChange', params);
  nextTick(() => {
    formRefObjs[row.num].addr.clearValidate();
  });
}
function cancel(row: any) {
  const params = {
    key: 'cancel',
    value: row,
  };
  validateResult[row.num] = {};
  setTimeout(() => {
    formRefObjs[row.num].addr.clearValidate();
    formRefObjsPort[row.num].port.clearValidate();
    formRefObjs[row.num]['addr'].$el.classList.remove('has-error');
    formRefObjsPort[row.num]['port'].$el.classList.remove('has-error');
  }, 0);
  emits('operateChange', params);
}
function save(row: any) {
  const params = {
    key: 'save',
    value: row,
  };
  emits('operateChange', params);
}
function test(row: any) {
  if (!props.hasPermission || !row.enabled || !props.enabled) {
    return;
  }
  const params = {
    key: 'test',
    value: row,
  };
  emits('operateChange', params);
}
const formRules: any = reactive({
  serviceAddr: {
    required: true,
    type: 'string',
    trigger: 'change',
    message: traduction('COMMON_FORMAT_ERROR'),
    validator: checkIpAndDomin,
  },
  port: {
    trigger: 'change',
    required: true,
    type: 'number',
    isInteger: true,
    min: 1,
    max: 65535,
    message: traduction('VALIDTOR_RANGE'),
    validator: rangeVerification,
  },
});
// 表单校验结果
let validateResult = reactive([] as any);
function change(key: string, value: string, row: any) {
  if (!validateResult[row.num]) {
    validateResult[row.num] = {};
  }
  validateResult[row.num][key] = formRules[key].validator(formRules[key], value, () => {});
  if (validateResult[row.num]['serviceAddr'] === false || validateResult[row.num]['port'] === false) {
    row.disabled = true;
  } else {
    row.disabled = false;
  }
}

function checkIpAndDomin(rule: any, value: any, callback: (error?: Error) => void): any {
  if (value === '') {
    callback(new Error());
    return false;
  }
  let result = false;
  if (/^[0-9.]+$/.test(value)) {
    result = IPV4.test(value);
  } else if (value.indexOf(':') > -1) {
    result = IPV6.test(value);
  } else {
    result = DOMAIN_NAME.test(value);
  }
  if (result) {
    callback();
    return true;
  } else {
    callback(new Error());
    return false;
  }
}

// 表单校验发生时 - 控制保存按钮状态 state:校验结果
function validateAction(row: any) {
  row.canSave =
    rangeVerification(formRules.port, row.port, () => {}) && checkIpAndDomin(formRules.serviceAddr, row.serviceAddr, () => {});
  const action = (key: any, value: boolean) => {};
  return { action };
}
function focus(key: string, row: any) {
  popoverVisible[key][row.num] = true;
}

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

function clear(key: string, row: any) {
  // 如果没有focus，那么这个地方需要手动调用一次校验
  if (popoverVisible[key] !== row.num) {
    if (key === 'port') {
      formRefObjsPort[row.num]['port'].validateField(key);
    } else {
      formRefObjs[row.num]['addr'].validateField(key);
    }
  }
}
function setAddrFormRef(el: any) {
  if (!formRefObjs[editIndexTemp]) {
    formRefObjs[editIndexTemp] = {};
  }
  formRefObjs[editIndexTemp]['addr'] = el;
}
function setPortFormRef(el: any) {
  if (!formRefObjsPort[editIndexTemp]) {
    formRefObjsPort[editIndexTemp] = {};
  }
  formRefObjsPort[editIndexTemp]['port'] = el;
}
watch(
  () => props.data,
  val => {
    val.map((item: any) => {
      popoverVisible.serviceAddr[item.num] = false;
      popoverVisible.port[item.num] = false;
    });
  },
);
</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);
  }
}
.portSection {
  width: 120px;
}
.addrSection {
  width: 240px;
}
.edit {
  margin-right: 8px;
}
.save {
  margin-right: 8px;
}
.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;
  }
}
.statusTrue {
  & > span {
    font-size: 12px;
    color: #ffffff;
    display: inline-block;
    background: var(--o-color-success);
    border-radius: 2px;
    padding: 0 14px;
  }
}
.log-type-item {
  margin-right: 18px;
}
.syslog-form {
  &.has-error {
    .el-form-item {
      margin-bottom: var(--o-form-item-gap);
    }
  }
  .el-form-item {
    margin-bottom: 0;
  }
}
.switch {
  :deep(.el-switch) {
    margin-top: -0.3em;
  }
}
</style>
<style>
#syslogTable .el-table__cell {
  vertical-align: baseline;
}
</style>
