<script setup lang="ts">
import { reqPath } from '@/api/reqPath';
import { IconDownload, IconError, IconSuccess, IconRemind } from '@computing/opendesign-icons';
import { downloadFileWithResponse } from '@/utils/common-service';
import { traduction, getErrorTranslate } from '@/utils/language';
import { safeStringify, showElMessage } from '@/utils/utils';
import { computed, onMounted, onUnmounted, ref, reactive, watch, Ref } from 'vue';
import useStore from '@/stores';
import {
  downloadData,
  editSystemDiagnostic,
  getDownloadProgress,
  getDownloadUrl,
  processor,
  systemDiagnostic,
  getPCIeCard,
} from './systemlog.server';
import { parsingInfo } from './systemlogFunctons';
import { showFailedMessage } from '@/utils/composition';

import Loading from '@/components/Loading/Loading.vue';
import GlobalStoreService from '@/services/gloabal-store-service';
import Dialog from '@/components/Dialog/Dialog.vue';
import { getStoreData } from '@/utils/composition';
import { hostItemT } from '@/model/Maintance/systemlog-interface';
import type { CheckboxValueType } from 'element-plus';

const npuTypeDialogRef = ref();
const checkAll = ref(false);
const isIndeterminate = ref(false);
const npuType = ref([] as any);
const npuSupportedPartNumber = ['03029WRV', '03028DFH', '0302018194', '0302034997', '06030667'];
const npuTypeList = [
  {
    id: 0,
    value: 'Blackbox',
    label: traduction('NPU_OPTION_BLACKBOX'),
  },
  {
    id: 1,
    value: 'Device',
    label: traduction('NPU_OPTION_DEVICE'),
  },
];

const handleCheckAllChange = (val: CheckboxValueType) => {
  if (val) {
    npuType.value = ['Blackbox', 'Device'];
    npuTypeDialogRef.value.enable();
  } else {
    npuType.value = [];
    npuTypeDialogRef.value.disable();
  }
  isIndeterminate.value = false;
};

const handleCheckTypeChange = (value: CheckboxValueType[]) => {
  if (value.length === 0) {
    npuTypeDialogRef.value.disable();
  } else {
    npuTypeDialogRef.value.enable();
  }
  const checkedCount = value.length;
  checkAll.value = checkedCount === npuTypeList.length;
  isIndeterminate.value = checkedCount > 0 && checkedCount < npuTypeList.length;
};

const globalStoreService = new GlobalStoreService();
const errorMsg = traduction('COMMON_FAILED');
const dialogRef = ref();
const npuSelectItem = ref({} as any);
const npuDialogRef = ref();
const dialogConfig = reactive({
  id: 'SDIBlackBoxTip',
  type: 'warning',
  content: '',
  title: traduction('COMMON_CONFIRM'),
});

const pcieInterfaceSupported = computed(() => getStoreData('loct', 'pcieInterfaceSupported'));
const multihost = computed(() => getStoreData('loct', 'multihost'));
const systemIds = computed(() => getStoreData('loct', 'systemIds') || []);
const isMultihost = computed(() => multihost.value || systemIds.value.length > 1);
const serialPortDataSupported = computed(() => getStoreData('loct', 'serialPortDataSupported'));

const percentValue = ref(0);
const percent = ref('0%');
const npuDialogConfig = reactive({
  id: 'NPUBoxTip',
  type: 'warning',
  content: '',
  title: traduction('COMMON_CONFIRM'),
});
const npuTypeDialogConfig = reactive({
  id: 'NPUTypeTip',
  type: 'warning',
  content: '',
  title: traduction('COMMON_DOWN'),
  okButton: { id: 'npu_type_download_button', label: traduction('COMMON_DOWN') },
  cancelButton: { id: 'npu_type_cancel_button' },
});
let timer: any[] = [];
// 用于取消正在进行的 API 请求（支持多个并行任务）
let abortControllers: AbortController[] = [];
// 标志位：组件是否已卸载，用于阻止异步回调在组件卸载后继续执行
let isUnmounted = false;

let isSecondEntry: boolean = false;
let hostSecondEntry = false;

let npuLogProgressItem: any = {};
const str = sessionStorage.getItem('npuLogProgressItem');
if (str) {
  npuLogProgressItem = JSON.parse(str);
}
// hostLogProgress: 支持多个并行下载任务的恢复
let hostLogProgressArr: { url: string; title: string }[] = [];
const hostLogProgressStr = sessionStorage.getItem('hostLogProgress');
if (hostLogProgressStr) {
  hostLogProgressArr = JSON.parse(hostLogProgressStr);
}
const store = useStore();
const isSystemLock = computed(() => {
  return store.state.glob.systemLocked;
});
const fdmSupport = computed(() => getStoreData('loct', 'fdmspt'));
const pcieItem = reactive({
  id: 'blackBoxPCIe',
  title: traduction('SYSTEM_LOG_PCIE'),
  status: false,
});
const blackBoxItem = reactive({
  id: 'blackBox',
  title: traduction('SYSTEM_LOG_BLACKCLIP'),
  disable: false,
  desc: traduction('SYSTEM_LOG_BLACKCLIP1'),
  status: false,
  fileName: 'blackbox.tar',
  size: '4M',
  down: false,
  currentDownType: '',
  showProgress: false,
  progressResult: '',
  isCollectingOk: false,
  isCollectingErr: false,
  hostPercent: '0%',
  hostPercentValue: 0,
});
const sdiItem = reactive({
  id: 'SDIBlackBox',
  title: traduction('SYSTEM_LOG_SDI'),
  desc: traduction('SYSTEM_LOG_PCIE_SID'),
  status: false,
  fileName: 'SmartNIC_blackbox.tar',
  size: '60K',
  down: false,
  currentDownType: 'sdiBlackBox',
});
// 黑匣子卡片：双主机模式下为每个主机生成独立卡片，单主机模式下复用原对象
const blackBoxCards = ref([] as any[]);

