<script lang="ts" setup>
import { IconAlarm } from '@computing/opendesign-icons';
import { traduction } from '@/utils/language';
import { editNetworkData } from '../network.server';
import { nextTick, reactive, ref, watch } from 'vue';
import { showElMessage, deepClone } from '@/utils/utils';
import { DNS_DOMAIN_NAME, IP_REGEX_V4, IPV6 } from '@/utils/regular';

import IpInput from '@/components/IpInput/IpInput.vue';
import ErrorIcon from '@/components/ErrorIcon/ErrorIcon.vue';
import ClearableIcon from '@/components/ClearableIcon/ClearableIcon.vue';

import GlobalStoreService from '@/services/gloabal-store-service';

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']);

watch(
  () => props.data,
  (val: any) => {
    protocolInit(val);
  },
  { deep: true },
);

// 保存按钮状态
const saveBtnState = ref(true);
// 保存确认弹窗的开关
const dialogVisible = ref(false);
// 记录校验结果
let validateRes: any = {};
// 记录最终保存数据 - 以及用于判断保存按钮的状态
let queryParams: any = {};

// 记录原始数据
let preDnsParams: any = {};
// 展示数据
const dnsParams: any = reactive({});
// DNS的前两个单选的可选状态
const disabledState = reactive({
  IPv4: false,
  IPv6: false,
});

// form的ref对象
const formRef = ref();

const focusState = reactive({
  dnsDomain: false,
  dnsServer: false,
  dnsServer1: false,
  dnsServer2: false,
});

const popoverSetting = reactive({
  dnsDomain: {
    show: true,
    width: '320px',
    content: traduction('IBMC_DOMAIN_TIP').replace(/\{\d\}/, '67'),
    placement: 'right-start',
    trigger: 'focus',
  },
  other: {
    show: true,
    width: 'auto',
    content: traduction('IBMC_DNS_TIP_CHECK'),
    placement: 'right',
    trigger: 'focus',
  },
});

// 服务器地址校验
function validateIp46(value: string, callback: any) {
  // 不是必传的
  if (value === '') {
    callback();
    return true;
  }
  if (/^[0-9.]+$/.test(value)) {
    if (!IP_REGEX_V4.test(value)) {
      callback(new Error(traduction('COMMON_FORMAT_ERROR')));
      return false;
    } else {
      callback();
      return true;
    }
  } else if (value.indexOf(':') > -1) {
    if (!IPV6.test(value)) {
      callback(new Error(traduction('COMMON_FORMAT_ERROR')));
      return false;
    } else {
      callback();
      return true;
    }
  }
  callback(new Error(traduction('COMMON_FORMAT_ERROR')));
  return false;
}

const rules = reactive({
  dnsDomain: {
    trigger: 'blur',
    validator: (rule: any, value: string, callback: any) => {
      if (value && !DNS_DOMAIN_NAME.test(value)) {
        callback(new Error(traduction('COMMON_FORMAT_ERROR')));
        return false;
      }

      callback();
      return true;
    },
  },
  dnsServer: {
    trigger: 'blur',
    validator: (rule: any, value: string, callback: any) => {
      return validateIp46(value, callback);
    },
  },
  dnsServer1: {
    trigger: 'blur',
    validator: (rule: any, value: string, callback: any) => {
      return validateIp46(value, callback);
    },
  },
  dnsServer2: {
    trigger: 'blur',
    validator: (rule: any, value: string, callback: any) => {
      return validateIp46(value, callback);
    },
  },
});

// 清空校验
function clearValidate() {
  formRef.value.clearValidate(['dnsDomain', 'dnsServer', 'dnsServer1', 'dnsServer2']);
  Object.assign(validateRes, {
    dnsDomain: true,
    dnsServer: true,
    dnsServer1: true,
    dnsServer2: true,
  });
}

