<script lang="ts" setup>
import { reactive, ref, onMounted, computed } from 'vue';
import { getErrorTranslate, traduction } from '@/utils/language';
import {
  clientCertInfoAssemble,
  delRootCert,
  getTwoFactoryData,
  uploadClientCertFile,
  importClientCertificate,
} from '../twoFactor.service';
import { UploadRawFile, UploadFile } from 'element-plus/es/components/upload/src/upload';
import Dialog from '@/components/Dialog/Dialog.vue';
import GlobalStoreService from '@/services/gloabal-store-service';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import { setStoreData, showFailedMessage, showSuccessMessage } from '@/utils/composition';
import useStore from '@/stores';
import { escapeHeader } from '@/utils/utils';
const globService = new GlobalStoreService();
const hasUserConfigPrivil = checkPrivil(UserPrivil.userConfig);

const store = useStore();
let systemLock = computed(() => {
  return store.state.glob.systemLocked;
});

const tableDataRoot = reactive({
  data: [
    {
      id: 1,
      userName: '',
      user: '',
      issueBycertificateStatus: '',
      clientCertificateFingerprint: '--',
      revokedState: false,
      revokedStateValue: '',
      revokedDate: '--',
      isUpload: true,
      isClientUpload: false,
    },
  ],
});
const diaginfo = reactive({
  id: '',
  type: '',
  content: '',
  title: '',
});
const defaultCurrentPage = 1;
const defaultPageSize = 10;
const currentPage = ref(defaultCurrentPage);
const pageSize = ref(defaultPageSize);
const pageSizes = ref([10, 20, 30, 50]);
const layout = ref('total, sizes, prev, pager, next, jumper');
const total = ref(0);
const dialog = ref();
const tableData: any = ref([]);

let currentCertId: number = 1;
function handleSizeChange(val: number) {
  init(val);
}
function handleCurrentChange() {
  getData();
}
function getData() {
  tableData.value = tableDataRoot.data.slice(
    (currentPage.value - 1) * pageSize.value,
    currentPage.value * pageSize.value,
  );
}

function clientCertificateInit(resData: any) {
  tableDataRoot.data = clientCertInfoAssemble(resData);
  total.value = tableDataRoot.data.length;
  getData();
}
function delClientCertClick(certId: number) {
  diaginfo.id = 'delClient';
  diaginfo.type = 'warning';
  diaginfo.title = traduction('COMMON_CONFIRM');
  diaginfo.content = traduction('TWO_FACTORS_DELETE_CERTIFICATE_TIP');
  dialog.value.show();
  currentCertId = certId;
}
function dialogClose(val: boolean) {
  dialog.value.hide();
  if (val) {
    const param = {
      CertificateType: 1,
      ID: currentCertId,
    };
    delRootCert(param)
      .then(res => {
        showSuccessMessage();
        init();
      })
      .catch(err => {
        showFailedMessage();
      });
  }
}
const loct = localStorage.getItem('loct');
const uploadConfig = reactive({
  data: {
    action: '/UI/Rest/AccessMgnt/TwoFactorAuthentication/ImportClientCertificate',
    headers: {
      From: 'WebUI',
      'X-CSRF-Token': escapeHeader(loct ? JSON.parse(loct).to : ''),
    },
    method: 'POST',
    name: 'Content',
    data: { UserId: '' } as any,
    isAutoUpload: true,
    accept: '.cer,.pem,.crt',
    showList: false,
    onAddItem: (file: UploadRawFile): void | boolean => {
      let type = file.name.substring(file.name.lastIndexOf('.') + 1);
      if (!['cer', 'pem', 'crt'].includes(type)) {
        showFailedMessage(traduction('COMMON_FILE_SUFFIX_CER_PEM_CRT'));
        return false;
      } else if ((file.size as any) > 1024 * 1024) {
        showFailedMessage(traduction('COMMON_UPLOAD_FILE_MORN_1M_ERROR'));
        return false;
      } else {
        if (file) {
          updateCACertFile(file);
        }
      }
      return false;
    },
    onError: (error: any, file: UploadFile): void => {
      const errorCode = JSON.parse(error.message).error[0].code;
      if (errorCode === 'NoValidSession') {
        setStoreData(
          'event',
          'error401',
          `${traduction('SessionTimeout.errorMessage')}${Date.now()}`,
        );
      } else {
        const errorMsg = getErrorTranslate(errorCode);
        showFailedMessage(errorMsg);
      }
    },
    onSuccess: (response: any, file: UploadFile): void => {
      showSuccessMessage();
      init();
    },
  },
});
function updateCACertFile(file: any) {
  const clientFormData = new FormData();
  clientFormData.append('imgfile', file, file.name);
  uploadClientCertFile(clientFormData).then(() => {
    importClientCertificate(file.name, uploadConfig.data.data.UserId)
      .then(() => {
        showSuccessMessage();
        init();
      })
      .catch(error => {
        const errorCode = error?.data?.error?.[0]?.code;
        if (errorCode) {
          const errorMsg = getErrorTranslate(errorCode);
          showFailedMessage(errorMsg);
        } else {
          showFailedMessage();
        }
      });
  });
}
function clickUpload(id: number) {
  uploadConfig.data.data.UserId = id;
}
function init(size?: number) {
  globService.loading(true);
  getTwoFactoryData()
    .then((response: any) => {
      if (size) {
        pageSize.value = size;
        currentPage.value = 1;
      }
      const resData = response['data'];
      clientCertificateInit(resData);
      globService.loading(false);
    })
    .catch(error => {
      globService.loading(false);
    });
}
onMounted(() => {
  init();
});
function setRowClass(item: any) {
  const { row } = item;
  return `twofactor-client-row-${row.id}`;
}
</script>

