<script lang="ts" setup>
import { computed, nextTick, reactive, ref } from 'vue';
import { getErrorTranslate, traduction } from '@/utils/language';
import { getWebService, setWebService } from '@/services/web-service';
import useStore from '@/stores';
import { rangeVerification } from '@/validators/validation-functions';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import { loading, showFailedMessage, showSuccessMessage } from '@/utils/composition';
import { LDAP_PAGE_ENABLED } from '@/model/configure';

loading(true);
const store = useStore();
let origin = '';
const buttonDisable = ref(true);
let params = {};

const ruleFormRef = ref();
// 表单校验结果
let validateResult = {};
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});

const hasSecurityConfig = checkPrivil(UserPrivil.securityConfig);
const hasBasicConfig = checkPrivil(UserPrivil.baseConfig);

const dialogRef = ref();
const dialogConfig = reactive({
  id: 'httpsStateMessage',
  content: traduction('SERVICE_WBS_HTTPS_TIP', { softwareName: store.state.loct.sn }),
  title: traduction('COMMON_CONFIRM')
});

const radioModelList: { key: string; id: string; disable: boolean }[] = [
  {
    key: traduction('SERVICE_SHARED'),
    id: 'Shared',
    disable: !hasBasicConfig
  },
  {
    key: traduction('SERVICE_EXCLUSIVE'),
    id: 'Private',
    disable: !hasBasicConfig
  }
];

const popoverVisible = reactive({
  HTTP: false,
  HTTPS: false,
  TimeoutMinutes: false
});

// 端口校验规则 1.必填 2.数字 3.整型 4.范围1-65535
const formRules = reactive({
  port: {
    type: 'number',
    isInteger: true,
    required: true,
    min: 1,
    max: 65535,
    message: traduction('VALID_VALUE_RANGE_TIP', [1, 65535]),
    validator: rangeVerification,
    trigger: 'change'
  },
  time: {
    type: 'number',
    isInteger: true,
    required: true,
    min: 5,
    max: 480,
    message: traduction('VALID_VALUE_RANGE_TIP', [5, 480]),
    validator: rangeVerification,
    trigger: 'change'
  }
});

const config = reactive({
  data: {
    HTTP: { Enabled: false, Port: '0' },
    HTTPS: { Enabled: false, Port: '0' },
    WebSession: { TimeoutMinutes: '0', Mode: 'Shared' }
  }
});

// 获取Web服务信息
webGetInit();
function webGetInit() {
  getWebService()
    .then(res => {
      origin = JSON.stringify(res);
      Object.assign(config.data, res);
      loading(false);
    })
    .catch(() => {
      loading(false);
    });
}

// 恢复默认值
function resetHttpPort() {
  config.data.HTTP.Port = '80';
  ruleFormRef.value.validateField('HTTP.Port');
}

function resetHttpsPort() {
  config.data.HTTPS.Port = '443';
  ruleFormRef.value.validateField('HTTPS.Port');
}

// 输入框 发生input 事件
function input(key: string, value: string) {
  if (key === 'TimeoutMinutes') {
    config.data.WebSession.TimeoutMinutes = value;
    validateResult[key] = formRules.time.validator(
      formRules.time,
      config.data.WebSession.TimeoutMinutes,
      () => {}
    );
  } else {
    config.data[key].Port = value;
    validateResult[key] = formRules.port.validator(formRules.port, config.data[key].Port, () => {});
  }
  nextTick(() => {
    setSaveBtnState();
  });
}

// 表单校验发生时 - 控制保存按钮状态 state:校验结果
function validate(keyParams: string, state: boolean) {
  let key = keyParams;
  if (key.indexOf('TimeoutMinutes') > -1) {
    key = 'TimeoutMinutes';
  } else if (key.indexOf('HTTPS') > -1) {
    key = 'HTTPS';
  } else {
    key = 'HTTP';
  }
  validateResult[key] = state;
  nextTick(() => {
    setSaveBtnState();
  });
}

