<script setup lang="ts">
import { PageContainer } from 'antdv-pro-layout';
import { ColumnsType } from 'ant-design-vue/es/table';
import { message } from 'ant-design-vue/es';
import { reactive, ref, onMounted, onBeforeUnmount, markRaw } from 'vue';
import useI18n from '@/hooks/useI18n';
import { TooltipComponent } from 'echarts/components';
import { GaugeChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';
import * as echarts from 'echarts/core';
import { TitleComponent, LegendComponent } from 'echarts/components';
import { PieChart } from 'echarts/charts';
import { LabelLayout } from 'echarts/features';
import { useRoute } from 'vue-router';
import useAppStore from '@/store/modules/app';
import useDictStore from '@/store/modules/dict';
import { listAllNeInfo } from '@/api/ne/neInfo';
import { parseDateToStr } from '@/utils/date-utils';
const { getDict } = useDictStore();
const appStore = useAppStore();
const route = useRoute();
const { t } = useI18n();

echarts.use([
  TooltipComponent,
  GaugeChart,
  TitleComponent,
  LegendComponent,
  PieChart,
  CanvasRenderer,
  LabelLayout,
]);

/**图DOM节点实例对象 */
const statusBar = ref<HTMLElement | undefined>(undefined);

/**图实例对象 */
const statusBarChart = ref<any>(null);

/**网元状态字典数据 */
let indexColor = ref<DictType[]>([
  { label: 'Normal', value: 'normal', tagType: '', tagClass: '#91cc75' },
  {
    label: 'Abnormal',
    value: 'abnormal',
    tagType: '',
    tagClass: '#ee6666',
  },
]);

/**表格字段列 */
//customRender(){} ----单元格处理
let tableColumns: ColumnsType = [
  {
    title: t('views.index.object'),
    dataIndex: 'neName',
    align: 'left',
  },
  {
    title: t('views.index.realNeStatus'),
    dataIndex: 'serverState',
    align: 'left',
    key: 'status',
  },
  {
    title: t('views.index.reloadTime'),
    dataIndex: 'serverState',
    align: 'left',
    customRender(opt) {
      if (opt.value?.refreshTime) return parseDateToStr(opt.value?.refreshTime);
      return '-';
    },
  },
  {
    title: t('views.index.version'),
    dataIndex: 'serverState',
    align: 'left',
    customRender(opt) {
      return opt.value?.version || '-';
    },
  },
  {
    title: t('views.index.serialNum'),
    dataIndex: 'serverState',
    align: 'left',
    customRender(opt) {
      return opt.value?.sn || '-';
    },
  },
  {
    title: t('views.index.expiryDate'),
    dataIndex: 'serverState',
    align: 'left',
    customRender(opt) {
      return opt.value?.expire || '-';
    },
  },
  {
    title: t('views.index.ipAddress'),
    dataIndex: 'serverState',
    align: 'left',
    customRender(opt) {
      return opt.value?.neIP || '-';
    },
  },
];
/**表格状态类型 */
type TabeStateType = {
  /**加载等待 */
  loading: boolean;
  /**记录数据 */
  data: object[];
  /**勾选记录 */
  selectedRowKeys: (string | number)[];
};

/**表格状态 */
let tableState: TabeStateType = reactive({
  loading: false,
  data: [],
  selectedRowKeys: [],
});

/**表格状态 */
let nfInfo: any = reactive({
  obj: 'OMC',
  version: appStore.version,
  status: t('views.index.normal'),
  outTimeDate: '',
  serialNum: appStore.serialNum,
});

/**表格状态类型 */
type nfStateType = {
  /**主机名 */
  hostName: string;
  /**操作系统信息 */
  osInfo: string;
  /**IP地址 */
  ipAddress: string;
  /**版本 */
  version: string;
  /**CPU利用率 */
  cpuUse: string;
  /**内存使用 */
  memoryUse: string;
  /**用户容量 */
  capability: number;
  /**序列号 */
  serialNum: string;
  /**许可证到期日期 */
  /*  selectedRowKeys: (string | number)[];*/
  expiryDate: string;
};
/**网元详细信息 */
let pronInfo: nfStateType = reactive({
  hostName: '5gc',
  osInfo: 'Linux 5gc 4.15.0-112-generic 2020 x86_64 GNU/Linux',
  ipAddress: '-',
  version: '-',
  cpuUse: '-',
  memoryUse: '-',
  capability: 0,
  serialNum: '-',
  expiryDate: '-',
});

/**查询网元状态列表 */
function fnGetList(one: boolean) {
  if (tableState.loading) return;
  one && (tableState.loading = true);
  listAllNeInfo({ bandStatus: true }).then(res => {
    tableState.data = res.data;
    tableState.loading = false;
    var rightNum = 0;
    var errorNum = 0;
    res.data.forEach((item: any) => {
      if (item.serverState.online) {
        rightNum++;
      } else {
        errorNum++;
      }
    });
    const optionData: any = {
      title: {
        text: '',
        subtext: '',
        left: 'center',
      },
      tooltip: {
        trigger: 'item',
      },
      legend: {
        orient: 'vertical',
        left: 'left',
      },
      color: indexColor.value.map(item => item.tagClass),
      series: [
        {
          name: t('views.index.realNeStatus'),
          type: 'pie',
          radius: '70%',
          center: ['50%', '50%'],
          data: [
            { value: rightNum, name: t('views.index.normal') },
            { value: errorNum, name: t('views.index.abnormal') },
          ],
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },

          label: {},
        },
      ],
    };

    fnDesign(statusBar.value, optionData);
  });
}

