<script lang="ts" setup>
import { IGeneric } from '@/model/base-interface';
import { getGenericInfo } from '@/services/header/header.service';
import { getSSLCertificates, getSSLGMCertificates } from '@/services/web-service';
import { getStoreData, loading, setStoreData } from '@/utils/composition';
import { traduction } from '@/utils/language';
import { computed, reactive, ref } from 'vue';
import Certificate from './components/ssl/Certificate.vue';
import ServerCertDialog from './components/ssl/ServerCertDialog.vue';
import useStore from '@/stores';
import { CertSeriesIndex, ICertInfo, ICertSeries } from '../../models/type';
import Dialog from '@/components/Dialog/Dialog.vue';
import CustomCertDialog from './components/ssl/CustomCertDialog.vue';
import serverImg from '@/assets/common/image/ssl-server-cert.svg';
import customImg from '@/assets/common/image/ssl-custom-cert.svg';
import { deepClone } from '@/utils/utils';

setStoreData('glob', 'showPresetMessage', false);
const certList = ref([] as ICertSeries[]);
const rootCredentialDataShow = ref(false);
const certificateSigningRequest = ref(false);
const showCert = ref(false);
const isPresetCert = ref(false);
const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const dialogConfig = reactive({
  title: traduction('COMMON_CER_UPLOAD'),
  content: '',
  modalClass: 'cert-select-dialog',
  okButton: { hide: true },
  cancelButton: { hide: true },
});
const dialogRef = ref();
const showUploadCustomCert = ref(false);
const showUploadServerCert = ref(false);

const tabList = [
  {
    name: 'intl',
    label: traduction('CERT_INTL_TABNAME'),
  },
  {
    name: 'gm',
    label: traduction('CERT_GM_TABNAME'),
  },
] as const;

const availableTabs = ref<any>([tabList[0]]);
type TabNames = typeof tabList[number]['name'];

const activeName = ref<TabNames>('intl');

// SSL证书
const serverInfoTemplate: ICertInfo[] = [
  {
    id: 'serverSigner',
    label: traduction('SERVICE_WBS_CRE_SIGNER'),
    value: '',
  },
  {
    id: 'serverUser',
    label: traduction('SERVICE_WBS_CRE_USER'),
    value: '',
  },
  {
    id: 'serverDate',
    label: traduction('SERVICE_WBS_CRE_VALID_DATE'),
    value: '',
  },
  {
    id: 'serverSn',
    label: traduction('COMMON_SERIALNUMBER'),
    value: '',
  },
  {
    id: 'serverSAN',
    label: traduction('IBMC_SUBJECT_ALTERNATIVE_NAME'),
    value: '',
  },
];

// 根证书
const rootCredentialDataTemplate: ICertInfo[] = [
  {
    id: 'rootSigner',
    label: traduction('SERVICE_WBS_CRE_SIGNER'),
    value: '',
  },
  {
    id: 'rootUser',
    label: traduction('SERVICE_WBS_CRE_USER'),
    value: '',
  },
  {
    id: 'rootDate',
    label: traduction('SERVICE_WBS_CRE_VALID_DATE'),
    value: '',
  },
  {
    id: 'rootSn',
    label: traduction('COMMON_SERIALNUMBER'),
    value: '',
  },
];

const certUploadType = [
  {
    id: 'serverCertUpload',
    img: serverImg,
    label: traduction('CERT_SERVER_TITLE'),
    content: traduction('CERT_CSR_IMPORT_SERVER_CERT'),
  },
  {
    id: 'customCertUpload',
    img: customImg,
    label: traduction('CERT_CUSTOM_TITLE'),
    content: traduction('CERT_IMPORT_CUSTOM_CERT'),
  },
];

// 获取Web服务信息
webGetInit();
function webGetInit() {
  loading(true);
  getGenericInfo()
    .then((res: IGeneric) => {
      setStoreData(
        'loct',
        'customeCertFlag',
        res.customeCertFlag !== undefined ? res.customeCertFlag : true,
      );
      isPresetCert.value = !getStoreData('loct', 'customeCertFlag');
    })
    .catch(() => {
      loading(false);
    });

  getSSLCertificates()
    .then(res => {
      drawCert(res, CertSeriesIndex.SSL);
      loading(false);
    })
    .catch(() => {
      loading(false);
    });

  getSSLGMCertificates()
    .then(res => {
      const enc = {} as any;
      const sig = {} as any;
      if (res.GmTlsSupported) {
        availableTabs.value = [...tabList];
      }
      Object.keys(res).forEach(key => {
        const [prefix, realName] = key.match(/[A-Z][a-z]*/g) as string[];
        if (prefix.includes('Enc')) {
          enc[`${realName}Cert`] = res[key];
        } else {
          sig[`${realName}Cert`] = res[key];
        }
      });
      if (!Array.isArray(enc.ServerCert)) {
        drawCert(enc, CertSeriesIndex.ENC);
      }
      if (!Array.isArray(sig.ServerCert)) {
        drawCert(sig, CertSeriesIndex.SIG);
      }
      loading(false);
    }).catch(() => {
      loading(false);
    });
}

