<script setup lang="ts">
import useStore from '@/stores';
import { showElMessage, dataFilter } from '@/utils/utils';
import { traduction } from '@/utils/language';
import { onMounted, ref, reactive, computed } from 'vue';
import { ITableColumns } from '@/model/base-interface';
import { escapeHeader } from '@/utils/utils';
import { UserPrivil } from '@/model/base-enum';
import { getStoreData } from '@/utils/composition';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { IconList, IconThumbnail } from '@computing/opendesign-icons';
import { UploadRawFile, UploadFile } from 'element-plus/es/components/upload/src/upload';
import CaCardItem from './components/CaCardItem.vue';
import SearchInput from '@/components/SearchInput/SearchInput.vue';
import CaCertificateService from '../../../../services/caCertificate.service';
import GlobalStoreService from '@/services/gloabal-store-service';
import { showFailedMessage, showSuccessMessage } from '@/utils/composition';
import { getErrorTranslate } from '@/utils/language';
import NoDataAvailable from '@/components/NoDataAvailable/NoDataAvailable.vue';
import { IconAlarm } from '@computing/opendesign-icons';


const globalStoreService = new GlobalStoreService();
const store = useStore();
// 安全配置权限
const securityConfig = computed(() => {
  return checkPrivil(UserPrivil.securityConfig);
});
// 系统锁定状态
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
// 免密登录
const nopwd = getStoreData('loct', 'nopwd') || false;
const loct = localStorage.getItem('loct');

// 搜索的字段
const filterKeys: string[] = ['issuer', 'subject', 'time', 'serialNumber', 'crlTimeRange'];
const columns: ITableColumns[] = [
  {
    title: 'ALARM_REPORT_SYSLOG_USER',
    content: 'subject',
    width: '30%',
  },
  {
    title: 'ALARM_REPORT_SYSLOG_ISSUED',
    content: 'issuer',
    width: '30%',
  },
  {
    title: 'ALARM_REPORT_SYSLOG_EFFECTIVE',
    content: 'time',
    width: '15%',
  },
  {
    title: 'ALARM_REPORT_SYSLOG_REVOKING_LIST',
    content: 'isImportCrl',
    width: '15%',
  },
];

const searchContent = ref('');
const showType = ref(1);

const delDialog = ref();
const delDialogConfig = reactive({
  title: traduction('ALARM_OK'),
  content: traduction('COMMON_ASK_OK'),
});

const delCrlDialog = ref();
const delCrlDialogConfig = reactive({
  title: traduction('ALARM_OK'),
  content: '',
  okButton: {
    id: 'delCrlCertify_ok_btn',
  },
  cancelButton: {
    id: 'delCrlCertify_cancel_btn',
  }, 
});

const total = ref(4);
const pageSizes = ref([10, 20, 30, 50]);
const currentPage = ref(1);
const pageSize = ref(10);
const layout = ref('total, sizes, prev, pager, next, jumper');

// 所有数据
const dataList: any = reactive([]);
// 展示数据
const tableData: any = reactive([]);
// 点击删除的证书
let delItem: any = {};

function handleSizeChange(val: number) {
  pageSize.value = val;
  getData();
}
let fileRaw: UploadRawFile | undefined;
function handleCurrentChange() {
  getData();
}

// 证书上传的配置
const certConfig = reactive({
  action: '',
  accept: '.crt, .cer, .pem, .der',
  isAutoUpload: true,
  isNeedClearError: false,
  beforeUpload: (rawFile: UploadRawFile): void | boolean => {
    let type = rawFile.name.substring(rawFile.name.lastIndexOf('.') + 1);
    let acceptTypes = ['crt', 'cer', 'pem', 'der'];
    if (!acceptTypes.includes(type)) {
      showFailedMessage(traduction('COMMON_FILE_SUFFIX_CER_DER_CRT'));
      return false;
    } else if ((rawFile.size as any) > 100 * 1024) {
      showFailedMessage(traduction('COMMON_UPLOAD_FILE_MORN_100KB_ERROR4'));
      return false;
    } else {
      fileRaw = rawFile;
      if (fileRaw) {
        updateServerCertificate(fileRaw);
      }
    }
    return false;
  },
});

