<script setup lang="ts">
import { reqPath } from '@/api/reqPath';
import TableNoData from '@/components/TableNoData/TableNoData.vue';
import TableExtendData from '@/pages/System/Info/components/TableExtendData/TableExtendData.vue';
import { loading } from '@/utils/composition';
import { deepClone, showElMessage } from '@/utils/utils';
import { IconChevronDown, IconChevronUp } from '@computing/opendesign-icons';
import type { PropType } from 'vue';
import { nextTick, ref, toRefs, computed, reactive, onMounted, onUnmounted } from 'vue';
import useStore from '@/stores';
import { setStoreData, getStoreData } from '@/utils/composition';
import { useI18n } from 'vue-i18n';
import {
  ISDICard,
  INetCard,
  IOtherTab,
  IPCIeCard,
  IPort,
  IPorts,
} from '../../product.datatype';
import { getBoard, getDownloadData, getDownloadProgress } from '../../service/system.service';
import { isOtherEmptyProperty } from '../../utils/system.util';
import { checkPrivil } from '@/apps/app-bmc/router/routes';
import { UserPrivil } from '@/model/base-enum';
import { traduction, getErrorTranslate } from '@/utils/language';
import Dialog from '@/components/Dialog/Dialog.vue';
import { downloadFileWithResponse } from '@/utils/common-service';
import { showFailedMessage } from '@/utils/composition';
import { downloadData } from '@/pages/Maintance/Systemlog/systemlog.server';
const store = useStore();
// 系统锁定状态
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const hasBasicConfig = checkPrivil(UserPrivil.baseConfig);
const i18n = useI18n();
const errorMsg = traduction('COMMON_FAILED');
const props = defineProps({
  data: {
    type: Object as PropType<IOtherTab>,
    required: true,
    default: () => {
      return {};
    },
  },
});
const { data } = toRefs(props);
const boardData: IOtherTab = data?.value;
const boardTableData = ref([] as any);
const currentPage = ref(1);
const pageSize = ref(10);
const total = ref(boardTableData.value.length);
const tableData = ref([]);
const tableRef = ref();
const percentValue = ref(0);
const percent = ref('0%');
let isSecondEntry: boolean = false;
let lcnLogProgressItem: any = {};
const npuSelectItem = ref({} as any);
let timer: any[] = getStoreData('glob', 'lcnTimer');
let lcnLogProgressUrl: any = sessionStorage.getItem('lcnLogProgressUrl');
const str = sessionStorage.getItem('lcnLogProgressItem');
if (str) {
  lcnLogProgressItem = JSON.parse(str);
}

// 进度条结尾部分的展示
const progressFormat = (value: number) => {
  return '';
};

function getPCleData() {
  boardTableData.value = [];
  getBoard(boardData.detailLink)
    .then((res: any) => {
      if (res.data && res.data.length > 0) {
        res.data.forEach((borad: any) => {
          const d = parseData(borad);
          if (d) {
            boardTableData.value.push(d);
          }
        });
      }
      total.value = boardTableData.value.length;
      getData();
    })
    .finally(() => {
      continueProgress();
      loading(false);
    });
}

function continueProgress() {
  if (lcnLogProgressUrl) {
    if (timer && timer.length !== 0) {
      timer.forEach((item: any) => {
        clearTimeout(item);
      });
    }
    isSecondEntry = true;
    let idx = boardTableData.value.findIndex((v: any) => v.slot === lcnLogProgressItem.slot);
    boardTableData.value[idx].showProgress = true;
    let item = boardTableData.value[idx];
    taskService(lcnLogProgressUrl, item);
  }
}

function parseData(board: any): any {
  let canCollect = false;
  const type = board.FunctionType;
  const exArr = ['SlotNumber', 'EventRecieveEnabled', 'ManagedByBMC', 'SubCards', 'LogicDevices'];
  let extendAttr = initNetRAIDCard(board);
  let showSlotNumber = false;
  Object.keys(board).forEach(key => {
    if ((key === 'SubCards' || key === 'LogicDevices') && board[key].length > 0) {
      canCollect = true;
    }
    if (!exArr.includes(key) && board[key] !== '' && board[key] !== null) {
      canCollect = true;
      showSlotNumber = true;
    }
  });
  return {
    type: isOtherEmptyProperty(board.ProductName) || ' ',
    slot: showSlotNumber ? isOtherEmptyProperty(board.SlotNumber) || ' ' : '--',
    manufacturer: isOtherEmptyProperty(board.Manufacturer) || ' ',
    serialNumber: isOtherEmptyProperty(board?.SerialNumber) || ' ',
    partNumber: isOtherEmptyProperty(board.PartNumber) || ' ',
    description: isOtherEmptyProperty(board.Description) || ' ',
    managedByBMC: isOtherEmptyProperty(board?.ManagedByBMC) || false,
    canCollect,
    showProgress: false,
    extendAttr,
  };
}