// 黑匣子下载进度：支持多个并行下载任务的恢复
let blackBoxLogProgressArr: { url: string; title: string }[] = [];
const blackBoxLogProgressStr = sessionStorage.getItem('blackBoxLogProgress');
if (blackBoxLogProgressStr) {
  blackBoxLogProgressArr = JSON.parse(blackBoxLogProgressStr);
}

const serialPortItem = reactive({
  id: 'serialPort',
  title: traduction('SYSTEM_LOG_SERIAL_PORT'),
  desc: traduction('SYSTEM_LOG_SERIAL_PORT1_TIP'),
  status: false,
  fileName: 'systemcom.tar',
  size: '2M',
});

const npuCards: any[] = reactive([]);
let hostLogCards: Ref<hostItemT[]> = ref([]);

// 获取host集合数据
function getAllHostLog() {
  hostLogCards.value.splice(0);
  if (!isMultihost.value) {
    // 单主机：创建1个卡片
    hostLogCards.value = [{
      title: 'systemcom.tar',
      id: 'HOST',
      progressResult: '',
      isCollectingOk: false,
      isCollectingErr: false,
      showProgress: false,
      down: false,
      fileName: 'systemcom.tar',
      systemId: '',
      hostPercent: '0%',
      hostPercentValue: 0,
    }];
    return;
  }
  // 多主机
  let arr = [];
  let length = systemIds.value.length === 2 ? systemIds.value.length : 8;
  for (let i = 1; i <= length; i++) {
    arr.push({
      title: `system${i}com.tar`,
      id: 'HOST',
      progressResult: '',
      isCollectingOk: false,
      isCollectingErr: false,
      showProgress: false,
      down: false,
      fileName: `system${i}com.tar`,
      systemId: `${i}`,
      hostPercent: '0%',
      hostPercentValue: 0,
    });
  }
  hostLogCards.value = arr;
}

// 获取处理器集合数据
function getAllProcessor() {
  npuCards.splice(0);
  Promise.all([processor(), getPCIeCard()])
    .then(res => {
      const moduleResp = res[0] as any;
      const moduleNPU = parsingInfo((moduleResp.NPU ?? []).filter((npu :any) => npu.State !== 'Absent'));
      const cardBody = res[1];
      let cardNPU = [] as any[];
      if (cardBody && Array.isArray(cardBody)) {
        const adaptedRes = cardBody
          .filter(
            item =>
              ['NPU'].some(itemTemp =>
                (item.FunctionType as string)?.toUpperCase().includes(itemTemp),
              ) && npuSupportedPartNumber.includes(item.PartNumber),
          )
          .map(item => {
            const match = (item.Id as string).match(/\d+/) as any;
            const slotNumber = parseInt(match[0], 10);
            return isNaN(slotNumber)
              ? null
              : {
                slotNumber,
                ...item,
              };
          });
        cardNPU = parsingInfo(adaptedRes) as any[];
      }
      npuCards.push(...moduleNPU, ...cardNPU);
      const npuArr = sessionStorage.getItem('npuLogProgressItem');
      if (npuArr) {
        const targetArr = JSON.parse(npuArr);
        isSecondEntry = true;
        const npuCardsMap = npuCards.reduce((map, npu) => {
          map[npu.title] = npu;
          return map;
        }, {});
        targetArr.forEach((target: any) => {
          const targetItem = npuCardsMap[target.title];
          if (targetItem) {
            taskService(target.url, targetItem);
          }
        });
      }
      globalStoreService.setValue('isLoading', false);
    })
    .catch(() => {
      globalStoreService.setValue('isLoading', false);
    });
}

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

// 黑匣子功能 / 系统串口数据记录功能 开关发生修改
function change(item: any) {
  const par:any = {};
  if (item.id === 'blackBox') {
    par['BlackBoxEnabled'] = item.status;
  } else if (item.id === 'serialPort') {
    par['SerialPortDataEnabled'] = item.status;
  }
  editSystemDiagnostic(par)
    .then(() => {
      showElMessage('success', traduction('COMMON_SUCCESS'));
    })
    .catch(() => {
      item.status = !item.status;
      showElMessage('error', traduction('COMMON_FAILED'));
    });
}

// PCIe接口 开关发生修改
function changePCIe() {
  editSystemDiagnostic({
    PCIeInterfaceEnabled: pcieItem.status,
  })
    .then(() => {
      if (pcieItem.status) {
        blackBoxItem.disable = false;
      } else {
        blackBoxItem.disable = true;
        blackBoxItem.status = false;
      }
      showElMessage('success', traduction('SYSTEM_LOG_PCIE_TIP'));
    })
    .catch(() => {
      pcieItem.status = !pcieItem.status;
      showElMessage('error', traduction('COMMON_FAILED'));
    });
}

function openNPUDownloadDialog(item: any) {
  npuTypeDialogRef.value.show();
  initNPUType();
  npuSelectItem.value = item;
}