function updateServerCertificate(file: any) {
  const clientFormData = new FormData();
  clientFormData.append('imgfile', file, file.name);
  CaCertificateService.uploadCerFile(clientFormData).then(() => {
    CaCertificateService.imporCACertificate(file.name)
      .then(() => {
        showSuccessMessage();
        dataList.splice(0);
        getData();
      })
      .catch(error => {
        const errorCode = error?.data?.error?.[0]?.code;
        if (errorCode) {
          const errorMsg = getErrorTranslate(errorCode);
          showFailedMessage(errorMsg);
        } else {
          showFailedMessage();
        }
      });
  });
}

// 上传吊销列表的配置
function getCrlConfig(id: string) {
  return {
    url: '',
    autoUpload: true,
    accept: '.crl',
    name: 'Content',
    data: { CertificateType: '0', ID: id },
    beforeUpload: (rawFile: UploadRawFile): void | boolean => {
      const type = rawFile.name.substring(rawFile.name.lastIndexOf('.'));
      if (!['.crl'].includes(type)) {
        showElMessage('error', traduction('COMMON_FILE_SUFFIX_CRL'));
        return false;
      } else if ((rawFile.size as any) > 100 * 1024) {
        showElMessage('error', traduction('COMMON_UPLOAD_FILE_MORN_100KB_ERROR4'));
        return false;
      } else {
        fileRaw = rawFile;
        if (fileRaw) {
          updateCrlConfig(fileRaw, id);
        }
      }
      return false;
    },
  };
}

function updateCrlConfig(file: any, id: string) {
  const clientFormData = new FormData();
  clientFormData.append('imgfile', file, file.name);
  CaCertificateService.uploadCerFile(clientFormData).then(() => {
    CaCertificateService.importCerCtrl(file.name, id)
      .then(() => {
        showElMessage('success', traduction('COMMON_SUCCESS'));
        dataList.splice(0);
        
        getData();
      })
      .catch(error => {
        const errorCode = error?.data?.error[0]?.code;
        if (errorCode) {
          const errorMsg = getErrorTranslate(errorCode);
          showFailedMessage(errorMsg);
        } else {
          showFailedMessage();
        }
      });
  });
}
function initShowData() {
  const searchText = searchContent.value;
  // 输入框数据进行数据过滤
  let filterList = dataFilter(dataList, filterKeys, searchText);
  total.value = filterList.length;

  const showList = filterList.slice(
    (currentPage.value - 1) * pageSize.value,
    currentPage.value * pageSize.value,
  );
  tableData.push(...showList);
}

// 加工初始数据
function initData(data: any) {
  dataList.splice(0);
  data.forEach((item: any) => {
    // 上传了吊销列表
    if (item.CRLStartTime && item.CRLExpireTime) {
      item.crlTimeRange = item.CRLStartTime + ' - ' + item.CRLExpireTime;
      item.isImportCrl = true;
    } else {
      item.isImportCrl = false;
    }

    item.time = item.ValidNotBefore + ' - ' + item.ValidNotAfter;
    item.id = item.ID;
    // 字段首字母转小写
    Object.keys(item).forEach((key: string) => {
      const arr = key.split('');
      arr[0] = arr[0].toLowerCase();
      const value = item[key];
      delete item[key];
      item[arr.join('')] = value;
    });

    item.crlConfig = getCrlConfig(item.id);
    dataList.push(item);
  });
  initShowData();
}

// 获取数据列表
function getData() {
  tableData.splice(0);

  // 如果请求过数据，那么不再发送请求，直接对现有请求数据做重新组合，除非有进行证书相关的操作
  if (dataList.length > 0) {
    initShowData();
    return;
  }

  dataList.splice(0);
  globalStoreService.setValue('isLoading', true);
  CaCertificateService.getCaCertificateList()
    .then((res: any) => {
      dataList.splice(0);
      if (res && res.Count && res.Members) {
        total.value = res.Count;
        initData(res.Members);
      } else {
        total.value = 0;
      }
      globalStoreService.setValue('isLoading', false);
    })
    .catch((err: any) => {
      globalStoreService.setValue('isLoading', false);
    });
}

// 搜索框回车、搜索事件、清空事件
function searchInput(value: string) {
  searchContent.value = value;
  getData();
}

function delCert(item: any) {
  if (isSystemLock.value || !securityConfig.value) {
    return;
  }
  delItem = item;
  delDialog.value.show();
}