// 设置DNS的前两个单选的可选状态
function ipVersionDNS(networkDns: any) {
  if (networkDns.ipVersion === 'IPv4') {
    if (networkDns.netModelV4 !== 'Static') {
      disabledState.IPv4 = false;
      disabledState.IPv6 = true;
    } else {
      disabledState.IPv4 = true;
      disabledState.IPv6 = true;
    }
  } else if (networkDns.ipVersion === 'IPv6') {
    if (networkDns.netModelV6 !== 'Static') {
      disabledState.IPv4 = true;
      disabledState.IPv6 = false;
    } else {
      disabledState.IPv4 = true;
      disabledState.IPv6 = true;
    }
  } else if (networkDns.ipVersion === 'IPv4AndIPv6') {
    if (networkDns.netModelV4 !== 'Static') {
      disabledState.IPv4 = false;
    } else {
      disabledState.IPv4 = true;
    }
    if (networkDns.netModelV6 !== 'Static') {
      disabledState.IPv6 = false;
    } else {
      disabledState.IPv6 = true;
    }
  }
}

// DNS信息发生修改
function dnsRadioChange() {
  const { dnsAddress } = dnsParams;
  // 恢复初始值
  if (dnsAddress === 'IPv4' || dnsAddress === 'IPv6') {
    Object.assign(dnsParams, {
      dnsDomain: preDnsParams.dnsDomain,
      dnsServer: preDnsParams.dnsServer,
      dnsServer1: preDnsParams.dnsServer1,
      dnsServer2: preDnsParams.dnsServer2,
    });
    // 清空校验
    clearValidate();
  } else {
    // 设置其进行校验
    formRef.value.validateField(['dnsDomain', 'dnsServer', 'dnsServer1', 'dnsServer2']);
  }

  nextTick(() => {
    protocolEnabledEN();
  });
}

// 初始化数据加工
function protocolInit(networkDns: any) {
  validateRes = {};
  if (JSON.stringify(networkDns) === '{}') {
    return;
  }

  // 初始化展示数据
  Object.assign(dnsParams, deepClone(networkDns));
  preDnsParams = deepClone(networkDns);
  // 设置DNS的前两个单选的可选状态
  ipVersionDNS(networkDns);
  // 清空校验
  clearValidate();
}

// 点击确认
function sureSetting() {
  globalStoreService.setValue('isLoading', true);
  editNetworkData(queryParams)
    .then((data: any) => {
      emits('initShowData', data);
      saveBtnState.value = !saveBtnState.value;
      dialogVisible.value = false;
      showElMessage('success', traduction('COMMON_SUCCESS'));
      globalStoreService.setValue('isLoading', false);
    })
    .catch(err => {
      dialogVisible.value = false;
      showElMessage('error', traduction('COMMON_FAILED'));
      globalStoreService.setValue('isLoading', false);
    });
}

// 设置保存按钮的状态
function protocolEnabledEN() {
  // 有校验失败的
  for (const key in validateRes) {
    if (!validateRes[key]) {
      saveBtnState.value = true;
      return;
    }
  }

  queryParams = { DNS: {} };

  const { dnsAddress, dnsDomain, dnsServer, dnsServer1, dnsServer2 } = dnsParams;

  if (dnsAddress !== preDnsParams['dnsAddress']) {
    queryParams.DNS['AddressMode'] = dnsAddress;
  }
  if (dnsDomain !== preDnsParams['dnsDomain']) {
    queryParams.DNS['Domain'] = dnsDomain;
  }
  if (dnsServer !== preDnsParams['dnsServer']) {
    queryParams.DNS['PrimaryServer'] = dnsServer;
  }
  if (dnsServer1 !== preDnsParams['dnsServer1']) {
    queryParams.DNS['BackupServer'] = dnsServer1;
  }
  if (dnsServer2 !== preDnsParams['dnsServer2']) {
    queryParams.DNS['TertiaryServer'] = dnsServer2;
  }

  if (JSON.stringify(queryParams.DNS) !== '{}') {
    saveBtnState.value = false;
  } else {
    saveBtnState.value = true;
  }
}