// 表头数组
const columns = [
  {
    title: 'FAN_HEAT_TYPE',
    width: '10%',
    show: true,
    content: 'type',
  },
  {
    title: 'INFO_MAIN_BOARD_SLOT',
    width: '10%',
    show: true,
    content: 'slot',
  },
  {
    title: 'COMMON_MANUFACTURER',
    width: '10%',
    show: true,
    content: 'manufacturer',
  },
  {
    title: 'COMMON_SERIALNUMBER',
    width: '15%',
    show: true,
    content: 'serialNumber',
  },
  {
    title: 'OTHER_PART_NUMBER',
    width: '10%',
    show: true,
    content: 'partNumber',
  },
  {
    title: 'COMMON_DESCRIPTION',
    width: '25%',
    show: true,
    content: 'description',
  },
  {
    title: 'COMMON_OPERATE',
    width: '20%',
    show: true,
    content: 'operate',
  },
];

function handleSizeChange(val: number) {
  pageSize.value = val;
  currentPage.value = 1;
  getData();
}

function handleCurrentChange(val: number) {
  getData();
}

function getData() {
  tableData.value = boardTableData.value.slice(
    (currentPage.value - 1) * pageSize.value,
    currentPage.value * pageSize.value,
  );
}

// LCN扩展数据
const LCNExtendArr = [
  {
    label: 'STORE_MEMORY_SIZE',
    content: 'memorySizeMiB',
    hide: true,
  },
  {
    label: 'INFO_MAIN_BOARD_PCB_VERSION',
    content: 'pcbVersion',
    hide: true,
  },
  {
    label: 'OTHER_FLASH_SIZE',
    content: 'flashSizeMiB',
    hide: true,
  },
  {
    label: 'OTHER_MAB_VERSION',
    content: 'mabVersion',
    hide: true,
  },
  {
    label: 'OTHER_SYSTME_VERSION',
    content: 'softwareVersion',
    hide: true,
  },
  {
    label: 'OTHER_CPLD_VERSION',
    content: 'cpldVersion',
    hide: true,
  },
  {
    label: 'OTHER_PATCH_VERSION',
    content: 'patchVersion',
    hide: true,
  },
  {
    label: 'IBMC_FDM_ALARM_BIOS_VERSION',
    content: 'biosVersion',
    hide: true,
  },
];

const LCNCardExtendArr = [
  {
    label: 'FAN_HEAT_TYPE',
    content: 'extType',
    hide: true,
  },
  {
    label: 'INFO_MAIN_BOARD_PCB_VERSION',
    content: 'pcbVersion',
    hide: true,
  },
  {
    label: 'OTHER_CPLD_VERSION',
    content: 'cpldVersion',
    hide: true,
  },
  {
    label: 'COMMON_SERIALNUMBER',
    content: 'serialNumber',
    hide: true,
  },
  {
    label: 'OTHER_PART_NUMBER',
    content: 'partNumber',
    hide: true,
  }
];
function initNetRAIDCard(bodyData: any): any {
  const memorySizeMiB = isOtherEmptyProperty(bodyData?.MemorySizeMiB);
  const pcbVersion = isOtherEmptyProperty(bodyData?.PCBVersion) || ' ';
  const flashSizeMiB = isOtherEmptyProperty(bodyData?.FlashSizeMiB);
  const mabVersion = isOtherEmptyProperty(bodyData?.MABVersion) || ' ';
  const softwareVersion = isOtherEmptyProperty(bodyData.SoftwareVersion) || ' ';
  const patchVersion =
    isOtherEmptyProperty(bodyData?.PatchVersion) || ' ';
  const biosVersion = isOtherEmptyProperty(bodyData?.BiosVersion) || ' ';
  const extendCard = bodyData?.SubCards || [] as any;
  const titleArr = deepClone(LCNExtendArr);
  let cpldVersion = '--';
  let extendData = {
    memorySizeMiB: memorySizeMiB === '--' ? '--' : `${memorySizeMiB} MB`,
    pcbVersion,
    cpldVersion,
    flashSizeMiB: flashSizeMiB === '--' ? '--' : `${flashSizeMiB} MB`,
    mabVersion,
    softwareVersion,
    patchVersion,
    biosVersion,
    extendCards: [] as any,
    extendTitleArr: titleArr,
  };
  if (bodyData.LogicDevices) {
    if (bodyData.LogicDevices.length === 1) {
      extendData.cpldVersion = isOtherEmptyProperty(bodyData.LogicDevices[0].Version) || ' ';
    } else if (bodyData?.LogicDevices.length > 1) {
      bodyData?.LogicDevices.sort((a: any, b: any) => a.Name.localeCompare(b.Name)).forEach((item: any) => {
        const content = `${item.Name}Version`;
        let defaultTitle = traduction('COMMIN_CPLD_VERSION_CUSTOM', [item.Name.replace(/[^\d]/g, '')]);
        if (item.Name.includes('FPGA')) {
          defaultTitle = defaultTitle.replace('CPLD', 'FPGA');
        }
        titleArr.push({
          label: defaultTitle,
          content,
          hide: true,
        });
        extendData[content] = item.Version;
      });
    }
  }
  extendData.extendTitleArr.forEach((element: any) => {
    element.hide = extendData[element.content] === '--';
  });
  if (extendCard && extendCard instanceof Array && extendCard.length > 0) {
    extendData.extendCards = [];
    extendCard.forEach((extendCardInfo: any) => {
      if (extendCardInfo !== null && extendCardInfo !== []) {
        extendData.extendCards?.push(getExtendCard(extendCardInfo));
      }
    });
  }
  return extendData;
}

