<script setup lang="ts">
import { traduction } from '@/utils/language';
import { DomainValidators } from '@/validators/domain-validators';
import { ElForm } from 'element-plus';
import { computed, nextTick, PropType, reactive, ref, toRefs } from 'vue';
import { IDHCPData, INtpModal, IRadio } from '../models/ntp.datatype';
import { ntpCtrlFactory } from '../util/ntp.util';
import useStore from '@/stores';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';

const props = defineProps({
  data: {
    type: Object as PropType<IDHCPData>,
    required: true,
    default: () => {
      return {};
    },
  },
});
const { data } = toRefs(props);
const dhcpData = reactive(data.value);
const originMode = dhcpData.addressMode;
const ntpControl = ref([] as any);
const ntpControlAlt = ref([] as any);
const emit = defineEmits(['change']);
const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const hasBasicConfig = checkPrivil(UserPrivil.baseConfig);
// 表单校验结果
let validateResult = {};
const radioList: IRadio[] = [
  {
    key: 'NTP_DHCPV4_AUTOGET',
    id: 'IPv4',
    disable: !dhcpData.dhcpv4Enable,
  },
  {
    key: 'NTP_DHCPV6_AUTOGET',
    id: 'IPv6',
    disable: !dhcpData.dhcpv6Enable,
  },
  {
    key: 'NTP_MANUAL_CONFIGURATION',
    id: 'Static',
    disable: false,
  },
];

const ntpModel: INtpModal = {
  server: {
    id: 'serverPreferred',
    label: 'NTP_SERVER',
    value: '',
    count: 3,
    tip: traduction('COMMON_IPV4_IPV6_DOMIN'),
  },
  serverPreferred: {
    id: 'serverPreferred',
    label: 'NTP_SERVER_PREFERRED',
    value: '',
    count: 3,
    tip: traduction('COMMON_IPV4_IPV6_DOMIN'),
  },
  serverAlternate: {
    id: 'serverAlternate',
    label: 'NTP_SERVER_ALTERNATE',
    value: '',
    count: 3,
    tip: traduction('COMMON_IPV4_IPV6_DOMIN'),
  },
};

const formRules = reactive({
  server: DomainValidators.ipv46AndDomin(),
} as any);

const popoverVisible = reactive({});
const ruleFormRef = ref();

const serverData = reactive({} as any);

function init() {
  const ntpCount = dhcpData.serverCount || 3;
  if (ntpCount === 3) {
    const ntpValue = [];
    ntpValue.push(dhcpData.preferredServer || '');
    ntpValue.push(dhcpData.alternateServer || '');
    ntpValue.push(dhcpData.extraServer || '');
    ntpControl.value = ntpCtrlFactory(ntpModel.server, ntpValue, serverData, popoverVisible);
  } else {
    const arr = dhcpData.extraServer.split(',');
    // 主选服务器IP数组
    const ntpValuePre = [];
    // 备选服务器IP数组
    const ntpValueAlt = [];
    ntpValuePre.push(dhcpData.preferredServer || '');
    ntpValuePre.push(dhcpData.alternateServer || '');
    if (dhcpData.extraServer.indexOf(',') > -1) {
      ntpValuePre.push(arr[0] || '');
      ntpValueAlt.push(arr[1] || '');
      ntpValueAlt.push(arr[2] || '');
      ntpValueAlt.push(arr[3] || '');
    } else {
      ntpValuePre.push(dhcpData.extraServer || '');
      ntpValueAlt.push('', '', '');
    }
    ntpControl.value = ntpCtrlFactory(
      ntpModel.serverPreferred,
      ntpValuePre,
      serverData,
      popoverVisible,
    );
    ntpControlAlt.value = ntpCtrlFactory(
      ntpModel.serverAlternate,
      ntpValueAlt,
      serverData,
      popoverVisible,
    );
  }
}

// 输入框 发生input 事件
function input(key: string, value: string) {
  serverData[key] = value;
  validateResult[key] = formRules['server'].validator(
    formRules['server'],
    serverData[key],
    () => {},
  );
  nextTick(() => {
    setSaveBtnState();
  });
}

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