<template>
  <div class="tables">
    <el-table
      v-addId.table="'clientTableId'"
      :data="tableData"
      :class="{ 'empty-table': tableData.length === 0 }"
      :row-class-name="setRowClass"
      style="width: 100%"
      resizable
      border
    >
      <el-table-column :label="$t('TWO_FACTORS_CERTIFICATES_ID')">
        <template #default="scope">
          <span class="twofactor-client-id">{{ scope.row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('COMMON_USERNAME')">
        <template #default="scope">
          <span class="twofactor-client-user-name">{{ scope.row.userName }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('COMMON_ROLE')">
        <template #default="scope">
          <span class="twofactor-client-user">{{ scope.row.user }}</span>
        </template>
      </el-table-column>
      <el-table-column
        :label="$t('TWO_FACTORS_ROOT_CERTIFICATE_STATE')"
        prop="issueBycertificateStatus"
      >
        <template #default="scope">
          <span class="twofactor-client-issue">{{ scope.row.issueBycertificateStatus }}</span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('TWO_FACTORS_REVOKED_STATE')">
        <template #default="scope">
          <span
            class="revoked twofactor-client-revoked"
            :class="{ revokedState: scope.row.revokedState }"
          >
            {{ scope.row.revokedStateValue }}
          </span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('TWO_FACTORS_REVOKED_TIME')">
        <template #default="scope">
          <span class="twofactor-client-revoked-data">{{ scope.row.revokedDate }}</span>
        </template>
      </el-table-column>
      <el-table-column
        :label="$t('TWO_FACTORS_CLIENT_CERTIFICATE_FINGERPRINT')"
        prop="clientCertificateFingerprint"
      >
        <template #default="scope">
          <span class="twofactor-client-fingerprint">
            {{ scope.row.clientCertificateFingerprint }}
          </span>
        </template>
      </el-table-column>
      <el-table-column :label="$t('COMMON_OPERATE')" class-name="twofactor-client-operate">
        <template #default="scope">
          <div v-if="scope.row.isUpload && hasUserConfigPrivil">
            <el-upload
              v-if="!systemLock"
              :id="`clientUploadId${scope.row.id}`"
              :headers="uploadConfig.data.headers"
              :name="uploadConfig.data.name"
              :data="uploadConfig.data.data"
              :action="uploadConfig.data.action"
              :accept="uploadConfig.data.accept"
              :show-file-list="uploadConfig.data.showList"
              :on-success="uploadConfig.data.onSuccess"
              :on-error="uploadConfig.data.onError"
              :before-upload="uploadConfig.data.onAddItem"
            >
              <span
                :id="`crlUploadId${scope.row.id}`"
                class="crlUpload"
                @click="clickUpload(scope.row.id)"
              >
                {{ $t('COMMON_UPLOAD') }}
              </span>
              <template #tip></template>
            </el-upload>
            <span
              v-if="systemLock"
              :id="`crlUploadId${scope.row.id}`"
              class="crlUpload disabled-btn"
            >
              {{ $t('COMMON_UPLOAD') }}
            </span>
          </div>
          <span
            v-if="!scope.row.isUpload && hasUserConfigPrivil && !systemLock"
            :id="`clientDelId${scope.row.id}`"
            v-t="'COMMON_DELETE'"
            class="clientCertDel"
            @click="delClientCertClick(scope.row.id)"
          ></span>
          <span
            v-if="!scope.row.isUpload && hasUserConfigPrivil && systemLock"
            :id="`clientDelId${scope.row.id}`"
            v-t="'COMMON_DELETE'"
            class="clientCertDel disabled-btn"
          ></span>
        </template>
      </el-table-column>
    </el-table>
    <div v-if="tableData.length == 0" class="no-data">
      <div class="no-data-img"></div>
      <span v-t="'COMMON_NO_DATA'" class="no-data-text"></span>
    </div>
    <el-pagination
      v-if="tableData.length > 0"
      v-model:currentPage="currentPage"
      v-addId.pagination="'clientPagination'"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      :layout="layout"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>
  </div>
  <Dialog ref="dialog" :config="diaginfo" @close="dialogClose"></Dialog>
</template>

<style lang="scss" scoped>
.tables {
  padding: 16px;
  background-color: var(--o-bg-color-base);
  position: relative;

  :deep(.el-pagination) {
    margin-top: 16px;
  }
}

.table-details {
  display: flex;
  padding: 16px 40px;
  justify-content: space-between;
  > div {
    width: calc(100% - 32px);
    .el-form-item {
      margin-bottom: 8px;
    }
  }
  :deep(.el-table__expanded-cell) {
    background-color: var(--o-bg-color-light);
  }
}
.table-details-title {
  font-size: 12px;
  color: var(--o-text-color-primary);
  line-height: 16px;
  font-weight: bold;
  padding-left: 40px;
}
.crlUpload {
  color: var(--o-color-primary);
  cursor: pointer;
  margin-right: 8px;
  &:hover {
    color: var(--o-color-primary-secondary);
  }
}
.clientCertDel {
  color: var(--o-color-primary);
  cursor: pointer;
  &:hover {
    color: var(--o-color-primary-secondary);
  }
}
.clientCertDel.disabled {
  color: var(--o-text-color-primary);
  cursor: not-allowed;
  &:hover {
    color: var(--o-text-color-primary);
  }
}
.revoked {
  display: inline-block;
  min-width: 64px;
  padding: 0 4px;
  height: 16px;
  line-height: 16px;
  background-color: var(--o-text-color-tertiary);
  color: #fff;
  text-align: center;
  border-radius: var(--i-button-border-radius);
}
.layout-patination {
  margin-left: 0;
}
:deep(.empty-table) {
  .el-table__body-wrapper {
    height: 450px !important;
  }
}
.el-table {
  min-height: 482px;
}
</style>