// 点击下载黑匣子日志
function handleBlackBoxDownload(item: any) {
  // 检查全局开关状态
  if (!blackBoxItem.status) {
    showElMessage('error', traduction('SYSTEM_LOG_BLACKCLIP_MEG'));
    return;
  }
  if (item.down) {
    return;
  }
  item.down = true;
  item.currentDownType = 'blackBox';
  
  // 双主机场景下附带 SystemId 参数
  const params = item.systemId ? { SystemId: `${item.systemId}` } : {};

  getDownloadUrl(reqPath.maintance.systemlog.downloadBlackBox, params)
    .then((data: any) => {
      // 保存下载进度到 sessionStorage，用于页面刷新后恢复
      item.showProgress = true;
      const stored = sessionStorage.getItem('blackBoxLogProgress');
      const arr = stored ? JSON.parse(stored) : [];
      // 避免重复添加
      if (!arr.some((p: any) => p.title === item.title)) {
        arr.push({ url: data.url, title: item.title });
        sessionStorage.setItem('blackBoxLogProgress', safeStringify(arr));
      }
      taskService(data.url, item);
    })
    .catch(() => {
      item.down = false;
      item.showProgress = false;
    });
}

function initNPUType() {
  npuTypeDialogRef.value.disable();
  npuType.value = [];
  checkAll.value = false;
  isIndeterminate.value = false;
}

// SDI点击下载 获取下载地址
function sdiDownload() {
  if (sdiItem.status) {
    if (sdiItem.down) {
      return;
    }
    dialogRef.value.show();
  } else {
    showElMessage('error', traduction('REMOTE_FULL_TIP_NOT_SUPPORT'));
  }
}

function closeModal(reason: boolean) {
  if (reason) {
    dialogRef.value.hide();
    sdiItem.down = true;
    getDownloadUrl(reqPath.maintance.systemlog.downloadSDIBlackBox, {})
      .then((data: any) => {
        if (!data.url || data.url === '') {
          showElMessage('error', traduction('COMMON_FAILED'));
          sdiItem.down = false;
        } else {
          taskService(data.url, sdiItem);
        }
      })
      .catch(() => {
        sdiItem.down = false;
      });
  } else {
    dialogRef.value.hide();
  }
}
function hostLogDownload(item: hostItemT) {
  // 单主机需检查开关状态
  if (!isMultihost.value && !serialPortItem.status) {
    showElMessage('error', traduction('SYSTEM_LOG_SERIAL_PORT_MEG'));
    return;
  }
  if (item.down) {
    return;
  }
  item.down = true;
  let url = reqPath.maintance.systemlog.downloadSerialPortData;
  const params = item.systemId ? { SystemId: item.systemId } : {};
  getDownloadUrl(url, params)
    .then((data: any) => {
      item.showProgress = true;
      const stored = sessionStorage.getItem('hostLogProgress');
      const arr = stored ? JSON.parse(stored) : [];
      if (!arr.some((p: any) => p.title === item.title)) {
        arr.push({ url: data.url, title: item.title });
        sessionStorage.setItem('hostLogProgress', safeStringify(arr));
      }
      taskService(data.url, item);
    })
    .catch(err => {
      const errorCode = err?.data?.error?.[0]?.code;
      if (errorCode) {
        showFailedMessage(getErrorTranslate(errorCode));
      } else {
        showElMessage('error', errorMsg);
      }
      item.down = false;
    });
}
function closeNPUTypeModal(reason: boolean) {
  if (reason) {
    npuDialogRef.value.show();
  }
  npuTypeDialogRef.value.disable();
  npuTypeDialogRef.value.hide();
}
function closeNPUModal(reason: boolean) {
  if (reason) {
    npuDialogRef.value.hide();
    let item = {} as any;
    npuCards.forEach(npu => {
      if (npu.title === npuSelectItem.value.title) {
        item = npu;
      }
    });
    if (item.status) {
      if (item.down) {
        return;
      }
      item.down = true;
      let npuId: number = getParams(item);
      const url = reqPath.maintance.systemlog.downloadNPUDeviceLog;
      const params = { NpuId: npuId, LogType: npuType.value };
      getDownloadUrl(url, params)
        .then((data: any) => {
          item.showProgress = true;
          item.url = data.url;
          if (sessionStorage.getItem('npuLogProgressItem')) {
            const targetArr = JSON.parse(sessionStorage.getItem('npuLogProgressItem') as string) ?? [];
            targetArr.push(item);
            sessionStorage.setItem('npuLogProgressItem', safeStringify(targetArr));
          } else {
            sessionStorage.setItem('npuLogProgressItem', safeStringify([item]));
          }
          taskService(data.url, item);
        })
        .catch(err => {
          const errorCode = err?.data?.error?.[0]?.code;
          if (errorCode) {
            showFailedMessage(getErrorTranslate(errorCode));
          } else {
            showElMessage('error', errorMsg);
          }
          item.down = false;
        });
    }
  } else {
    npuDialogRef.value.hide();
  }
}

// 开始下载
function beginDownLoad(item: any) {
  downloadData(item.fileName)
    .then((res: any) => {
      const fileName = res.headers['content-disposition'].split('=')[1];
      downloadFileWithResponse(res.data, fileName);
      item.down = false;
      showElMessage('success', traduction('DOWNLOAD_SUCCESS'));
    })
    .catch(() => {
      item.down = false;
      showElMessage('error', traduction('DOWNLOAD_FAILED'));
    });
}