// 确认删除 / 点击取消
function sureDel(flag: boolean) {
  if (flag) {
    globalStoreService.setValue('isLoading', true);
    CaCertificateService.deletedCaCertificate('0', delItem.id)
      .then(() => {
        showSuccessMessage();
        delDialog.value.hide();
        globalStoreService.setValue('isLoading', false);
        dataList.splice(0);
        getData();
      })
      .catch((err: any) => {
        if (err.data && err.data.error && err.data.error.length > 0) {
          const errorCode = err.data.error[0]?.code;
          if (errorCode) {
            const errorMsg = getErrorTranslate(errorCode);
            showFailedMessage(errorMsg);
          } else {
            showFailedMessage();
          }
        } else {
          showFailedMessage();
        }
        delDialog.value.hide();
        globalStoreService.setValue('isLoading', false);
      });
  } else {
    delDialog.value.hide();
  }
}

// 删除吊销列表
function delCrlCertify(item: any) {
  if (isSystemLock.value) {
    return;
  }
  delItem = item;
  delCrlDialog.value.show();
}

// 确认删除 / 点击取消
function sureCrlDel(flag: boolean) {
  if (flag) {
    globalStoreService.setValue('isLoading', true);
    CaCertificateService.delCerCrl(delItem.id)
      .then(() => {
        globalStoreService.setValue('isLoading', false);
        delCrlDialog.value.hide();
        showSuccessMessage();
        dataList.splice(0);
        getData();
      })
      .catch((err: any) => {
        if (err.data && err.data.error && err.data.error.length > 0) {
          const errorCode = err.data.error[0]?.code;
          if (errorCode) {
            const errorMsg = getErrorTranslate(errorCode);
            showFailedMessage(errorMsg);
          } else {
            showFailedMessage();
          }
        } else {
          showFailedMessage();
        }
        delCrlDialog.value.hide();
        globalStoreService.setValue('isLoading', false);
      });
  } else {
    delCrlDialog.value.hide();
  }
}

onMounted(() => {
  getData();
});
</script>