// 证书信息显示
function drawCert(webData: any, drawToIndex: CertSeriesIndex): void {
  // 证书信息
  const serverInfo = deepClone(serverInfoTemplate);
  serverInfo[0].value = webData.ServerCert.Issuer;
  serverInfo[1].value = webData.ServerCert.Subject;
  serverInfo[2].value =
    webData.ServerCert.ValidNotBefore +
    traduction('SERVICE_WBS_CRE_VALID_DATE_TO') +
    webData.ServerCert.ValidNotAfter;
  serverInfo[3].value = webData.ServerCert.SerialNumber;
  serverInfo[4].value = webData.ServerCert.AlternativeNames?.join(',');
  const RootCert = webData.RootCert;
  certificateSigningRequest.value = webData.ServerCert.CertificateSigningRequest ? true : false;

  // 根证书
  const rootCredentialData = deepClone(rootCredentialDataTemplate);
  if (RootCert) {
    rootCredentialDataShow.value = true;
    rootCredentialData[0].value = RootCert.Issuer;
    rootCredentialData[1].value = RootCert.Subject;
    rootCredentialData[2].value =
      RootCert.ValidNotBefore +
      traduction('SERVICE_WBS_CRE_VALID_DATE_TO') +
      RootCert.ValidNotAfter;
    rootCredentialData[3].value = RootCert.SerialNumber;
  } else {
    rootCredentialDataShow.value = false;
  }
  // 中间证书
  const intermediateCert = webData.IntermediateCert;
  const interCertInfo = drawMediateCert(intermediateCert);

  const newValue = [...certList.value] as ICertSeries[];
  newValue[drawToIndex] = {
    server: serverInfo,
    middle: interCertInfo,
    root: rootCredentialData,
  };
  certList.value = newValue;
  showCert.value = true;
}

function drawMediateCert(intermediateCert: any) {
  const middleCredentialData = [] as ICertInfo[][];
  if (intermediateCert && JSON.stringify(intermediateCert) !== '{}') {
    for (const key of intermediateCert) {
      const item: ICertInfo[] = [
        {
          id: 'middleSigner',
          label: traduction('SERVICE_WBS_CRE_SIGNER'),
          value: key.Issuer,
        },
        {
          id: 'middleUser',
          label: traduction('SERVICE_WBS_CRE_USER'),
          value: key.Subject,
        },
        {
          id: 'middleDate',
          label: traduction('SERVICE_WBS_CRE_VALID_DATE'),
          value:
            key.ValidNotBefore + traduction('SERVICE_WBS_CRE_VALID_DATE_TO') + key.ValidNotAfter,
        },
        {
          id: 'middleSn',
          label: traduction('COMMON_SERIALNUMBER'),
          value: key.SerialNumber,
        },
      ];
      middleCredentialData.push(item);
    }
  }
  return middleCredentialData;
}

// 打开导入证书弹窗
function openCertDialog() {
  dialogRef.value.show();
}

// 关闭导入证书弹窗
function dialogClose(isNeedRefresh?: boolean) {
  dialogRef.value.hide();
  showUploadServerCert.value = false;
  showUploadCustomCert.value = false;
  if (isNeedRefresh) {
    webGetInit();
  }
}

function chooseUploadType(type: string) {
  dialogRef.value.hide();
  if (type === 'serverCertUpload') {
    showUploadServerCert.value = true;
  } else {
    showUploadCustomCert.value = true;
  }
}
</script>