function getParams(item: any) {
  const patternMulti = /^NPU\d+-\d+$/;
  const patternSingle = /^NPU\d+$/;
  const patternCard = /^(NPU Card )\d+$/;
  let npuId: number = 0;
  item.fileName = 'npu_device_log.tar.gz';
  if (patternMulti.test(item.title)) {
    npuId =
    ((Number(item.title.slice(3).split('-')[0]) - 1) * 2) +
    Number(item.title.slice(3).split('-')[1]);
  } else if (patternSingle.test(item.title)) {
    const match = item.title.match(/^(?<npuId>NPU\d+)$/);
    npuId = Number(match.groups.npuId.slice(3));
    item.fileName = `npu${npuId}_device_log.tar.gz`;
  } else if (patternCard.test(item.title)) {
    npuId = parseInt(((item.title as string).match(/\d+/) as any[])[0], 10);
    npuId = (npuId * 2) - 1; 
  } else {}
  return npuId;
}

function setPercent(data: any, id: string, item: any) {
  if (id === 'NPU') {
    item.percent = data.prepare_progress ? data.prepare_progress + '%' : '0%';
    item.percentValue = data.prepare_progress;
  }
}
// 设置下载结果状态（成功/失败）并清理任务
function setDownloadResult(item: any, success: boolean) {
  const statusKey = success ? 'isCollectingOk' : 'isCollectingErr';
  item[statusKey] = true;
  item.progressResult = success ? 'success' : 'warning';
  if (item.id === 'NPU') {
    clearDownloadTask(item, 'npuLogProgressItem', true);
    if (isSecondEntry) {
      const cur = npuCards.find(npu => npu.title === item.title);
      if (cur) {
        cur[statusKey] = true;
        clearDownloadTask(cur, 'npuLogProgressItem', true);
      }
    }
  }
  if (item.id === 'HOST') {
    clearDownloadTask(item, 'hostLogProgress');
    if (hostSecondEntry) {
      const cur = hostLogCards.value.find(host => host.title === item.title);
      if (cur) {
        cur[statusKey] = true;
        clearDownloadTask(cur, 'hostLogProgress');
      }
    }
  }
  if (item.currentDownType === 'blackBox') {
    clearDownloadTask(item, 'blackBoxLogProgress');
  }
}
function setCatch(item: any, err: { data: any }) {
  setDownloadResult(item, false);
  const errorCode = err?.data?.error?.[0]?.code;
  if (errorCode) {
    showFailedMessage(getErrorTranslate(errorCode));
  } else {
    showElMessage('error', errorMsg);
  }
}
// 处理下载进度响应
function handleTaskProgress(data: any, url: string, item: any) {
  if (isUnmounted) {
    return;
  }
  if (item.id === 'HOST' || item.currentDownType === 'blackBox') {
    item.hostPercent = data.prepare_progress ? data.prepare_progress + '%' : '0%';
    item.hostPercentValue = data.prepare_progress;
  }
  setPercent(data, item.id, item);
  if (data.prepare_progress === 100 && data.state === 'Completed') {
    setDownloadResult(item, true);
    beginDownLoad(item);
  } else if (data.prepare_progress === null && data.state === 'Exception') {
    // SDI 没有进度条和 sessionStorage 恢复，直接重置下载状态
    if (item.currentDownType === 'sdiBlackBox') {
      item.down = false;
    }
    setDownloadResult(item, false);
    showElMessage('error', traduction('COMMON_FAILED'));
  } else {
    const timerItem = setTimeout(() => {
      taskService(url, item);
    }, 500);
    timer.push(timerItem);
  }
}

// 移除已完成的 AbortController，避免内存泄漏
function removeAbortController(controller: AbortController) {
  const index = abortControllers.indexOf(controller);
  if (index > -1) {
    abortControllers.splice(index, 1);
  }
}

// 处理下载任务错误及重试逻辑
function handleTaskError(err: any, url: string, item: any, retryCount: number) {
  if (isUnmounted) {
    return;
  }
  // 忽略取消请求导致的错误
  if (!err || err.name === 'CanceledError' || err.name === 'AbortError') {
    return;
  }

  // 重试逻辑：最多重试 3 次，使用指数退避（1s → 2s → 4s）
  if (retryCount < 3) {
    const delay = 1000 * Math.pow(2, retryCount);
    const timerItem = setTimeout(() => {
      taskService(url, item, retryCount + 1);
    }, delay);
    timer.push(timerItem);
  } else {
    // 超过重试次数，走失败流程
    setCatch(item, err);
    item.down = false;
  }
}

// 清除下载状态（通用）
function clearDownloadTask(item: any, storageKey: string, isNpu = false) {
  const stored = sessionStorage.getItem(storageKey);
  if (stored) {
    const arr = JSON.parse(stored);
    const updated = arr.filter((p: any) => p.title !== item.title);
    if (updated.length === 0) {
      sessionStorage.removeItem(storageKey);
    } else {
      sessionStorage.setItem(storageKey, safeStringify(updated));
    }
  }
  const timerItem = setTimeout(() => {
    if (isNpu) {
      percentValue.value = 0;
      percent.value = '0%';
    } else {
      item.hostPercentValue = 0;
      item.hostPercent = '0%';
    }
    item.showProgress = false;
    item.isCollectingOk = false;
    item.isCollectingErr = false;
    item.down = false;
    item.progressResult = '';
  }, 3000);
  timer.push(timerItem);
}