function getExtendCard(extendCardInfo: any) {
  const title =
    i18n.t('OTHER_SUBCARD_INFO') +
    ' (' +
    i18n.t('OTHER_SLOT_POSITION') +
    extendCardInfo.SlotNumber +
    ')';
  const extType = isOtherEmptyProperty(extendCardInfo.ProductName) || ' ';
  const extPcbVersion = isOtherEmptyProperty(extendCardInfo.PCBVersion) || ' ';
  const cpldVersion = isOtherEmptyProperty(extendCardInfo.CPLDVersion) || ' ';
  const serialNumber = isOtherEmptyProperty(extendCardInfo.SerialNumber) || ' ';
  const partNumber = isOtherEmptyProperty(extendCardInfo.PartNumber) || ' ';

  const sDIExtendCard: any = {
    title,
    extType,
    pcbVersion: extPcbVersion,
    cpldVersion,
    serialNumber,
    partNumber,
  };
  const titleArr = deepClone(LCNCardExtendArr);
  sDIExtendCard.extendCardTitleArr = titleArr;
  if (extendCardInfo?.LogicDevices) {
    if (extendCardInfo.LogicDevices.length === 1) {
      sDIExtendCard.cpldVersion = isOtherEmptyProperty(extendCardInfo.LogicDevices[0].Version) || ' ';
    } else if (extendCardInfo?.LogicDevices.length > 1) {
      extendCardInfo?.LogicDevices.forEach((item: any) => {
        const content = `${item.Name}Version`;
        titleArr.push({
          label: traduction('COMMIN_CPLD_VERSION_CUSTOM', [item.Name.replace(/[^\d]/g, '')]),
          content,
          hide: true,
        });
        sDIExtendCard[content] = item.Version;
      });
    }
  }

  titleArr.forEach((element: any) => {
    element.hide = sDIExtendCard[element.content] === '--';
  });
  return sDIExtendCard;
}

function getRowKey(rowInfo: any) {
  return 'PCIe' + rowInfo.rowIndex;
}

function getCellClass(cellInfo: any) {
  if (cellInfo.columnIndex === 0) {
    return 'expand_cell';
  }
  return columns[cellInfo.columnIndex - 1]?.content;
}

const SendNmidialogRef = ref();
const SendNmiinfo = reactive({
  id: 'collectDialog',
  content: traduction('STORE_COLLECTING_CONFIRM'),
  title: traduction('COMMON_CONFIRM'),
  okButton: {
    id: 'secondConfirm_ok_btn',
    hide: false,
  },
});
function clickSendNmi(item: any) {
  npuSelectItem.value = item;
  SendNmidialogRef.value.show();
}
function sendNmidialogClose(reason: boolean) {
  if (reason) {
    SendNmidialogRef.value.hide();
    let item = {} as any;
    boardTableData.value.forEach((boardItem: any) => {
      if (boardItem.slot === npuSelectItem.value.slot) {
        item = boardItem;
      }
    });
    getDownloadData(item.slot)
      .then((downloadTemp: any) => {
        item.showProgress = true;
        sessionStorage.setItem('lcnLogProgressUrl', downloadTemp.url);
        sessionStorage.setItem('lcnLogProgressItem', JSON.stringify(item));
        taskService(downloadTemp.url, item);
      })
      .catch((err: any) => {
        const errorCode = err?.data?.error?.[0]?.code;
        if (errorCode) {
          showFailedMessage(getErrorTranslate(errorCode));
        } else {
          showElMessage('error', errorMsg);
        }
      });
  } else {
    SendNmidialogRef.value.hide();
  }
}