// 数据是否发生变化
function setSaveBtnState() {
  buttonDisable.value = true;
  // 1. 表单是否通过了校验
  for (let key in validateResult) {
    // 任意一个校验失败
    if (!validateResult[key]) {
      return;
    }
  }

  // 2. 数据是否发生了变化
  const curData = config.data;
  const originData = JSON.parse(origin);
  params = {};
  const HTTP = {};
  const HTTPS = {};
  const webSession = {};
  if (curData.HTTP.Enabled !== originData.HTTP.Enabled) {
    HTTP['Enabled'] = curData.HTTP.Enabled;
  }
  if (Number(curData.HTTP.Port) !== originData.HTTP.Port) {
    HTTP['Port'] = Number(curData.HTTP.Port);
  }
  if (curData.HTTPS.Enabled !== originData.HTTPS.Enabled) {
    HTTPS['Enabled'] = curData.HTTPS.Enabled;
  }
  if (Number(curData.HTTPS.Port) !== originData.HTTPS.Port) {
    HTTPS['Port'] = Number(curData.HTTPS.Port);
  }
  if (curData.WebSession.Mode !== originData.WebSession.Mode) {
    webSession['Mode'] = curData.WebSession.Mode;
  }
  if (Number(curData.WebSession.TimeoutMinutes) !== originData.WebSession.TimeoutMinutes) {
    webSession['TimeoutMinutes'] = Number(curData.WebSession.TimeoutMinutes);
  }
  if (Object.keys(HTTP).length !== 0) {
    params['HTTP'] = HTTP;
  }
  if (Object.keys(HTTPS).length !== 0) {
    params['HTTPS'] = HTTPS;
  }
  if (Object.keys(webSession).length !== 0) {
    params['WebSession'] = webSession;
  }

  if (JSON.stringify(params) !== '{}') {
    buttonDisable.value = false;
  }
}

// 提交基本配置
const submitForm = () => {
  if (JSON.stringify(params) === '{}') {
    return;
  }
  loading(true);
  setWebService(params).then(
    res => {
      loading(false);
      if (res?.data?.error) {
        showFailedMessage(getErrorTranslate(res?.data?.error[0]?.code));
        config.data = res?.data?.data;
      } else {
        showSuccessMessage(
          params?.['WebSession']?.['Mode'] !== undefined
            ? traduction('WEB_MODE_OPERATE_TIP')
            : traduction('COMMON_SUCCESS')
        );
        config.data = res.data;
      }

      buttonDisable.value = true;
      origin = JSON.stringify(config.data);

      // 端口修改成功
      if (
        params &&
        params['HTTPS'] &&
        params['HTTPS']['Port'] &&
        params['HTTPS']['Port'] === config.data.HTTPS.Port
      ) {
        window.location.port = config.data.HTTPS.Port;
      }
    },
    error => {
      loading(false);
      showFailedMessage(getErrorTranslate(error?.data?.error[0]?.code));
      buttonDisable.value = true;
      if (error?.data?.data) {
        config.data = error?.data?.data;
        origin = JSON.stringify(config.data);
      }
    }
  );
};

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

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

function clear(key: string) {
  // 如果没有focus,那么这个地方需要手动调用一次校验
  if (!popoverVisible[key]) {
    if (key === 'TimeoutMinutes') {
      ruleFormRef.value.validateField('WebSession.TimeoutMinutes');
    } else {
      ruleFormRef.value.validateField(key + '.Port');
    }
  }
}

function save() {
  if (params && params['HTTPS'] && params['HTTPS']['Enabled'] === false) {
    dialogRef.value.show();
  } else {
    submitForm();
  }
}

function dialogClose(reason: boolean) {
  dialogRef.value.hide();
  if (reason) {
    submitForm();
  }
}
</script>