// 获取下载进度等
function taskService(url: string, item: any, retryCount = 0) {
  if (isUnmounted) {
    return;
  }

  const abortController = new AbortController();
  abortControllers.push(abortController);

  getDownloadProgress(url, { signal: abortController.signal })
    .then((data: any) => {
      handleTaskProgress(data, url, item);
    })
    .catch((err: any) => {
      handleTaskError(err, url, item, retryCount);
    })
    .finally(() => {
      removeAbortController(abortController);
    });
}

// 获取数据
function applyDiagnosticData(data: any) {
  blackBoxItem.status = data.BlackBoxEnabled;
  serialPortItem.status = data.SerialPortDataEnabled;
  pcieItem.status = data.PCIeInterfaceEnabled;
  sdiItem.status = data.IsSupportBlackBoxOfSdi;
  if (!pcieItem.status) {
    blackBoxItem.disable = true;
  }
  // 此处需要根据产品名称修改大小
  const blackBoxSize = Math.round(data.BlackBoxSize / (1024 * 1024));
  const serialDataSize = Math.round(data.SerialPortDataSize / (1024 * 1024));
  blackBoxItem.size = blackBoxSize + 'M';
  serialPortItem.size = serialDataSize + 'M';
  serialPortItem.desc = traduction('SYSTEM_LOG_SERIAL_PORT1', [serialDataSize]);
}

function restoreBlackBoxProgress() {
  blackBoxLogProgressArr.forEach((progress) => {
    const idx = blackBoxCards.value.findIndex((v: any) => v.title === progress.title);
    if (idx >= 0) {
      const card = blackBoxCards.value[idx];
      card.showProgress = true;
      card.down = true;
      card.currentDownType = 'blackBox';
      taskService(progress.url, card);
    }
  });
}

// systemIds 由 Navigate.vue 的 getGeneric() 写入 store，可能与 systemDiagnostic 存在竞态
// 若 systemIds 尚未就绪（null），保持 loading 状态直到其写入后再初始化卡片
function initCardsWhenReady() {
  const doInit = () => {
    getAllHostLog();
    initBlackBoxCards();
    restoreBlackBoxProgress();
    globalStoreService.setValue('isLoading', false);
  };
  if (getStoreData('loct', 'systemIds') !== null) {
    doInit();
  } else {
    const unwatch = watch(systemIds, () => {
      unwatch();
      doInit();
    });
  }
}

function getData() {
  globalStoreService.setValue('isLoading', true);
  getAllProcessor();
  systemDiagnostic()
    .then((data: any) => {
      applyDiagnosticData(data);
      initCardsWhenReady();
    })
    .catch(() => {
      globalStoreService.setValue('isLoading', false);
    });
}

function initBlackBoxCards() {
  blackBoxCards.value = [];
  if (isMultihost.value && systemIds.value.length === 2) {
    // 双主机模式：为每个主机创建独立的下载卡片，只拷贝需要独立维护的状态字段
    systemIds.value.forEach((id: string) => {
      blackBoxCards.value.push({
        id: 'blackBox',
        title: `system${id}blackbox.tar`,
        fileName: `system${id}blackbox.tar`,
        systemId: id,
        currentDownType: '',
        down: false,
        showProgress: false,
        hostPercent: '0%',
        hostPercentValue: 0,
        progressResult: '',
        isCollectingOk: false,
        isCollectingErr: false,
      });
    });
  } else {
    // 单主机模式：创建独立下载卡片，避免下载状态污染 blackBoxItem 配置对象
    blackBoxCards.value.push({
      id: 'blackBox',
      title: blackBoxItem.fileName,
      fileName: blackBoxItem.fileName,
      systemId: '',
      currentDownType: '',
      down: false,
      showProgress: false,
      hostPercent: '0%',
      hostPercentValue: 0,
      progressResult: '',
      isCollectingOk: false,
      isCollectingErr: false,
    });
  }
}

// 处理 Navigate.vue 的 getGeneric() 与 systemDiagnostic() 的竞态：
// 若 store 中的 isMultihost 在 systemDiagnostic 回调之后才更新，需重新初始化卡片
onMounted(() => {
  // 重置卸载标志位
  isUnmounted = false;
  getData();
  if (hostLogProgressArr.length > 0) {
    hostSecondEntry = true;
    hostLogProgressArr.forEach((progress) => {
      const idx = hostLogCards.value.findIndex((v: hostItemT) => v.title === progress.title);
      if (idx >= 0) {
        const card = hostLogCards.value[idx];
        card.showProgress = true;
        card.down = true;
        taskService(progress.url, card);
      }
    });
  }
});

onUnmounted(() => {
  // 设置卸载标志位，阻止后续异步操作
  isUnmounted = true;
  // 取消所有正在进行的 API 请求
  abortControllers.forEach(controller => controller.abort());
  abortControllers = [];
  // 清空定时器
  timer.forEach((item: any) => {
    clearTimeout(item);
  });
});
</script>