function setPercent(percentData: any) {
  percent.value = percentData.prepare_progress ? percentData.prepare_progress + '%' : '0%';
  percentValue.value = percentData.prepare_progress ?? 0;
}

// 获取下载进度等
function taskService(url: string, item: any) {
  getDownloadProgress(url)
    .then((progressData: any) => {
      setPercent(progressData);
      if (progressData.prepare_progress === 100 && progressData.state === 'Completed') {
        setTaskStatus(item);
        beginDownLoad(item);
      } else if (progressData.prepare_progress === null && progressData.state === 'Exception') {
        setErr(item);
        showElMessage('error', traduction('COMMON_FAILED'));
        return;
      } else {
        const timerItem = setTimeout(() => {
          taskService(url, item);
        }, 500);
        timer.push(timerItem);
        setStoreData('glob', 'lcnTimer', timer);
      }
    })
    .catch((err: any) => {
      setCatch(item, err);
    });
}

function setTaskStatus(item: any) {
  item.isCollectingOk = true;
  item.progressResult = 'success';
  clearTask(item);
  if (isSecondEntry) {
    let cur = boardTableData.value.find((i: any) => i.slot === item.slot);
    if (cur) {
      cur.isCollectingOk = true;
      clearTask(cur);
    }
  }
}

// 开始下载
function beginDownLoad(item: any) {
  downloadData('diagnostic_information.zip')
    .then((res: any) => {
      const fileName = res.headers['content-disposition'].split('=')[1];
      downloadFileWithResponse(res.data, fileName);
      showElMessage('success', traduction('DOWNLOAD_SUCCESS'));
    })
    .catch(() => {
      showElMessage('error', traduction('DOWNLOAD_FAILED'));
    });
}
function setCatch(item: any, err: { data: any }) {
  item.isCollectingErr = true;
  item.progressResult = 'warning';
  setErr(item);
  const errorCode = err?.data?.error?.[0]?.code;
  if (errorCode) {
    showFailedMessage(getErrorTranslate(errorCode));
  } else {
    showElMessage('error', errorMsg);
  }
}
function setErr(item: any) {
  item.isCollectingErr = true;
  item.progressResult = 'warning';
  clearTask(item);
  if (isSecondEntry) {
    let cur = boardTableData.value.find((i: any) => i.title === item.title);
    if (cur) {
      cur.isCollectingErr = true;
      clearTask(cur);
    }
  }
}
// 清除下载状态
function clearTask(item: any) {
  sessionStorage.removeItem('lcnLogProgressItem');
  sessionStorage.removeItem('lcnLogProgressUrl');
  const timerItem = setTimeout(() => {
    percentValue.value = 0;
    percent.value = '0%';
    item.showProgress = false;
    item.isCollectingOk = false;
    item.isCollectingErr = false;
    item.down = false;
    item.progressResult = '';
  }, 3000);
  timer.push(timerItem);
}

onMounted(() => {
  if (boardData.currentNumber && boardData.currentNumber > 0) {
    loading(true);
    getPCleData();
  }
});
</script>