<template>
  <div id="SSLCert" class="page-view">
    <div class="certificate module">
      <el-tabs v-model="activeName">
        <el-tab-pane v-for="tab in availableTabs" :key="tab.name" :label="tab.label" :name="tab.name">
          <el-button
            v-if="!isSystemLock"
            id="webSslButton"
            v-privil.security
            type="primary"
            class="button-ssl"
            @click="openCertDialog"
          >
            {{ $t('COMMON_CER_UPLOAD') }}
          </el-button>
          <template v-if="activeName === 'intl' && certList[0]">
            <!-- 证书信息 -->
            <Certificate
              v-show="showCert"
              :title="'SERVICE_WBS_SERVER_CRE_INFO'"
              :data="certList[0].server"
            ></Certificate>
            <!-- 中间证书信息 -->
            <Certificate
              v-for="(cert, index) in certList[0].middle"
              v-show="showCert"
              :key="index"
              :title="'SERVICE_WBS_MIDDLE_CRE_INFO'"
              :data="cert"
            ></Certificate>
            <!-- 根证书信息 -->
            <Certificate
              v-show="rootCredentialDataShow && showCert"
              :title="'SERVICE_WBS_ROOT_CRE_INFO'"
              :data="certList[0].root"
            ></Certificate>
          </template>
          <template v-else-if="activeName === 'gm'">
            <template v-if="certList[1]">
              <!-- 证书信息 -->
              <Certificate
                v-show="showCert"
                :title="'CERT_GM_ENC'"
                :data="certList[1].server"
              ></Certificate>
              <!-- 中间证书信息 -->
              <Certificate
                v-for="(cert, index) in certList[1].middle"
                v-show="showCert"
                :key="index"
                :title="'SERVICE_WBS_MIDDLE_CRE_INFO'"
                :data="cert"
              ></Certificate>
              <!-- 根证书信息 -->
              <Certificate
                v-show="rootCredentialDataShow && showCert"
                :title="'SERVICE_WBS_ROOT_CRE_INFO'"
                :data="certList[1].root"
              ></Certificate>
            </template>
            <template v-if="certList[2]">
              <!-- 证书信息 -->
              <Certificate
                v-show="showCert"
                :title="'CERT_GM_SIG'"
                :data="certList[2].server"
              ></Certificate>
              <!-- 中间证书信息 -->
              <Certificate
                v-for="(cert, index) in certList[2].middle"
                v-show="showCert"
                :key="index"
                :title="'SERVICE_WBS_MIDDLE_CRE_INFO'"
                :data="cert"
              ></Certificate>
              <!-- 根证书信息 -->
              <Certificate
                v-show="rootCredentialDataShow && showCert"
                :title="'SERVICE_WBS_ROOT_CRE_INFO'"
                :data="certList[2].root"
              ></Certificate>
            </template>
          </template>
        </el-tab-pane>
      </el-tabs>

    </div>
  </div>
  <ServerCertDialog
    v-if="showUploadServerCert"
    :is-gm="activeName === 'gm'"
    :data="certList[activeName === 'intl' ? 0 : 1]?.server?.[0]?.value ?? ''"
    @close="dialogClose"
  ></ServerCertDialog>
  <Dialog ref="dialogRef" :config="dialogConfig" @close="dialogClose">
    <template #other>
      <div class="upload-select-dialog">
        <div
          v-for="type in certUploadType"
          :id="type.id"
          :key="type.id"
          class="upload-div"
          @click="chooseUploadType(type.id)"
        >
          <img class="upload-icon" :src="type.img" />
          <div>
            <div class="upload-label">{{ type.label }}</div>
            <div class="upload-content">{{ type.content }}</div>
          </div>
        </div>
      </div>
    </template>
  </Dialog>
  <CustomCertDialog v-if="showUploadCustomCert" :is-gm="activeName === 'gm'" @close="dialogClose"></CustomCertDialog>
</template>

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

  .certificate {
    padding-bottom: 16px;
  }

  .button-ssl {
    margin-bottom: 8px;
    margin-top: 16px;
  }
}
.upload-select-dialog {
  width: 100%;
}
.upload-div {
  display: flex;
  padding: 12px 16px;
  border-radius: 2px;
  border: 1px solid var(--o-bg-color-light);
  background-color: var(--o-bg-color-light);
  &:first-child {
    margin-bottom: 8px;
  }
  &:hover {
    border: 1px solid var(--o-color-primary-secondary);
  }
}

.upload-icon {
  width: 32px;
  margin-right: 16px;
}

.upload-label {
  font-size: 14px;
  font-weight: 600;
  line-height: 20px;
  color: var(--o-text-color-primary);
}

.upload-content {
  margin-top: 4px;
  color: var(--o-text-color-tertiary);
}
</style>