<template>
  <div id="systemLog" class="system-log">
    <div class="boxs">
      <!-- PCIe 接口，黑匣子功能区 -->
      <div v-if="pcieInterfaceSupported || fdmSupport" class="box">
        <el-form label-width="auto" label-position="left">
          <!-- PCIe接口 -->
          <template v-if="pcieInterfaceSupported">
            <el-form-item class="item-box" :label="pcieItem.title">
              <el-switch
                :id="pcieItem.id"
                v-model="pcieItem.status"
                :disabled="isSystemLock"
                @change="changePCIe"
              />
            </el-form-item>
            <div class="desc">
              {{ fdmSupport ? $t('SYSTEM_LOG_PCIE_DESCRIBE') : $t('SYSTEM_LOG_PCIE_DESCRIBE2') }}
            </div>
          </template>
          <!-- 黑匣子功能开关 -->
          <template v-if="fdmSupport">
            <el-form-item class="item-box" :label="blackBoxItem.title">
              <el-switch
                :id="blackBoxItem.id"
                v-model="blackBoxItem.status"
                :disabled="isSystemLock || blackBoxItem.disable"
                @change="change(blackBoxItem)"
              />
            </el-form-item>
            <div class="desc">{{ blackBoxItem.desc }}</div>
          </template>
        </el-form>

        <!-- 黑匣子下载 -->
        <div v-if="fdmSupport">
          <div v-for="card in blackBoxCards" :key="card.title" class="section up">
            <div class="left">
              <img class="file-img" src="@/assets/common/image/folder.svg" alt="" />
              <div class="name-size">
                <p class="name">{{ card.fileName }}</p>
                <p v-if="!card.showProgress" class="size">{{ blackBoxItem.size }}</p>
                <div v-if="card.showProgress" class="progress">
                  <el-progress
                    :percentage="card.hostPercentValue"
                    :format="progressFormat"
                    :status="card.progressResult"
                  />
                  <span class="percent">{{ card.hostPercent }}</span>
                  <span v-if="card.isCollectingOk" class="download-res">
                    <el-icon>
                      <IconSuccess />
                    </el-icon>
                    <span>{{ $t('NPU_COMPLETED') }}</span>
                  </span>
                  <span v-if="card.isCollectingErr" class="download-res">
                    <el-icon>
                      <IconError />
                    </el-icon>
                    <span>{{ $t('NPU_COLLECTION_FAILED') }}</span>
                  </span>
                </div>
              </div>
            </div>
            <div class="right">
              <el-button
                :id="card.title + 'Download'"
                :class="card.down ? 'visibility-hidden' : ''"
                :disabled="!blackBoxItem.status"
                @click="handleBlackBoxDownload(card)"
              >
                <el-icon><IconDownload /></el-icon>
                {{ $t('COMMON_DOWN') }}
              </el-button>
              <div class="loading-box" :class="card.down ? '' : 'visibility-hidden'">
                <Loading :state="true" />
              </div>
            </div>
          </div>
        </div>

        <!-- SDI黑匣子描述信息 -->
        <el-form
          v-if="sdiItem.status"
          label-width="auto"
          label-position="left"
          class="sdi-sction"
        >
          <el-form-item class="item-box" :label="sdiItem.title"></el-form-item>
          <div class="desc">{{ sdiItem.desc }}</div>
        </el-form>
        <!-- SDI黑匣子下载链接 -->
        <div v-if="sdiItem.status" class="section">
          <div class="left">
            <img class="file-img" src="@/assets/common/image/folder.svg" alt="" />
            <div class="name-size">
              <p class="name">{{ sdiItem.fileName }}</p>
              <p class="size">{{ sdiItem.size }}</p>
            </div>
          </div>
          <div class="right">
            <!-- 没有通过v-if或者v-show来控制显示，而是通过类名绑定设置visibility: hidden; 这样利用了按钮的宽度来对加载中的图标进行定位，
              否则加载中的位置不方便设置（毕竟小语种的文本宽度不同） -->
            <!-- 下载按钮 -->
            <el-button
              :id="sdiItem.id + 'Download'"
              :class="sdiItem.down ? 'visibility-hidden' : ''"
              @click="sdiDownload()"
            >
              <el-icon><IconDownload /></el-icon>
              {{ $t('COMMON_DOWN') }}
            </el-button>
            <!-- 加载中 -->
            <div class="loading-box" :class="sdiItem.down ? '' : 'visibility-hidden'">
              <Loading :state="true" />
            </div>
          </div>
        </div>
      </div>

      <!-- 系统串口数据记录功能区 -->
      <div v-if="serialPortDataSupported" class="box">
        <!-- 串口日志开关（仅单主机显示） -->
        <el-form v-if="!isMultihost" label-width="auto" label-position="left">
          <el-form-item class="item-box" :label="serialPortItem.title">
            <el-switch
              :id="serialPortItem.id"
              v-model="serialPortItem.status"
              :disabled="isSystemLock"
              @change="change(serialPortItem)"
            />
          </el-form-item>
          <div class="desc">{{ serialPortItem.desc }}</div>
        </el-form>

        <!-- 多主机标题 -->
        <div v-if="isMultihost" class="serial-port-title">{{ serialPortItem.title }}</div>

        <!-- 串口日志下载列表 -->
        <div v-for="card in hostLogCards" :key="card.title" class="section up">
          <div class="left">
            <img class="file-img" src="@/assets/common/image/folder.svg" alt="" />
            <div class="name-size">
              <p class="name">{{ card.title }}</p>
              <p v-if="!card.showProgress" class="size">{{ serialPortItem.size }}</p>
              <div v-if="card.showProgress" class="progress">
                <el-progress
                  :percentage="card.hostPercentValue"
                  :format="progressFormat"
                  :status="card.progressResult"
                />
                <span class="percent">{{ card.hostPercent }}</span>
                <span v-if="card.isCollectingOk" class="download-res">
                  <el-icon>
                    <IconSuccess />
                  </el-icon>
                  <span>{{ $t('NPU_COMPLETED') }}</span>
                </span>
                <span v-if="card.isCollectingErr" class="download-res">
                  <el-icon>
                    <IconError />
                  </el-icon>
                  <span>{{ $t('NPU_COLLECTION_FAILED') }}</span>
                </span>
              </div>
            </div>
          </div>
          <div class="right">
            <el-button
              :id="card.title + 'Download'"
              :class="card.down ? 'visibility-hidden' : ''"
              @click="hostLogDownload(card)"
            >
              <el-icon>
                <IconDownload />
              </el-icon>
              {{ $t('COMMON_DOWN') }}
            </el-button>
            <div class="loading-box" :class="card.down ? '' : 'visibility-hidden'">
              <Loading :state="true" />
            </div>
          </div>
        </div>
      </div>
      <!-- SDI黑匣子下载弹窗信息 -->
      <Dialog ref="dialogRef" :config="dialogConfig" @close="closeModal">
        <template v-if="dialogConfig.id === 'SDIBlackBoxTip'" #other>
          <div>
            <div class="sdi-dialog">
              <el-icon>
                <IconRemind />
              </el-icon>
              <div class="sdi-content">
                <p>{{ traduction('SYSTEM_SID_DOWN_TIP1') }}</p>
                <p>{{ traduction('SYSTEM_SID_DOWN_TIP2') }}</p>
                <p>{{ traduction('SYSTEM_SID_DOWN_TIP3') }}</p>
              </div>
            </div>
            <div class="sdi-info-tip">
              <p>{{ traduction('SYSTEM_SID_DOWN_TIP4') }}</p>
            </div>
          </div>
        </template>
      </Dialog>
    </div>
    <div v-if="npuCards.length" id="systemLogNPU" class="npu">
      <div class="title">{{ $t('NPU_LOG') }}</div>
      <div class="sub-title">{{ $t('NPU_DESCRIPTION') }}</div>
      <div class="content">
        <div v-for="item in npuCards" :key="item.title" class="item">
          <div class="left">
            <img src="@/assets/common/image/folder.svg" class="folder" />
            <div class="file-info">
              <div class="file-name">{{ item.title }}</div>
              <div v-if="item.showProgress" class="progress">
                <el-progress
                  :percentage="item.percentValue"
                  :format="progressFormat"
                  :status="item.progressResult"
                />
                <span class="percent">{{ item.percent }}</span>
                <!-- 成功 -->
                <span v-if="item.isCollectingOk" class="download-res">
                  <el-icon>
                    <IconSuccess />
                  </el-icon>
                  <span>{{ $t('NPU_COMPLETED') }}</span>
                </span>
                <!-- 失败 -->
                <span v-if="item.isCollectingErr" class="download-res">
                  <el-icon>
                    <IconError />
                  </el-icon>
                  <span>{{ $t('NPU_COLLECTION_FAILED') }}</span>
                </span>
              </div>
            </div>
          </div>
          <!-- 下载 -->
          <div class="right">
            <el-button
              :id="item.title + 'Download'"
              :class="item.down ? 'visibility-hidden' : ''"
              @click="openNPUDownloadDialog(item)"
            >
              <el-icon><IconDownload /></el-icon>
              {{ $t('COMMON_DOWN') }}
            </el-button>
            <div class="loading-box" :class="item.down ? '' : 'visibility-hidden'">
              <Loading :state="true" />
            </div>
          </div>
        </div>
      </div>
    </div>
    <!-- NPU弹窗1信息 -->
    <Dialog ref="npuTypeDialogRef" :config="npuTypeDialogConfig" @close="closeNPUTypeModal">
      <template #other>
        <div class="dialog-content">
          <div class="dialog-check-content">
            <div class="check-title">
              <div>{{ $t('NPU_TYPE_PROMPT') }}</div>
            </div>
            <div class="check-content">
              <el-checkbox
                id="check-all"
                v-model="checkAll"
                class="dialog-check-box"
                :indeterminate="isIndeterminate"
                @change="handleCheckAllChange"
              >
                {{ $t('ALARM_EVENT_ALL') }}
              </el-checkbox>
              <el-checkbox-group
                v-model="npuType"
                @change="handleCheckTypeChange"
              >
                <el-checkbox
                  v-for="npuItem in npuTypeList"
                  :id="npuItem.value"
                  :key="npuItem"
                  :label="npuItem.label"
                  :value="npuItem.value"
                >
                  {{ $t(npuItem.label) }}
                </el-checkbox>
              </el-checkbox-group>
            </div>
          </div>
        </div>
      </template>
    </Dialog>
    <!-- NPU弹窗信息 -->
    <Dialog ref="npuDialogRef" :config="npuDialogConfig" @close="closeNPUModal">
      <template #other>
        <div>
          <div class="sdi-dialog">
            <el-icon>
              <IconRemind />
            </el-icon>
            <div class="sdi-content">
              <p>{{ traduction('SYSTEM_NPU_DOWN_TIP1') }}</p>
              <p>{{ traduction('SYSTEM_NPU_DOWN_TIP2') }}</p>
              <p>{{ traduction('SYSTEM_NPU_DOWN_TIP3') }}</p>
            </div>
          </div>
          <div class="sdi-info-tip">
            <p>{{ traduction('SYSTEM_SID_DOWN_TIP4') }}</p>
          </div>
        </div>
      </template>
    </Dialog>
  </div>