<template>
  <div id="lcnPage" class="system-info-table">
    <div v-if="boardData.maxNumber && boardData.maxNumber > 0" class="summary">
      <span id="totalLabel" v-t="'HOME_HEALTH_TOTALNUM'" class="label" />
      <span id="totalNum" class="label-content">{{ boardData.maxNumber }}</span>
      <span id="currentLabel" v-t="'HOME_HEALTH_CURRENTNUM'" class="label" />
      <span id="currentNum" class="label-content">{{ total }}</span>
    </div>
    <el-table
      ref="tableRef"
      v-addId.table="'lcnTable'"
      :data="tableData"
      :row-class-name="getRowKey"
      :cell-class-name="getCellClass"
      resizable
      border
      :row-key="row => row.slot"
    >
      <el-table-column class="expand" type="expand">
        <template #default="scope">
          <span v-t="'OTHER_EXTEND_INFO'" class="module-title" />
          <TableExtendData
            :data-list="scope.row.extendAttr.extendTitleArr"
            :fields="scope.row.extendAttr"
          />

          <div
            v-if="scope.row.extendAttr.extendCards && scope.row.extendAttr.extendCards.length > 0"
          >
            <div v-for="card in scope.row.extendAttr.extendCards" :key="card.title" class="module">
              <span v-if="card.title" v-t="card.title" class="module-title" />
              <TableExtendData :data-list="card.extendCardTitleArr" :fields="card" />
            </div>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        v-for="col in columns"
        :key="col?.content"
        :label="$t(col?.title)"
        :prop="col?.content"
        :min-width="col?.width"
        show-overflow-tooltip
      >
        <template #default="attr">
          <span v-if="col.content !== 'operate'" :class="col?.content">
            {{ attr.row[col?.content] }}
          </span>
          <div v-else>
            <div v-if="!attr.row.showProgress">
              <el-button
                id="collectBtn"
                text
                @click="clickSendNmi(attr.row)"
                :disabled="isSystemLock || !hasBasicConfig || !attr.row.canCollect || !attr.row.managedByBMC"
              >
                {{ $t('STORE_COLLECTING_LOGS') }}
              </el-button>
            </div>
            <div class="collect-box" v-else>
              <span id="collectingBtn" class="collecting-text">
                {{ $t('OTHER_COLLECTING_TEXT') }}
              </span>
              <div id="progressBox" class="progress">
                <el-progress id="proCollect" :percentage="percentValue" stroke-width="4" />
              </div>
            </div>
          </div>
        </template>
      </el-table-column>
      <template #empty>
        <TableNoData />
      </template>
    </el-table>
    <el-pagination
      v-if="tableData.length != 0"
      v-model:currentPage="currentPage"
      v-addId.pagination="'lcnPagination'"
      :page-sizes="[10, 15, 30, 50]"
      :page-size="pageSize"
      layout="total, sizes, prev, pager, next, jumper"
      :total="total"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
  <Dialog ref="SendNmidialogRef" :config="SendNmiinfo" @close="sendNmidialogClose"></Dialog>
</template>

<style lang="scss" scoped>
.system-info-table {
  background: var(--o-bg-color-base);
  border-radius: 4px;
  position: relative;
  display: flex;
  flex-direction: column;
  padding: 0 16px 16px !important;
  height: 100%;

  .collect-box {
    display: flex;
    align-items: center;
    .collecting-text {
      font-size: 12px;
      color: var(--o-text-color-secondary);
      line-height: 16px;
    }
  }

  .el-button {
    background: none;
    margin: 0;
    min-width: 0;
  }

  #proCollect {
    width: 200px;
    margin-left: 8px;
    :deep(.el-progress__text) {
      margin-left: 8px;
      min-width: 30px;
    }
  }

  .el-tabs__content {
    margin-top: 0;
  }

  .summary {
    padding: 16px 0;
  }
  .label-content {
    background: var(--o-border-color-light);
    border-radius: 8px;
    width: 28px;
    height: 16px;
    display: inline-block;
    text-align: center;
    margin: 0 16px 0 8px;
    font-size: 12px;
    font-weight: 900;
  }

  .label {
    font-size: 12px;
    color: $APP-COLOR-TEXT;
    letter-spacing: 0;
    line-height: 16px;
  }
  .detail {
    width: 50%;
    float: left;
    display: flex;
    margin-top: 8px;
  }

  .module-title {
    font-weight: 700;
    margin: 16px 0;
    display: block;
  }

  .no-data {
    text-align: center;
    margin-top: 128px;
  }
  .no-data-text {
    font-size: 12px;
    color: var(--o-text-color-tertiary);
    text-align: center;
    line-height: 16px;
  }
  :deep(.el-table--border) {
    .el-table__cell:first-child .cell {
      margin-left: 8px;
      width: 16px;
      padding-left: 0;
      display: inline-block;
    }

    tr,
    colgroup {
      th:nth-child(1),
      col:nth-child(1),
      td:nth-child(1) {
        width: 40px;
        max-width: 40px;
      }
    }
  }
  :deep(.el-table__expanded-cell) {
    .cell {
      width: 100% !important;
    }

    .el-scrollbar__thumb,
    .el-scrollbar__bar {
      background-color: transparent !important;
    }
    .port-icon {
      top: 4px;
    }
  }
}
.small-item {
  margin-bottom: 0px !important;
}
</style>