// ip或者普通输入框发生修改
function input(key: string, value: string) {
  dnsParams[key] = value;
  // 进行校验，获取校验结果，用于设置保存按钮的状态
  validateRes[key] = rules[key].validator(null, value, () => {});
  nextTick(() => {
    protocolEnabledEN();
  });
}

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

// ip输入框或者普通输入框发生校验 记录校验结果
function validate(key: string, value: boolean) {
  validateRes[key] = value;
  nextTick(() => {
    protocolEnabledEN();
  });
}
</script>

<template>
  <!-- DNS -->
  <div id="netwotkDns" class="box">
    <div class="part-title">{{ $t('IBMC_DNS') }}</div>
    <div class="row">
      <span class="key check-mode network-page-label">{{ $t('IBMC_DNS_INFOR') }}</span>

      <div class="content">
        <!--  自动获取IPv4 DNS地址 - 自动获取IPv6 DNS地址  - 手动配置  -->
        <div class="radio-box">
          <el-radio
            v-model="dnsParams.dnsAddress"
            v-addId.radio="'dnsIPv4'"
            :disabled="disabledState.IPv4 || lock || !permission"
            label="IPv4"
            size="large"
            @change="dnsRadioChange"
          >
            {{ $t('IBMC_DHCPV4_AUTOGET') }}
          </el-radio>
          <el-radio
            v-model="dnsParams.dnsAddress"
            v-addId.radio="'dnsIPv6'"
            :disabled="disabledState.IPv6 || lock || !permission"
            label="IPv6"
            size="large"
            @change="dnsRadioChange"
          >
            {{ $t('IBMC_DHCPV6_AUTOGET') }}
          </el-radio>
          <el-radio
            v-model="dnsParams.dnsAddress"
            v-addId.radio="'dnsStatic'"
            :disabled="lock || !permission"
            label="Static"
            size="large"
            @change="dnsRadioChange"
          >
            {{ $t('IBMC_IP_CONFIGURATION') }}
          </el-radio>
        </div>

        <div class="bg-box">
          <el-form
            ref="formRef"
            class="setting-box"
            :model="dnsParams"
            :rules="rules"
            label-width="auto"
            label-position="left"
            :validate-on-rule-change="false"
            @validate="validate"
          >
            <!-- 域名 -->
            <el-form-item prop="dnsDomain" :label="$t('COMMON_DOMAIN')">
              <el-popover
                v-model:visible="focusState.dnsDomain"
                popper-class="wrap-el-popper"
                width="376px"
                placement="right-start"
                trigger="focus"
                trigger-keys
              >
                <div class="popper-content">
                  <div class="item">{{ $t('IBMC_DOMAIN_TIP1') }}</div>
                  <div class="item">{{ $t('IBMC_DOMAIN_TIP2', [67]) }}</div>
                  <div class="item">{{ $t('IBMC_DOMAIN_TIP3') }}</div>
                  <div class="item">{{ $t('IBMC_DOMAIN_TIP4') }}</div>
                  <div class="item">{{ $t('IBMC_DOMAIN_TIP5') }}</div>
                </div>
                <template #reference>
                  <el-input
                    v-model="dnsParams.dnsDomain"
                    v-addId.input="'dnsDomain'"
                    v-clearable
                    clearable
                    maxlength="67"
                    :disabled="dnsParams.dnsAddress !== 'Static' || lock || !permission"
                    @input="input('dnsDomain', $event)"
                    @focus="focusState.dnsDomain = true"
                    @blur="focusState.dnsDomain = false"
                    @clear="clear('dnsDomain')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>

            <!-- 首选服务器 -->
            <el-form-item prop="dnsServer" :label="$t('IBMC_IP_ADDRESS06')">
              <el-popover
                v-model:visible="focusState.dnsServer"
                popper-class="no-wrap-popper"
                placement="right"
                :teleported="false"
                :content="$t('IBMC_DNS_TIP_CHECK')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="dnsParams.dnsServer"
                    v-addId.input="'dnsPreferred'"
                    v-clearable
                    clearable
                    :disabled="dnsParams.dnsAddress !== 'Static' || lock || !permission"
                    @input="input('dnsServer', $event)"
                    @focus="focusState.dnsServer = true"
                    @blur="focusState.dnsServer = false"
                    @clear="clear('dnsServer')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>

            <!-- 备选服务器1 -->
            <el-form-item prop="dnsServer1" :label="$t('IBMC_IP_ADDRESS07_1')">
              <el-popover
                v-model:visible="focusState.dnsServer1"
                popper-class="no-wrap-popper"
                placement="right"
                :teleported="false"
                :content="$t('IBMC_DNS_TIP_CHECK')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="dnsParams.dnsServer1"
                    v-addId.input="'dnsServer1'"
                    v-clearable
                    clearable
                    :disabled="dnsParams.dnsAddress !== 'Static' || lock || !permission"
                    @input="input('dnsServer1', $event)"
                    @focus="focusState.dnsServer1 = true"
                    @blur="focusState.dnsServer1 = false"
                    @clear="clear('dnsServer1')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>

            <!-- 备选服务器2 -->
            <el-form-item prop="dnsServer2" :label="$t('IBMC_IP_ADDRESS07_2')">
              <el-popover
                v-model:visible="focusState.dnsServer2"
                popper-class="no-wrap-popper"
                placement="right"
                :teleported="false"
                :content="$t('IBMC_DNS_TIP_CHECK')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="dnsParams.dnsServer2"
                    v-addId.input="'dnsServer2'"
                    v-clearable
                    clearable
                    :disabled="dnsParams.dnsAddress !== 'Static' || lock || !permission"
                    @input="input('dnsServer2', $event)"
                    @focus="focusState.dnsServer2 = true"
                    @blur="focusState.dnsServer2 = false"
                    @clear="clear('dnsServer2')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </el-form>
        </div>

        <el-button
          v-if="permission"
          id="dnsButton"
          :disabled="saveBtnState || lock"
          type="primary"
          @click="dialogVisible = true"
        >
          {{ $t('COMMON_SAVE') }}
        </el-button>
      </div>
    </div>

    <!-- 点击保存的弹窗 -->
    <div v-if="dialogVisible" v-reqKeepAlive.dialog>
      <el-dialog
        v-model="dialogVisible"
        :title="$t('ALARM_OK')"
        :close-on-click-modal="false"
      >
        <div class="content">
          <el-icon>
            <IconAlarm />
          </el-icon>
          <span id="dnsTipText" class="text">{{ $t('IBMC_SAVE_DNS_POP_UP_BOX') }}</span>
        </div>

        <template #footer>
          <span class="dialog-footer">
            <el-button id="dnsSave" type="primary" @click="sureSetting">
              {{ $t('NETWORK_PORT_CHANGE_OK') }}
            </el-button>
            <el-button id="dnsCancel" @click="dialogVisible = false">
              {{ $t('COMMON_CANCEL') }}
            </el-button>
          </span>
        </template>
      </el-dialog>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.box {
  margin-top: 8px;
  padding: 24px;
  background-color: var(--o-bg-color-base);
  border-radius: 4px;

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

  .row {
    display: flex;
    align-items: flex-start;

    .key {
      color: var(--o-text-color-secondary);
      font-size: 12px;
      width: 160px;
    }

    .check-mode {
      margin-right: 24px;
    }

    .content {
      flex: 1;
      margin-left: 16px;

      .radio-box {
        .el-radio.el-radio--large {
          height: auto;
        }
      }

      .bg-box {
        width: 100%;
        margin: 16px 0 24px;
        padding: 24px;
        border-radius: 4px;
        background-color: var(--o-bg-color-light);

        .setting-box {
          .el-input {
            width: 320px;
          }

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

          .el-form-item:nth-last-child(1) {
            margin-bottom: 0;
          }
        }
      }
    }
  }

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

    .content {
      display: flex;

      .el-icon {
        margin-right: 16px;
        font-size: 28px;
      }

      .text {
        padding-top: 5px;
      }
    }
  }

  :deep(.el-popper) {
    min-width: auto !important;
    width: auto !important;
  }
}
</style>