function fnDesign(container: HTMLElement | undefined, option: any) {
  if (!container) return;

  if (!statusBarChart.value) {
    statusBarChart.value = markRaw(echarts.init(container, 'light'));
  }
  option && statusBarChart.value.setOption(option);

  // 创建 ResizeObserver 实例
  var observer = new ResizeObserver(entries => {
    if (statusBarChart.value) {
      statusBarChart.value.resize();
    }
  });
  // 监听元素大小变化
  observer.observe(container);
}

/**抽屉 网元详细信息 */
const open = ref(false);
const closeDrawer = () => {
  open.value = false;
};
/**抽屉 网元详细信息 */

/**监听表格行事件*/
function rowClick(record: any, index: any) {
  return {
    onClick: (event: any) => {
      let pronData = JSON.parse(JSON.stringify(record.serverState));
      if (!pronData.online) {
        message.error(t('views.index.neStatus'), 2);
        return false;
      } else {
        const totalMemInKB = pronData.mem?.totalMem;
        const nfUsedMemInKB = pronData.mem?.nfUsedMem;
        const sysMemUsageInKB = pronData.mem?.sysMemUsage;

        // 将KB转换为MB
        const totalMemInMB = Math.round((totalMemInKB / 1024) * 100) / 100;
        const nfUsedMemInMB = Math.round((nfUsedMemInKB / 1024) * 100) / 100;
        const sysMemUsageInMB =
          Math.round((sysMemUsageInKB / 1024) * 100) / 100;

        //渲染详细信息
        pronInfo = {
          hostName: pronData.hostname,
          osInfo: pronData.os,
          ipAddress: pronData.neIP,
          version: pronData.version,
          cpuUse:
            pronData.neName +
            ':' +
            pronData.cpu?.nfCpuUsage / 100 +
            '%; ' +
            'SYS:' +
            pronData.cpu?.sysCpuUsage / 100 +
            '%',
          memoryUse:
            'Total:' +
            totalMemInMB +
            'MB; ' +
            pronData.name +
            ':' +
            nfUsedMemInMB +
            'MB; SYS:' +
            sysMemUsageInMB +
            'MB',
          capability: pronData.capability,
          serialNum: pronData.sn,
          expiryDate: pronData.expire,
        };
      }
      open.value = true;
    },
  };
}
let timer: any;