<template>
  <div class="certificate-box">
    <div class="content-box">
      <!-- 证书上传 按钮 -->
      <div class="top-box">
        <el-upload
          id="uploadx"
          class="upload-root-cer"
          :action="certConfig.action"
          :accept="certConfig.accept"
          :auto-upload="certConfig.isAutoUpload"
          :show-file-list="false"
          :before-upload="certConfig.beforeUpload"
          :disabled="isSystemLock || !securityConfig"
        >
          <el-button id="addCaCert" type="primary" :disabled="isSystemLock || !securityConfig">
            {{ $t('COMMON_CER_UPLOAD') }}
          </el-button>
        </el-upload>

        <div class="right-search-model-box">
          <div class="el-input-search">
            <SearchInput
              :id-str="'certSearchInput'"
              :value="searchContent"
              :placeholder="$t('SENSOR_KEY_WORD')"
              @clear="searchInput"
              @keyup-enter="searchInput"
            />
          </div>
          <div class="change-model-box">
            <div :class="[showType === 1 ? 'action-icon' : '']">
              <el-tooltip
                :content="$t('IBMC_CARD')"
                :append-to-body="true"
                placement="top"
                trigger-keys
              >
                <el-icon
                  id="type1"
                  :disabled="isSystemLock || !securityConfig"
                  @click="showType = 1"
                >
                  <IconThumbnail />
                </el-icon>
              </el-tooltip>
            </div>

            <div :class="[showType === 2 ? 'action-icon' : '']">
              <el-tooltip
                :content="$t('IBMC_LIST')"
                :append-to-body="true"
                placement="top"
                trigger-keys
              >
                <el-icon
                  id="type2"
                  :disabled="isSystemLock || !securityConfig"
                  @click="showType = 2"
                >
                  <IconList />
                </el-icon>
              </el-tooltip>
            </div>
          </div>
        </div>
      </div>

      <!-- 表格数据 -->
      <el-table
        v-show="showType === 2"
        v-addId.table="'certificateTable'"
        :data="tableData"
        border
        resizable
      >
        <el-table-column class="expand" type="expand" width="35">
          <template #default="scope">
            <div class="little-title">{{ $t('FDM_INFO') }}</div>
            <div class="box">
              <div id="tr1" class="tr">
                <span class="td key">{{ $t('ALARM_REPORT_SYSLOG_USER') }}</span>
                <span class="td value">{{ scope.row.subject }}</span>
                <span class="td key">{{ $t('ALARM_REPORT_SYSLOG_ISSUED') }}</span>
                <span class="td value">
                  {{ scope.row.issuer }}
                </span>
              </div>

              <div id="tr2" class="tr">
                <span class="td key">{{ $t('ALARM_REPORT_SYSLOG_EFFECTIVE') }}</span>
                <span class="td value">
                  {{ scope.row.time }}
                </span>
                <span class="td key">{{ $t('COMMON_SERIALNUMBER') }}</span>
                <span class="td value">
                  {{ scope.row.serialNumber }}
                </span>
              </div>

              <div v-if="scope.row.isImportCrl" id="tr3" class="tr">
                <span class="td key">{{ $t('ALARM_REPORT_SYSLOG_REVOKING_DATE') }}</span>
                <span class="td value">
                  {{ scope.row.crlTimeRange }}
                </span>
              </div>
            </div>
          </template>
        </el-table-column>

        <el-table-column
          v-for="col in columns"
          :key="col.content"
          :label="$t(col.title)"
          :min-width="col.width"
        >
          <template #default="scope">
            <template v-if="col.content === 'subject'">
              <div class="issue-to">
                <img class="img" src="@/assets/common/image/certificate.svg" />
                <span>
                  {{ scope.row[col?.content || ''] }}
                </span>
              </div>
            </template>
            <template v-else-if="col.content === 'isImportCrl'">
              <div class="can-import-crl">
                <!-- 已配置 -->
                <el-tag
                  v-if="scope.row['isImportCrl']"
                  :id="`hadImportCrl${scope.$index}`"
                  size="small"
                  type="success"
                  class="tag-item"
                >
                  {{ $t('COMMON_CONFIGURED') }}
                </el-tag>
                <!-- 未配置 -->
                <el-tag
                  v-if="!scope.row['isImportCrl']"
                  :id="`notImportCrl${scope.$index}`"
                  size="small"
                  type="info"
                  class="tag-item"
                >
                  {{ $t('ALARM_REPORT_SYSLOG_HAS_NOT_SET') }}
                </el-tag>
                <!-- 上传 -->
                <span
                  v-if="isSystemLock || !securityConfig"
                  :id="`importCrlList${scope.$index}`"
                  class="btn disabled-btn"
                >
                  {{ $t('COMMON_UPLOAD') }}
                </span>
                <el-upload
                  v-else
                  id="uploadx"
                  :headers="scope.row.crlConfig.headers"
                  :name="scope.row.crlConfig.alias"
                  :action="scope.row.crlConfig.url"
                  :data="scope.row.crlConfig.data"
                  :accept="scope.row.crlConfig.accept"
                  :auto-upload="scope.row.crlConfig.autoUpload"
                  :show-file-list="false"
                  :before-upload="scope.row.crlConfig.beforeUpload"
                >
                  <span :id="`importCrlList${scope.$index}`" class="btn">
                    {{ $t('COMMON_UPLOAD') }}
                  </span>
                </el-upload>
                <span
                  v-if="scope.row['isImportCrl'] && (isSystemLock || !securityConfig)"
                  :id="`crlDeletedList${scope.$index}`"
                  class="crlDeleted btn disabled-btn"
                >
                  {{ $t('LICENSE_DELETE') }}
                </span>
                <span
                  v-if="scope.row['isImportCrl'] && !(isSystemLock || !securityConfig)"
                  :id="`crlDeletedList${scope.$index}`"
                  class="crlDeleted btn"
                  @click="delCrlCertify(scope.row)"
                >
                  {{ $t('LICENSE_DELETE') }}
                </span>
              </div>
            </template>
            <template v-else>
              <span :id="col?.content + scope.$index">{{ scope.row[col?.content || ''] }}</span>
            </template>
          </template>
        </el-table-column>

        <!-- 操作 -->
        <el-table-column :label="$t('COMMON_OPERATE')" min-width="10%">
          <template #default="scope">
            <!-- 删除 -->
            <span
              :id="`delCertificate${scope.$index}`"
              :class="['btn', isSystemLock || !securityConfig ? 'disabled-btn' : '']"
              @click="delCert(scope.row)"
            >
              {{ $t('COMMON_DELETE') }}
            </span>
          </template>
        </el-table-column>

        <template #empty>
          <TableNoData />
        </template>
      </el-table>

      <div v-show="showType === 1" class="card-box">
        <div id="caCertCardBox" class="card-content">
          <CaCardItem
            v-for="(item, index) in tableData"
            :key="index"
            :class="['card-item', index > 1 ? 'card-item-margin' : '']"
            :show-data="item"
            :is-system-lock="isSystemLock"
            :security-config="securityConfig"
            @del-cert="delCert(item)"
            @del-crl-certify="delCrlCertify(item)"
          />
        </div>

        <!-- 无数据 -->
        <NoDataAvailable v-if="tableData.length === 0" />
      </div>
    </div>

    <el-pagination
      v-if="total"
      v-model:currentPage="currentPage"
      v-addId.pagination="'caCertificatePagination'"
      :page-sizes="pageSizes"
      :page-size="pageSize"
      :layout="layout"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    ></el-pagination>

    <!-- 点击删除的弹窗 -->
    <Dialog ref="delDialog" :config="delDialogConfig" @close="sureDel" />
    <Dialog ref="delCrlDialog" :config="delCrlDialogConfig" @close="sureCrlDel">
      <template #other>
        <div class="content-item">
          <el-icon :size="24">
            <IconAlarm />
          </el-icon>
        </div>
        <div id="delCrlCertify_body" class="content-item text">
          {{ traduction('TWO_FACTORS_DELETE_CRL_TIP') }}
        </div>
      </template>
    </Dialog>
  </div>