function setSaveBtnState() {
  // 表单是否通过了校验
  const params = {};
  for (let key in validateResult) {
    // 任意一个校验失败
    if (!validateResult[key]) {
      emit('change', false, params);
      return;
    }
  }

  if (dhcpData.addressMode !== originMode) {
    params['AddressMode'] = dhcpData.addressMode;
  }

  if (ntpControlAlt.value.length === 0) {
    if (dhcpData.preferredServer !== serverData.serverPreferred0) {
      params['PreferredServer'] = serverData.serverPreferred0;
    }
    if (dhcpData.alternateServer !== serverData.serverPreferred1) {
      params['AlternateServer'] = serverData.serverPreferred1;
    }

    if (dhcpData.extraServer !== serverData.serverPreferred2) {
      params['ExtraServer'] = serverData.serverPreferred2;
    }
  } else {
    if (dhcpData.preferredServer !== serverData.serverPreferred0) {
      params['PreferredServer'] = serverData.serverPreferred0;
    }
    if (dhcpData.alternateServer !== serverData.serverPreferred1) {
      params['AlternateServer'] = serverData.serverPreferred1;
    }

    const extraServer =
      serverData.serverPreferred2 +
      ',' +
      serverData.serverAlternate0 +
      ',' +
      serverData.serverAlternate1 +
      ',' +
      serverData.serverAlternate2;
    if (dhcpData.extraServer !== extraServer) {
      params['ExtraServer'] = extraServer;
    }
  }

  emit('change', true, params);
}
init();

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);
  }
}
</script>

<template>
  <div class="dhcp-box">
    <el-radio-group v-model="dhcpData.addressMode" @change="setSaveBtnState">
      <el-radio
        v-for="option in radioList"
        :id="option.id"
        :key="option.id"
        :label="option.id"
        :disabled="option.disable || isSystemLock || !hasBasicConfig"
      >
        {{ $t(option.key) }}
      </el-radio>
    </el-radio-group>
    <div class="server">
      <el-form
        ref="ruleFormRef"
        :model="serverData"
        :rules="formRules"
        label-position="left"
        label-width="auto"
        class="dhcp-form"
        :validate-on-rule-change="false"
        @validate="validate"
      >
        <div v-if="ntpControlAlt.length === 0" class="ntp-server-static">
          <el-form-item
            v-for="server in ntpControl"
            :key="server.id"
            class="ntp-server-static-item"
            :label="$t(server.label)"
            :rules="formRules.server"
            :prop="server.id"
          >
            <el-popover
              v-model:visible="popoverVisible[server.id]"
              popper-class="no-wrap-popover"
              placement="right"
              :content="server.tip"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-model="serverData[server.id]"
                  v-addId.input="server.id"
                  v-clearable
                  clearable
                  :disabled="isSystemLock || !hasBasicConfig || dhcpData.addressMode !== 'Static'"
                  @focus="focus(server.id)"
                  @blur="blur(server.id)"
                  @input="input(server.id, $event)"
                  @clear="clear(server.id)"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>

        <div v-else class="ntp-serve-alter">
          <div class="ntp-server preferred">
            <el-form-item
              v-for="server in ntpControl"
              :key="server.id"
              class="ntp-server-item"
              :label="$t(server.label)"
              :rules="formRules.server"
              :prop="server.id"
            >
              <el-popover
                v-model:visible="popoverVisible[server.id]"
                popper-class="no-wrap-popover"
                placement="right"
                :content="traduction(server.tip)"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="serverData[server.id]"
                    v-addId.input="server.id"
                    v-clearable
                    clearable
                    :disabled="isSystemLock || !hasBasicConfig || dhcpData.addressMode !== 'Static'"
                    @focus="focus(server.id)"
                    @blur="blur(server.id)"
                    @input="input(server.id, $event)"
                    @clear="clear(server.id)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </div>

          <div class="ntp-server">
            <el-form-item
              v-for="server in ntpControlAlt"
              :key="server.id"
              class="ntp-server-item alert"
              :label="$t(server.label)"
              :rules="formRules.server"
              :prop="server.id"
            >
              <el-popover
                v-model:visible="popoverVisible[server.id]"
                popper-class="no-wrap-popover"
                placement="right"
                :content="traduction(server.tip)"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="serverData[server.id]"
                    v-addId.input="server.id"
                    v-clearable
                    clearable
                    :disabled="isSystemLock || !hasBasicConfig || dhcpData.addressMode !== 'Static'"
                    @focus="focus(server.id)"
                    @blur="blur(server.id)"
                    @input="input(server.id, $event)"
                    @clear="clear(server.id)"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
          </div>
        </div>
      </el-form>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.dhcp-box {
  width: 100%;
  .ntp-server {
    display: flex;
  }

  .ntp-server-static {
    background: var(--o-bg-color-light);
    border-radius: 2px;
    padding: 24px 24px 0 24px;
    border: 1px solid var(--o-bg-color-light);
    .ntp-server-static-item {
      margin-bottom: 24px;
    }
  }
  .ntp-server-item {
    background: var(--o-bg-color-light);
    border-radius: 2px;
    padding: 24px 24px 0 24px;
    margin-right: 16px;
  }

  .alert {
    padding-bottom: 24px;
  }

  .ntp-serve-alter {
    .ntp-server-item {
      width: calc((100% - 32px) / 3);
      &:last-child {
        margin-right: 0;
      }
    }
    .el-input {
      width: 100% !important;
    }
  }
}
</style>