/**
 * 国际化翻译转换
 */
function fnLocale() {
  let title = route.meta.title as string;
  if (title.indexOf('router.') !== -1) {
    title = t(title);
  }
  appStore.setTitle(title);
}

onMounted(() => {
  getDict('index_status')
    .then(res => {
      if (res.length > 0) {
        indexColor.value = res;
      }
    })
    .finally(() => {
      fnLocale();
      fnGetList(true);
      timer = setInterval(() => fnGetList(false), 10000); // 每隔10秒执行一次
    });
});

// 在组件卸载之前清除定时器

onBeforeUnmount(() => {
  clearInterval(timer);
});
</script>

<template>
  <PageContainer :breadcrumb="{}">
    <div>
      <a-drawer :open="open" @close="closeDrawer" :width="700">
        <a-descriptions bordered :column="1" :label-style="{ width: '160px' }">
          <a-descriptions-item :label="t('views.index.hostName')">{{
            pronInfo.hostName
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.osInfo')">{{
            pronInfo.osInfo
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.ipAddress')">{{
            pronInfo.ipAddress
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.version')">{{
            pronInfo.version
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.capability')">{{
            pronInfo.capability
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.cpuUse')">{{
            pronInfo.cpuUse
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.memoryUse')">{{
            pronInfo.memoryUse
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.serialNum')">{{
            pronInfo.serialNum
          }}</a-descriptions-item>
          <a-descriptions-item :label="t('views.index.expiryDate')">{{
            pronInfo.expiryDate
          }}</a-descriptions-item>
        </a-descriptions>
      </a-drawer>
    </div>

    <a-row :gutter="16">
      <a-col :lg="14" :md="16" :xs="24">
        <!-- 表格列表 -->
        <a-table
          class="table"
          row-key="id"
          size="small"
          :columns="tableColumns"
          :loading="tableState.loading"
          :data-source="tableState.data"
          :pagination="false"
          :scroll="{ x: true }"
          :customRow="rowClick"
        >
          <template #bodyCell="{ column, record }">
            <template v-if="column.key === 'status'">
              <div v-if="record.serverState.online">
                <a-tag color="blue">{{ t('views.index.normal') }}</a-tag>
              </div>
              <div v-else>
                <a-tag color="pink">{{ t('views.index.abnormal') }}</a-tag>
              </div>
            </template>
          </template>
        </a-table>
      </a-col>
      <a-col :lg="10" :md="8" :xs="24">
        <a-card
          :title="t('views.index.runStatus')"
          style="margin-bottom: 16px"
          size="small"
        >
          <div style="width: 100%; min-height: 200px" ref="statusBar"></div>
        </a-card>
        <a-card
          :title="t('views.index.mark')"
          style="margin-top: 16px"
          size="small"
        >
          <a-descriptions
            bordered
            :column="1"
            :label-style="{ width: '160px' }"
          >
            <a-descriptions-item :label="t('views.index.object')">{{
              nfInfo.obj
            }}</a-descriptions-item>
            <template v-if="nfInfo.obj === 'OMC'">
              <a-descriptions-item :label="t('views.index.versionNum')">{{
                nfInfo.version
              }}</a-descriptions-item>
              <a-descriptions-item :label="t('views.index.systemStatus')">{{
                nfInfo.status
              }}</a-descriptions-item>
            </template>
            <template v-else>
              <a-descriptions-item :label="t('views.index.serialNum')">{{
                nfInfo.serialNum
              }}</a-descriptions-item>
              <a-descriptions-item :label="t('views.index.expiryDate')">{{
                nfInfo.outTimeDate
              }}</a-descriptions-item>
            </template>
          </a-descriptions>
        </a-card>
      </a-col>
    </a-row>
  </PageContainer>
</template>

<style lang="less" scoped></style>