<template>
  <div id="webView" class="page-view">
    <div class="basic-config module">
      <el-form
        ref="ruleFormRef"
        :model="config.data"
        :rules="formRules"
        label-position="left"
        label-width="auto"
        :validate-on-rule-change="false"
        @validate="validate"
      >
        <!-- HTTP -->
        <div class="config-item">
          <el-form-item :label="$t('SERVICE_HTTP')">
            <el-switch
              id="httpEnable"
              v-model="config.data.HTTP.Enabled"
              :disabled="!hasSecurityConfig || isSystemLock"
              @change="setSaveBtnState"
            ></el-switch>
          </el-form-item>
          <div class="web-right">
            <el-form-item :rules="formRules.port" :label="$t('SERVICE_PORT')" prop="HTTP.Port">
              <el-popover
                v-model:visible="popoverVisible.HTTP"
                popper-class="no-wrap-popover"
                placement="top"
                :content="traduction('VALIDTOR_RANGE')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="config.data.HTTP.Port"
                    v-addId.input="'httpPort'"
                    v-clearable
                    clearable
                    :disabled="!hasSecurityConfig || isSystemLock"
                    class="input-class"
                    type="text"
                    @focus="focus('HTTP')"
                    @blur="blur('HTTP')"
                    @input="input('HTTP', $event)"
                    @clear="clear('HTTP')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
            <a
              v-if="!isSystemLock"
              id="resetHttp"
              v-privil.security
              v-t="'SERVICE_DEFAULT_VALUE'"
              class="resetting"
              @click="resetHttpPort()"
            ></a>
          </div>
        </div>
        <!-- HTTPS -->
        <div class="config-item">
          <el-form-item :label="$t('SERVICE_HTTPS')">
            <el-switch
              id="httpsEnableId"
              v-model="config.data.HTTPS.Enabled"
              :disabled="!hasSecurityConfig || isSystemLock"
              @change="setSaveBtnState"
            ></el-switch>
          </el-form-item>
          <div class="web-right">
            <el-form-item :rules="formRules.port" :label="$t('SERVICE_PORT')" prop="HTTPS.Port">
              <el-popover
                v-model:visible="popoverVisible.HTTPS"
                popper-class="no-wrap-popover"
                placement="top"
                :content="traduction('VALIDTOR_RANGE')"
                trigger="focus"
                trigger-keys
              >
                <template #reference>
                  <el-input
                    v-model="config.data.HTTPS.Port"
                    v-addId.input="'httpsPort'"
                    v-clearable
                    clearable
                    class="input-class"
                    :disabled="!hasSecurityConfig || isSystemLock"
                    type="text"
                    @focus="focus('HTTPS')"
                    @blur="blur('HTTPS')"
                    @input="input('HTTPS', $event)"
                    @clear="clear('HTTPS')"
                  >
                    <template #suffix>
                      <ErrorIcon />
                      <ClearableIcon />
                    </template>
                  </el-input>
                </template>
              </el-popover>
            </el-form-item>
            <a
              v-if="!isSystemLock"
              id="resetHttps"
              v-privil.security
              v-t="'SERVICE_DEFAULT_VALUE'"
              class="resetting"
              @click="resetHttpsPort()"
            ></a>
          </div>
        </div>
        <!-- 超时时长 -->
        <div class="config-item long-input" v-if="LDAP_PAGE_ENABLED">
          <el-form-item
            :rules="formRules.time"
            :label="$t('SERVICE_TIME_OUT_MINUTES')"
            prop="WebSession.TimeoutMinutes"
          >
            <el-popover
              v-model:visible="popoverVisible.TimeoutMinutes"
              popper-class="no-wrap-popover"
              placement="top"
              :content="traduction('SERVICE_OVER_TIME_VALI_TIP')"
              trigger="focus"
              trigger-keys
            >
              <template #reference>
                <el-input
                  v-model="config.data.WebSession.TimeoutMinutes"
                  v-addId.input="'webTimeout'"
                  v-clearable
                  clearable
                  class="input-class"
                  :disabled="!hasBasicConfig || isSystemLock"
                  type="text"
                  @focus="focus('TimeoutMinutes')"
                  @blur="blur('TimeoutMinutes')"
                  @input="input('TimeoutMinutes', $event)"
                  @clear="clear('TimeoutMinutes')"
                >
                  <template #suffix>
                    <ErrorIcon />
                    <ClearableIcon />
                  </template>
                </el-input>
              </template>
            </el-popover>
          </el-form-item>
        </div>
        <!-- 会话模式 -->
        <div class="config-item" v-if="LDAP_PAGE_ENABLED">
          <el-form-item :label="$t('SERVICE_WBS_CONVERSE_MODEL')" class="session-mode">
            <el-radio-group
              v-model="config.data.WebSession.Mode"
              :disabled="!hasBasicConfig || isSystemLock"
            >
              <el-radio
                v-for="radio in radioModelList"
                :key="radio.id"
                v-addId.radio="radio.id"
                :label="radio.id"
                :disable="radio.disable"
                @change="setSaveBtnState"
              >
                {{ radio.key }}
              </el-radio>
            </el-radio-group>
          </el-form-item>
        </div>
        <el-form-item label=" ">
          <el-button
            v-if="hasSecurityConfig || hasBasicConfig"
            id="webServiceButton"
            type="primary"
            :disabled="buttonDisable"
            @click="save()"
          >
            {{ $t('COMMON_SAVE') }}
          </el-button>
        </el-form-item>
      </el-form>
    </div>
  </div>
  <Dialog ref="dialogRef" :config="dialogConfig" @close="dialogClose" />
</template>

<style lang="scss" scoped>
.page-view {
  padding-right: 24px;
  .module {
    background: var(--o-bg-color-base);
    border-radius: 4px;
    padding: 24px 24px 0 24px;
    border: 1px solid var(--o-bg-color-base);
  }

  .input-class {
    width: 192px;
  }

  .long-input .input-class {
    width: 320px;
  }

  .web-right {
    margin-left: 48px;
    display: flex;
    a {
      margin-left: 8px;
      margin-top: 8px;
    }
  }

  .button-ssl {
    margin-bottom: 8px;
  }

  .el-input__inner {
    font-size: 12px;
  }

  .resetting {
    color: var(--o-color-primary);
    cursor: pointer;
    font-weight: 600;
  }

  .el-radio {
    height: 16px;
  }

  :deep(.el-form-item__label::before) {
    display: none;
  }
}
</style>

<style lang="scss">
#webView {
  .config-item {
    display: flex;

    .el-form-item__label {
      display: flex;
    }
    .web-right {
      .el-form-item__label-wrap {
        margin-right: 16px !important;
        display: contents;
      }
    }

    .session-mode {
      height: 16px;
      margin-bottom: 24px;
      .el-form-item__label {
        padding-top: 0;
        padding-bottom: 0;
      }
    }
  }
}
</style>