</template>

<style scoped lang="scss">
.system-log {
  font-size: 12px;
  color: var(--o-text-color-secondary);
  padding-right: 24px;

  .boxs {
    .box {
      margin-bottom: 16px;
      padding: 24px;
      border-radius: 4px;
      background-color: var(--o-bg-color-base);

      :deep(.el-form) {
        .el-form-item {
          margin-bottom: 0;

          .el-form-item__label-wrap {
            .el-form-item__label {
              font-weight: 600;
              color: var(--o-text-color-primary);
              font-size: 16px;
              line-height: 16px;
              padding-bottom: 8px;
            }
          }

          .el-form-item__content {
            line-height: 40px;
          }
        }

        .desc {
          color: rgba(141, 152, 170, 1);
          margin-bottom: 16px;
        }
      }

      .item-box {
        .row {
          margin-bottom: 8px;
          display: flex;
          align-items: center;

          .title {
            margin-right: 24px;
            font-weight: bold;
            color: var(--o-text-color-primary);
            font-size: 16px;
            line-height: 24px;
          }
        }

        .desc {
          margin-bottom: 16px;
          color: rgba(141, 152, 170, 1);
        }
      }

      .section {
        padding: 16px 24px;
        display: flex;
        align-items: center;
        justify-content: space-between;
        border-radius: 4px;
        background-color: var(--o-bg-color-light);
        &.up {
          margin-top: 8px;
        }
        .left {
          display: flex;
          align-items: center;

          .file-img {
            margin-right: 8px;
          }

          .name-size {
            .name {
              color: var(--o-text-color-primary);
              font-size: 16px;
            }

            .size {
              color: rgba(141, 152, 170, 1);
            }

            .progress {
              display: flex;
              align-items: center;

              :deep(.el-progress) {
                width: 262px;
                margin-right: 8px;
                border-radius: 3px;
                background-color: var(--o-border-color-light);

                .el-progress__text {
                  display: none;
                }
              }

              .download-res {
                display: flex;
                align-items: center;

                .el-icon {
                  margin: 0 8px;
                  font-size: 16px;
                }
              }
            }
          }
        }

        .el-icon {
          margin-right: 4px;
          font-size: 16px;
          cursor: pointer;
        }
      }
      .sdi-sction {
        margin-top: 12px;
      }

      .serial-port-title {
        font-weight: 600;
        color: var(--o-text-color-primary);
        font-size: 16px;
        line-height: 24px;
        margin-bottom: 8px;
      }
    }
  }

  .npu {
    padding: 24px;
    border-radius: 4px;
    background-color: var(--o-bg-color-base);

    .title {
      color: var(--o-text-color-primary);
      font-size: 16px;
      line-height: 24px;
      margin-bottom: 8px;
    }

    .sub-title {
      font-size: 12px;
      color: rgba(141, 152, 170, 1);
      line-height: 16px;
    }

    .item {
      margin-top: 16px;
      padding: 16px 24px;
      border-radius: 4px;
      background-color: var(--o-bg-color-light);
      display: flex;
      align-items: center;
      justify-content: space-between;

      .left {
        display: flex;
        align-items: center;

        .folder {
          margin-right: 8px;
        }

        .file-info {
          .file-name {
            color: var(--o-text-color-primary);
            font-size: 16px;
          }
          .progress {
            display: flex;
            align-items: center;

            :deep(.el-progress) {
              width: 262px;
              margin-right: 8px;
              border-radius: 3px;
              background-color: var(--o-border-color-light);

              .el-progress__text {
                display: none;
              }
            }

            .download-res {
              display: flex;
              align-items: center;

              .el-icon {
                margin: 0 8px;
                font-size: 16px;
              }
            }
          }
        }
      }
    }
  }

  .right {
    position: relative;

    .loading-box {
      position: absolute;
      top: 0;
      left: 0;
      height: 100%;
      width: 100%;

      :deep(.loading .circular) {
        margin-top: -10px;
        margin-left: -10px;
        height: 20px;
        width: 20px;
      }

      :deep(.loading) {
        background-color: rgba(0, 0, 0, 0);
      }
    }

    .visibility-hidden {
      visibility: hidden;
      pointer-events: none;
    }
  }
  .sdi-dialog {
    display: flex;
    line-height: 16px;
    padding: 8px 16px;
    border-radius: 4px;
    background-color: var(--o-color-state-primary-secondary);
    display: flex;

    .el-icon {
      margin-right: 12px;
      display: inline-block;
      width: 16px;
      height: 16px;
      color: rgba(0, 119, 255, 1); //icon不随品牌色变化
      font-size: 18px;
    }
  }
  .sdi-content {
    color: var(--el-color-black);
    margin-left: 0;
  }
  .sdi-info-tip {
    margin-top: 16px;
  }
}

.dialog-content {
  .dialog-check-content {
    display: flex;
    .check-title {
      max-width: 110px;
      white-space: nowrap;
      margin-right: 24px;
      div {
        line-height: 32px;
        height: 32px;
      }
    }
    
    :deep(.el-checkbox__inner)::before{
      top: 3px;
      left: 3px;
    }
    .dialog-check-box {
      margin-right: 24px;
    }
    :deep(.el-checkbox-group){
      .el-checkbox{
        margin-right: 24px;
      }
      :nth-last-child(1){
        margin-right: 0;
      }
    }
  }
}
</style>