</template>

<style lang="scss" scoped>
.certificate-box {
  flex: 1;
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  background-color: var(--o-bg-color-base);
  padding: 16px 24px;
  border-radius: 4px;

  .content-box {
    flex: 1;
    display: flex;
    flex-direction: column;

    .top-box {
      margin-bottom: 16px;
      display: flex;
      align-items: center;
      justify-content: space-between;

      .right-search-model-box {
        display: flex;
        align-items: center;
        justify-content: center;

        .change-model-box {
          margin-left: 8px;
          display: flex;
          align-items: center;

          .el-icon {
            font-size: 16px;
            display: flex;
            flex-direction: column;
            width: 32px;
            height: 32px;
            text-align: center;
            cursor: pointer;
            color: var(--o-text-color-tertiary);
          }

          #type1 {
            border: 1px solid var(--o-border-color-light);
            border-right: none;
            border-radius: 2px 0 0 2px;
          }
          #type2 {
            border: 1px solid var(--o-border-color-light);
            border-radius: 0 2px 2px 0;
            border-left: none;
          }

          .action-icon {
            background-color: var(--o-color-primary);

            .el-icon {
              color: var(--o-text-color-fourth);
              border: none;
            }
          }
        }
      }
    }

    :deep(.el-table) {
      margin-left: 0;
      flex: 1;
      .tag-item {
        margin-right: 4px;
      }

      .tag-item:nth-last-child(1) {
        margin-right: 0;
      }

      .btn {
        margin-right: 8px;
        cursor: pointer;
        font-size: 12px;
        color: var(--o-color-primary);

        &:hover {
          color: var(--o-color-primary-secondary);
        }
      }

      .btn:nth-last-child(1) {
        margin-right: 0;
      }

      .little-title {
        padding-left: 46px;
        margin-bottom: 8px;
        font-size: 12px;
        color: var(--o-text-color-primary);
        line-height: 16px;
        font-weight: 700;
      }

      .box {
        display: table;
        width: 100%;
        padding-left: 46px;

        .tr {
          display: table-row;

          .td {
            display: table-cell;
            color: var(--o-text-color-secondary);
            padding-bottom: 8px;

            .ssh-value {
              margin-right: 4px;
            }
          }

          .key {
            padding-right: 24px;
            white-space: nowrap;
          }

          .value {
            color: var(--o-text-color-primary);
            width: 50%;

            .icon-upload {
              color: var(--o-color-primary);
              text-decoration: none;

              &:hover {
                color: var(--o-color-primary-secondary);
              }
            }
          }
        }

        .tr:nth-last-child(1) {
          .td {
            padding-bottom: 0;
          }
        }
      }

      .issue-to {
        display: flex;
        align-items: center;

        .img {
          display: inline-block;
          width: 30px;
          height: 24px;
          margin-right: 8px;
        }
      }

      .can-import-crl {
        display: flex;
        align-items: center;
      }
    }

    .card-box {
      flex: 1;
      position: relative;

      .card-content {
        display: flex;
        flex-wrap: wrap;

        .card-item {
          width: calc(50% - 8px);
        }

        .card-item:nth-of-type(even) {
          margin-left: 16px;
        }

        .card-item-margin {
          margin-top: 16px;
        }
      }
    }
  }

  :deep(.el-pagination) {
    margin-top: 16px;
  }
}
.content-item.text {
  margin-left: 16px;
  padding-top: 4px;
}
</style>
