<script setup lang="ts">
import * as echarts from 'echarts/core';
import {
  TooltipComponent,
  TooltipComponentOption,
  GridComponent,
  GridComponentOption,
  LegendComponent,
  LegendComponentOption,
  DataZoomComponent,
  DataZoomComponentOption,
} from 'echarts/components';
import { LineChart, LineSeriesOption } from 'echarts/charts';
import { UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';

import {
  reactive,
  ref,
  onMounted,
  toRaw,
  markRaw,
  nextTick,
  onBeforeUnmount,
  h,
  watch,
} from 'vue';
import { PageContainer } from 'antdv-pro-layout';
import { message, Modal, TableColumnType } from 'ant-design-vue/es';
import { SizeType } from 'ant-design-vue/es/config-provider';
import { MenuInfo } from 'ant-design-vue/es/menu/src/interface';
import TableColumnsDnd from '@/components/TableColumnsDnd/index.vue';
import {
  RESULT_CODE_ERROR,
  RESULT_CODE_SUCCESS,
} from '@/constants/result-constants';
import useNeInfoStore from '@/store/modules/neinfo';
import useI18n from '@/hooks/useI18n';
import { getKPITitle, listKPIData } from '@/api/perfManage/goldTarget';
import { parseDateToStr } from '@/utils/date-utils';
import { writeSheet } from '@/utils/execl-utils';
import saveAs from 'file-saver';
import { generateColorRGBA } from '@/utils/generate-utils';
import { OptionsType, WS } from '@/plugins/ws-websocket';
import { useRoute } from 'vue-router';
import { LineOutlined } from '@ant-design/icons-vue';
import useLayoutStore from '@/store/modules/layout';
import { SelectValue } from 'ant-design-vue/es/select';
import type { DefaultOptionType } from 'ant-design-vue/es/select';
import dayjs from 'dayjs';
const layoutStore = useLayoutStore();
const neInfoStore = useNeInfoStore();
const route = useRoute();
const { t, currentLocale } = useI18n();
const ws = new WS();

echarts.use([
  TooltipComponent,
  GridComponent,
  LegendComponent,
  DataZoomComponent,
  LineChart,
  CanvasRenderer,
  UniversalTransition,
]);

type EChartsOption = echarts.ComposeOption<
  | TooltipComponentOption
  | GridComponentOption
  | LegendComponentOption
  | DataZoomComponentOption
  | LineSeriesOption
>;

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

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

/**网元参数 */
let neCascaderOptions = ref<Record<string, any>[]>([]);

/**记录开始结束时间 */
let queryRangePicker = ref<[string, string]>(['', '']);
//日期快捷选择
const ranges = ref([
  {
    label: t('views.perfManage.customTarget.toDay'),
    value: [dayjs().startOf('day'), dayjs()],
  },
  {
    label: t('views.perfManage.customTarget.ago1Hour'),
    value: [
      dayjs().subtract(1, 'hour').startOf('hour'),
      dayjs().subtract(1, 'hour').endOf('hour'),
    ],
  },
  // {
  //   label: t('views.perfManage.customTarget.ago3Hour'),
  //   value: [dayjs().subtract(3, 'hours'), dayjs()],
  // },
  // {
  //   label: t('views.perfManage.customTarget.ago6Hour'),
  //   value: [dayjs().subtract(6, 'hours'), dayjs()],
  // },
  {
    label: t('views.perfManage.customTarget.ago1Day'),
    value: [
      dayjs().subtract(1, 'day').startOf('day'),
      dayjs().subtract(1, 'day').endOf('day'),
    ],
  },
  {
    label: t('views.perfManage.customTarget.ago7Day'),
    value: [
      dayjs().subtract(7, 'day').startOf('day'),
      dayjs().subtract(1, 'day').endOf('day'),
    ],
  },
  {
    label: t('views.perfManage.customTarget.ago15Day'),
    value: [
      dayjs().subtract(15, 'day').startOf('day'),
      dayjs().subtract(1, 'day').endOf('day'),
    ],
  },
]);

/**表格字段列 */
let tableColumns = ref<any[]>([]);

/**表格字段列排序 */
let tableColumnsDnd = ref<any[]>([]);

/**表格分页器参数 */
let tablePagination = reactive({
  /**当前页数 */
  current: 1,
  /**每页条数 */
  pageSize: 20,
  /**默认的每页条数 */
  defaultPageSize: 20,
  /**指定每页可以显示多少条 */
  pageSizeOptions: ['10', '20', '50', '100'],
  /**只有一页时是否隐藏分页器 */
  hideOnSinglePage: false,
  /**是否可以快速跳转至某页 */
  showQuickJumper: true,
  /**是否可以改变 pageSize */
  showSizeChanger: true,
  /**数据总数 */
  total: 0,
  showTotal: (total: number) => t('common.tablePaginationTotal', { total }),
  onChange: (page: number, pageSize: number) => {
    tablePagination.current = page;
    tablePagination.pageSize = pageSize;
  },
});

/**表格状态类型 */
type TabeStateType = {
  /**加载等待 */
  loading: boolean;
  /**紧凑型 */
  size: SizeType;
  /**搜索栏 */
  seached: boolean;
  /**记录数据 */
  data: Record<string, any>[];
  /**显示表格 */
  showTable: boolean;
};

/**表格状态 */
let tableState: TabeStateType = reactive({
  tableColumns: [],
  loading: false,
  size: 'middle',
  seached: true,
  data: [],
  showTable: false,
});

/**表格紧凑型变更操作 */
function fnTableSize({ key }: MenuInfo) {
  tableState.size = key as SizeType;
}

/**选中的网元信息 */
let selectedNes = ref<{ neType: string; neId: string }[]>([]);

/**查询参数 */
let queryParams: any = reactive({
  /**网元类型 */
  neType: '',
  /**网元标识列表 */
  neIds: [] as string[],
  /**颗粒度 */
  interval: 900,
  /**开始时间 */
  startTime: '',
  /**结束时间 */
  endTime: '',
  /**排序字段 */
  sortField: 'timeGroup',
  /**排序方式 */
  sortOrder: 'desc',
});

/**表格分页、排序、筛选变化时触发操作, 排序方式，取值为 ascend descend */
function fnTableChange(pagination: any, filters: any, sorter: any, extra: any) {
  const { columnKey, order } = sorter;
  if (!order) return;
  if (order.startsWith(queryParams.sortOrder)) return;

  if (order) {
    queryParams.sortField = columnKey;
    queryParams.sortOrder = order.replace('end', '');
  } else {
    queryParams.sortOrder = 'asc';
  }

  fnGetList();
}

/**对象信息状态类型 */
type StateType = {
  /**网元类型 */
  neType: string;
  /**选中的网元ID列表 */
  neIds: string[];
  /**图表实时统计 */
  chartRealTime: boolean;
  /**图表标签选择 */
  chartLegendSelectedFlag: boolean;
};

/**对象信息状态 */
let state: StateType = reactive({
  neType: '',
  neIds: [],
  chartRealTime: false,
  chartLegendSelectedFlag: true,
});

// 存储每个指标的临时固定颜色
const kpiColors = new Map<string, string>();
//legend表格数据
const kpiStats: any = ref([]);

// 添加表格列定义
const statsColumns: TableColumnType<any>[] = [
  {
    title: '',
    key: 'icon',
    width: 50,
    customRender: ({ record }: { record: any }) => {
      return h(LineOutlined, {
        style: {
          color: kpiColors.get(record.kpiId) || '#000', // 使用与折线图相同的颜色
          fontSize: '30px', // 增大图标尺寸到30px
          fontWeight: 'bold', // 加粗
        },
      });
    },
  },
  {
    title: t('views.perfManage.kpiOverView.kpiName'),
    dataIndex: 'title',
    key: 'title',
    width: '65%',
  },
  {
    title: t('views.perfManage.kpiOverView.totalValue'),
    dataIndex: 'total',
    key: 'total',
    width: '24%',
    sortDirections: ['ascend', 'descend'],
  },
  {
    title: t('views.perfManage.kpiOverView.avgValue'),
    dataIndex: 'avg',
    key: 'avg',
    width: '24%',
    sortDirections: ['ascend', 'descend'],
  },
  {
    title: t('views.perfManage.kpiOverView.maxValue'),
    dataIndex: 'max',
    key: 'max',
    width: '17%',
    sortDirections: ['ascend', 'descend'],
  },
  {
    title: t('views.perfManage.kpiOverView.minValue'),
    dataIndex: 'min',
    key: 'min',
    width: '17%',
    sortDirections: ['ascend', 'descend'],
  },
];

/**
 * 数据列表导出
 */
function fnRecordExport() {
  Modal.confirm({
    title: 'Tip',
    content: t('views.perfManage.goldTarget.exportSure'),
    onOk() {
      const key = 'exportKPI';
      message.loading({ content: t('common.loading'), key });

      if (tableState.data.length <= 0) {
        message.error({
          content: t('views.perfManage.goldTarget.exportEmpty'),
          key,
          duration: 2,
        });
        return;
      }

      const tableColumnsTitleArr: string[] = [];
      const tableColumnsKeyArr: string[] = [];
      for (const columns of tableColumnsDnd.value) {
        tableColumnsTitleArr.push(`${columns.title}`);
        tableColumnsKeyArr.push(`${columns.key}`);
      }

      const kpiDataArr = [];
      for (const item of tableState.data) {
        const kpiData: Record<string, any> = {};
        const keys = Object.keys(item);
        for (let i = 0; i <= tableColumnsKeyArr.length; i++) {
          for (const key of keys) {
            if (tableColumnsKeyArr[i] === key) {
              const title = tableColumnsTitleArr[i];
              if (key === 'timeGroup') {
                kpiData[title] = parseDateToStr(item[key]);
              } else {
                kpiData[title] = item[key];
              }
            }
          }
        }
        kpiDataArr.push(kpiData);
      }

      writeSheet(kpiDataArr, 'KPI', { header: tableColumnsTitleArr })
        .then(fileBlob => saveAs(fileBlob, `kpi_data_${Date.now()}.xlsx`))
        .finally(() => {
          message.success({
            content: t('common.msgSuccess', { msg: t('common.export') }),
            key,
            duration: 2,
          });
        });
    },
  });
}

/**可选网元列表 */
let availableNeIds = ref<{ label: string; value: string }[]>([]);

// 添加类型定义
interface KPIStats {
  kpiId: string;
  title: string;
  rawKpiId: string;
  rawKpiTitle: string;
  neId: string;
  max: number;
  min: number;
  avg: number;
  total: number;
}

/**处理网元类型变化 */
function handleNeTypeChange(
  value: SelectValue,
  option: DefaultOptionType | DefaultOptionType[]
) {
  if (!value) {
    state.neType = '';
    state.neIds = [];
    availableNeIds.value = [];
    return;
  }

  state.neType = value as string;
  queryParams.neType = value as string;
  state.neIds = []; // 清空已选网元

  // 根据选择的网元类型更新可选的网元ID列表
  const neTypeOption = neCascaderOptions.value.find(
    item => item.value === value
  );
  if (
    neTypeOption &&
    neTypeOption.children &&
    neTypeOption.children.length > 0
  ) {
    availableNeIds.value = neTypeOption.children.map((ne: any) => ({
      label: `${ne.label}`,
      value: ne.neId,
    }));

    // 默认选择第一个网元
    if (availableNeIds.value.length > 0) {
      state.neIds = [availableNeIds.value[0].value];
      queryParams.neIds = [...state.neIds];
    }
  } else {
    availableNeIds.value = [];
  }
}

/**处理网元ID变化 */
function handleNeIdsChange(
  value: SelectValue,
  option: DefaultOptionType | DefaultOptionType[]
) {
  if (!value || (Array.isArray(value) && value.length === 0)) {
    state.neIds = [];
    queryParams.neIds = [];
    return;
  }

  const values = Array.isArray(value) ? value : [value];
  state.neIds = values as string[];
  queryParams.neIds = [...(values as string[])];

  // 更新选中的网元信息
  selectedNes.value = (values as string[]).map(neId => ({
    neType: state.neType,
    neId: neId,
  }));
}

/**查询数据列表表头 */
function fnGetListTitle() {
  // 当前语言
  var language = currentLocale.value.split('_')[0];
  if (language === 'zh') language = 'cn';

  // 获取表头文字，只传递纯网元类型
  getKPITitle(state.neType)
    .then(res => {
      //处理getKPITitle返回的结果
      if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
        //检查值
        tableColumns.value = []; //设为空数组
        const columns: any[] = []; //初始化，构建新表头
        for (const item of res.data) {
          //遍历res.data
          const kpiDisplay = item[`${language}Title`]; //提取标题kpiDisplay和ID标识kpiValue
          const kpiValue = item[`kpiId`];
          columns.push({
            //
            title: kpiDisplay,
            dataIndex: kpiValue,
            align: 'left',
            key: kpiValue,
            resizable: true,
            width: 100,
            minWidth: 150,
            maxWidth: 300,
          });
        }
        columns.push({
          title: t('views.perfManage.perfData.neName'),
          dataIndex: 'neName',
          key: 'neName',
          align: 'left',
          width: 100,
        });
        columns.push({
          title: t('views.perfManage.goldTarget.time'),
          dataIndex: 'timeGroup',
          align: 'left',
          fixed: 'right',
          key: 'timeGroup',
          sorter: true,
          width: 100,
        });
        nextTick(() => {
          tableColumns.value = columns;
        });
        return true;
      } else {
        message.warning({
          content: t('common.getInfoFail'),
          duration: 2,
        });
        return false;
      }
    })
    .then(result => {
      //result是前一个.then返回的值(true or false)
      result && fnGetList();
    });
}

/**查询数据列表 */
async function fnGetList() {
  if (tableState.loading) return;
  tableState.loading = true;

  try {
    // 获取所有网元数据
    let allNeData: any[] = [];

    // 每个选中的网元ID发送一个请求
    const promises = state.neIds.map(neId => {
      const params = {
        ...queryParams,
        neId: neId,
        startTime: queryRangePicker.value[0],
        endTime: queryRangePicker.value[1],
      };
      // 不需要将neIds发送到后端
      delete params.neIds;

      return listKPIData(toRaw(params)).then(res => {
        if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
          // 添加网元ID标识，方便后续处理
          return res.data.map(item => ({
            ...item,
            _neId: neId,
            neName: `${state.neType}-${neId}`,
          }));
        }
        return [];
      });
    });

    const results = await Promise.all(promises);
    allNeData = results.flat();

    tablePagination.total = allNeData.length;
    tableState.data = allNeData;

    // 调用图表渲染函数
    fnRanderChartData();

    // 封装legend表格数据
    kpiStats.value = [];

    // 为每个指标和每个网元创建统计数据
    for (const columns of tableColumns.value) {
      if (
        columns.key === 'neName' ||
        columns.key === 'startIndex' ||
        columns.key === 'timeGroup'
      ) {
        continue;
      }

      // 处理每个网元
      for (const neId of state.neIds) {
        // 过滤该网元的数据
        const neData = tableState.data.filter(item => item._neId === neId);

        if (neData.length === 0) continue;

        const values = neData.map((item: any) => {
          return item[columns.key] ? Number(item[columns.key]) : 0;
        });

        // 计算总值
        const total = Number(
          values.reduce((sum, val) => sum + val, 0).toFixed(2)
        );

        // 计算平均值
        const avg =
          values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;

        kpiStats.value.push({
          kpiId: `${columns.key}_${neId}`, // 使用组合ID来唯一标识指标-网元对
          title: `${columns.title}(${neId})`, // 在标题中显示网元ID
          rawKpiId: columns.key,
          rawKpiTitle: columns.title,
          neId: neId,
          max: values.length > 0 ? Math.max(...values) : 0,
          min: values.length > 0 ? Math.min(...values) : 0,
          avg: avg,
          total: total,
        });
      }
    }

    return true;
  } catch (error) {
    console.error('Error fetching data:', error);
    message.error({
      content: t('common.getInfoFail'),
      duration: 2,
    });
    return false;
  } finally {
    tableState.loading = false;
  }
}

/**切换显示类型 图或表格 */
function fnChangShowType() {
  tableState.showTable = !tableState.showTable;
}

/**绘制图表 */
function fnRanderChart() {
  const container: HTMLElement | undefined = kpiChartDom.value; //获取图表容器DOM元素
  if (!container) return; //若没有，则退出函数
  kpiChart.value = markRaw(echarts.init(container, 'light'));
  //初始化Echarts图表实例，应用light主题，并赋值给kpiChart.value，markRaw是vue函数，用于标记对象为不可响应
  const option: any = {
    //定义图表的配置对象，tooltip的出发方式为axis
    tooltip: {
      trigger: 'axis',
      position: function (pt: any) {
        return [pt[0], '10%'];
      },
      confine: true, // 限制 tooltip 显示范围
      backgroundColor:
        document.documentElement.getAttribute('data-theme') === 'dark'
          ? 'rgba(48, 48, 48, 0.8)'
          : 'rgba(255, 255, 255, 0.9)',
      borderColor:
        document.documentElement.getAttribute('data-theme') === 'dark'
          ? '#555'
          : '#ddd',
      textStyle: {
        color:
          document.documentElement.getAttribute('data-theme') === 'dark'
            ? '#CACADA'
            : '#333',
      },
    },
    xAxis: {
      //x类别轴
      type: 'category',
      boundaryGap: false,
      data: [], // 数据x轴
      axisLabel: {
        color:
          document.documentElement.getAttribute('data-theme') === 'dark'
            ? '#CACADA'
            : '#333',
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: getSplitLineColor(),
        },
      },
    },
    yAxis: {
      //y类别轴
      type: 'value',
      boundaryGap: [0, '100%'],
      axisLabel: {
        formatter: '{value}',
        color:
          document.documentElement.getAttribute('data-theme') === 'dark'
            ? '#CACADA'
            : '#333',
      },
      splitNumber: 5,
      scale: true,
      splitLine: {
        show: true,
        lineStyle: {
          color: getSplitLineColor(),
        },
      },
    },
    legend: {
      show: false,
      //图例垂直滚动
      type: 'scroll',
      orient: 'vertical',
      top: 40,
      right: 20,
      itemWidth: 20,
      itemGap: 25,
      textStyle: {
        color: '#646A73',
      },
      icon: 'circle',
      selected: {},
    },
    grid: {
      //网格区域边距
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true,
    },
    series: [], // 数据y轴
  };
  kpiChart.value.setOption(option); //设置图表配置项，应用到kpiChart实例上

  // 创建 ResizeObserver 实例 监听图表容器大小变化，并在变化时调整图表大小
  var observer = new ResizeObserver(entries => {
    if (kpiChart.value) {
      kpiChart.value.resize();
    }
  });
  // 监听元素大小变化
  observer.observe(container);
}

/**图表标签选择 */
let chartLegendSelected: Record<string, boolean> = {};
/**图表配置数据x轴 */
let chartDataXAxisData: string[] = [];
/**图表配置数据y轴 */
let chartDataYSeriesData: Record<string, any>[] = [];

/**图表数据渲染 */
function fnRanderChartData() {
  if (kpiChart.value == null || tableState.data.length <= 0) {
    return;
  }

  // 重置
  chartLegendSelected = {};
  chartDataXAxisData = [];
  chartDataYSeriesData = [];

  // 为每个网元的每个指标创建一条线
  for (const neId of state.neIds) {
    for (const columns of tableColumns.value) {
      if (
        columns.key === 'neName' ||
        columns.key === 'startIndex' ||
        columns.key === 'timeGroup'
      ) {
        continue;
      }

      const kpiId = `${columns.key}_${neId}`;
      const seriesName = `${columns.title}(${neId})`;

      // 获取或生成颜色
      const color = kpiColors.get(kpiId) || generateColorRGBA();
      kpiColors.set(kpiId, color);

      const seriesData = {
        name: seriesName,
        key: kpiId,
        type: 'line',
        symbol: 'none',
        symbolSize: 6,
        smooth: 0.6,
        showSymbol: true,
        sampling: 'lttb',
        itemStyle: {
          color: color,
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: color.replace(')', ',0.8)'),
            },
            {
              offset: 1,
              color: color.replace(')', ',0.3)'),
            },
          ]),
        },
        data: [] as (number | null)[],
      };

      chartDataYSeriesData.push(seriesData);

      // 默认所有指标都显示
      chartLegendSelected[seriesName] = true;
    }
  }

  // 获取所有时间点并格式化
  const timePoints = [
    ...new Set(tableState.data.map(item => item.timeGroup)),
  ].sort();
  chartDataXAxisData = timePoints.map(time => parseDateToStr(+time));

  // 填充数据
  for (const series of chartDataYSeriesData) {
    const [kpiKey, neId] = series.key.split('_');
    const neData = tableState.data.filter(item => item._neId === neId);
    series.data = timePoints.map(time => {
      const dataPoint = neData.find(item => item.timeGroup === time);
      return dataPoint ? +dataPoint[kpiKey] : null;
    });
  }

  // 如果有选中的行，只显示选中的指标
  if (selectedRows.value.length > 0) {
    Object.keys(chartLegendSelected).forEach(key => {
      chartLegendSelected[key] = false;
    });

    kpiStats.value.forEach((item: KPIStats) => {
      if (selectedRows.value.includes(item.kpiId)) {
        chartLegendSelected[item.title] = true;
      }
    });
  }

  // 更新图表
  kpiChart.value.setOption(
    {
      legend: {
        selected: chartLegendSelected,
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        axisLabel: {
          color:
            document.documentElement.getAttribute('data-theme') === 'dark'
              ? '#CACADA'
              : '#333',
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: getSplitLineColor(),
          },
        },
        data: chartDataXAxisData,
      },
      series: chartDataYSeriesData,
    },
    {
      replaceMerge: ['xAxis', 'series'],
    }
  );
}

/**图表折线显示全部 */
function fnLegendSelected(bool: any) {
  // 清空选中状态
  selectedRows.value = [];

  // 更新所有图例的显示状态
  Object.keys(chartLegendSelected).forEach(key => {
    chartLegendSelected[key] = bool;
  });

  // 更新图表设置
  kpiChart.value.setOption({
    legend: {
      selected: chartLegendSelected,
    },
  });
}

/**图表实时统计 */
function fnRealTimeSwitch(bool: any) {
  if (bool) {
    tableState.seached = false;
    // 清空图表数据
    chartData.value = [];
    chartDataXAxisData = [];
    chartDataYSeriesData = [];

    // 重新初始化图表配置
    const option = {
      tooltip: {
        trigger: 'axis',
        position: function (pt: any) {
          return [pt[0], '10%'];
        },
        confine: true,
        backgroundColor:
          document.documentElement.getAttribute('data-theme') === 'dark'
            ? 'rgba(48, 48, 48, 0.8)'
            : 'rgba(255, 255, 255, 0.9)',
        borderColor:
          document.documentElement.getAttribute('data-theme') === 'dark'
            ? '#555'
            : '#ddd',
        textStyle: {
          color:
            document.documentElement.getAttribute('data-theme') === 'dark'
              ? '#CACADA'
              : '#333',
        },
      },
      xAxis: {
        type: 'category',
        boundaryGap: false,
        data: [],
        axisLabel: {
          color:
            document.documentElement.getAttribute('data-theme') === 'dark'
              ? '#CACADA'
              : '#333',
        },
        splitLine: {
          show: true,
          lineStyle: {
            color: getSplitLineColor(),
          },
        },
      },
      yAxis: {
        type: 'value',
        boundaryGap: [0, '100%'],
        axisLabel: {
          formatter: '{value}',
          color:
            document.documentElement.getAttribute('data-theme') === 'dark'
              ? '#CACADA'
              : '#333',
        },
        splitNumber: 5,
        scale: true,
        splitLine: {
          show: true,
          lineStyle: {
            color: getSplitLineColor(),
          },
        },
      },
      legend: {
        show: false,
        type: 'scroll',
        orient: 'vertical',
        top: 40,
        right: 20,
        itemWidth: 20,
        itemGap: 25,
        textStyle: {
          color: '#646A73',
        },
        icon: 'circle',
        selected: {},
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      series: [],
    };

    kpiChart.value.setOption(option);

    // 建立链接
    const options: OptionsType = {
      url: '/ws',
      params: {
        /**订阅通道组
         * 指标(GroupID:10_neType_neId)
         * 为所有选中的网元创建订阅
         */
        subGroupID: state.neIds
          .map(neId => `10_${state.neType}_${neId}`)
          .join(','),
      },
      onmessage: wsMessage,
      onerror: wsError,
    };
    ws.connect(options);
  } else {
    tableState.seached = true;
    ws.close();
  }
}

/**接收数据后回调 */
function wsError(ev: any) {
  // 接收数据后回调
  console.error(ev);
}

// 添加 ChartDataItem 接口
interface ChartDataItem {
  date: string; // 存储完整的时间字符串
  [kpiId: string]: string | number; // 动态指标
}

// 添加图表数据响应式数组
const chartData = ref<ChartDataItem[]>([]);

/**接收数据后回调 */
function wsMessage(res: Record<string, any>) {
  const { code, requestId, data } = res;
  if (code === RESULT_CODE_ERROR) {
    console.warn(res.msg);
    return;
  }

  // 订阅组信息
  if (!data?.groupId) {
    return;
  }

  // 解析订阅组ID获取网元类型和ID
  const [_, neType, neId] = data.groupId.split('_');
  if (!neType || !neId) return;

  // kpiEvent 黄金指标指标事件
  const kpiEvent = data.data;
  if (!kpiEvent) return;

  // 构造新的数据点
  const newData: ChartDataItem = {
    date: kpiEvent.timeGroup?.toString() || Date.now().toString(),
  };

  // 为每个网元的每个指标添加数据
  for (const columns of tableColumns.value) {
    if (
      columns.key === 'neName' ||
      columns.key === 'startIndex' ||
      columns.key === 'timeGroup'
    ) {
      continue;
    }
    const key = `${columns.key}_${neId}`;
    // 确保从 kpiEvent 中获取正确的指标值
    const value = kpiEvent[columns.key];
    newData[key] = value !== undefined ? Number(value) : 0;
  }

  // 添加到数据列表
  tableState.data.unshift(kpiEvent);
  tablePagination.total++;

  // 非对应网元类型
  if (neType !== queryParams.neType) return;

  // 限制数据量
  if (tableState.data.length > 100) {
    tableState.data.pop();
  }

  // 更新图表数据
  chartData.value.unshift(newData);
  if (chartData.value.length > 100) {
    chartData.value.pop();
  }

  // 使用 requestAnimationFrame 更新图表
  requestAnimationFrame(() => {
    if (!kpiChart.value) return;

    // 重新生成 series 数据
    const series = [];
    for (const neId of state.neIds) {
      for (const columns of tableColumns.value) {
        if (
          columns.key === 'neName' ||
          columns.key === 'startIndex' ||
          columns.key === 'timeGroup'
        ) {
          continue;
        }

        const kpiId = `${columns.key}_${neId}`;
        const seriesName = `${columns.title}(${neId})`;

        // 获取或生成颜色
        const color = kpiColors.get(kpiId) || generateColorRGBA();
        kpiColors.set(kpiId, color);

        // 获取该网元该指标的所有数据点
        const dataPoints = chartData.value.map(item => {
          const value = item[kpiId];
          return value !== undefined ? Number(value) : 0;
        });

        series.push({
          name: seriesName,
          type: 'line',
          data: dataPoints,
          symbol: 'none',
          symbolSize: 6,
          smooth: 0.6,
          showSymbol: true,
          itemStyle: {
            color: color,
          },
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              {
                offset: 0,
                color: color.replace(')', ',0.8)'),
              },
              {
                offset: 1,
                color: color.replace(')', ',0.3)'),
              },
            ]),
          },
        });
      }
    }

    // 更新图表
    kpiChart.value.setOption(
      {
        xAxis: {
          type: 'category',
          boundaryGap: false,
          axisLabel: {
            color:
              document.documentElement.getAttribute('data-theme') === 'dark'
                ? '#CACADA'
                : '#333',
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: getSplitLineColor(),
            },
          },
          data: chartData.value.map(item => parseDateToStr(+item.date)),
        },
        series: series,
      },
      {
        replaceMerge: ['xAxis', 'series'],
      }
    );
  });

  // 更新统计数据
  updateKpiStats();
}

// 添加更新统计数据的函数
function updateKpiStats() {
  kpiStats.value = [];

  // 为每个指标和每个网元创建统计数据
  for (const columns of tableColumns.value) {
    if (
      columns.key === 'neName' ||
      columns.key === 'startIndex' ||
      columns.key === 'timeGroup'
    ) {
      continue;
    }

    // 处理每个网元
    for (const neId of state.neIds) {
      // 过滤该网元的数据
      const neData = tableState.data.filter(item => item._neId === neId);

      if (neData.length === 0) continue;

      const values = neData.map((item: any) => {
        return item[columns.key] ? Number(item[columns.key]) : 0;
      });

      // 计算总值
      const total = Number(
        values.reduce((sum, val) => sum + val, 0).toFixed(2)
      );

      // 计算平均值
      const avg =
        values.length > 0 ? Number((total / values.length).toFixed(2)) : 0;

      kpiStats.value.push({
        kpiId: `${columns.key}_${neId}`,
        title: `${columns.title}(${neId})`,
        rawKpiId: columns.key,
        rawKpiTitle: columns.title,
        neId: neId,
        max: values.length > 0 ? Math.max(...values) : 0,
        min: values.length > 0 ? Math.min(...values) : 0,
        avg: avg,
        total: total,
      });
    }
  }
}

// 添加一个变量来跟踪当前选中的行
const selectedRows = ref<string[]>([]);

// 修改行点击处理函数
function handleRowClick(record: KPIStats) {
  const index = selectedRows.value.indexOf(record.kpiId);

  // 如果已经选中，取消选中
  if (index > -1) {
    selectedRows.value.splice(index, 1);
  } else {
    // 添加新的选中项
    selectedRows.value.push(record.kpiId);

    // 如果是第一个选中项，重置所有图例为不显示
    if (selectedRows.value.length === 1) {
      Object.keys(chartLegendSelected).forEach(key => {
        chartLegendSelected[key] = false;
      });
    }
  }

  // 更新图例可见性
  if (selectedRows.value.length === 0) {
    // 如果没有选中项，显示所有图例
    Object.keys(chartLegendSelected).forEach(key => {
      chartLegendSelected[key] = true;
    });
  } else {
    // 如果有选中项，只显示选中的图例
    kpiStats.value.forEach((item: KPIStats) => {
      const isSelected = selectedRows.value.includes(item.kpiId);
      chartLegendSelected[item.title] = isSelected;
    });
  }

  // 更新图表设置
  kpiChart.value.setOption({
    legend: {
      selected: chartLegendSelected,
    },
  });
}

// 添加一个函数来获取当前主题下的网格线颜色
function getSplitLineColor() {
  return document.documentElement.getAttribute('data-theme') === 'dark'
    ? '#333333'
    : '#E8E8E8'; // 亮色模式返回 undefined，使用默认颜色
}

// 监听主题变化
watch(
  () => layoutStore.proConfig.theme, // 监听的值
  newValue => {
    if (kpiChart.value) {
      const splitLineColor = getSplitLineColor();
      // 绘制图数据
      kpiChart.value.setOption({
        tooltip: {
          trigger: 'axis',
          position: function (pt: any) {
            return [pt[0], '10%'];
          },
          confine: true, // 限制 tooltip 显示范围
          backgroundColor:
            newValue === 'dark'
              ? 'rgba(48, 48, 48, 0.8)'
              : 'rgba(255, 255, 255, 0.9)',
          borderColor: newValue === 'dark' ? '#555' : '#ddd',
          textStyle: {
            color: newValue === 'dark' ? '#CACADA' : '#333',
          },
        },
        xAxis: {
          axisLabel: {
            color: newValue === 'dark' ? '#CACADA' : '#333',
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: splitLineColor,
            },
          },
        },
        yAxis: {
          axisLabel: {
            color: newValue === 'dark' ? '#CACADA' : '#333',
          },
          splitLine: {
            show: true,
            lineStyle: {
              color: splitLineColor,
            },
          },
        },
      });
    }
  }
);

/**点击搜索按钮 */
function handleSearch() {
  // 检查是否选择了网元类型和网元ID
  if (!state.neType) {
    message.warning({
      content: 'Please select the network element type first',
      duration: 2,
    });
    return;
  }

  if (state.neIds.length === 0) {
    message.warning({
      content: 'Please select at least one network element',
      duration: 2,
    });
    return;
  }

  // 更新查询参数
  queryParams.neType = state.neType;
  queryParams.neIds = [...state.neIds];
  queryParams.startTime = queryRangePicker.value[0];
  queryParams.endTime = queryRangePicker.value[1];

  // 获取指标名，成功后会自动获取指标值
  fnGetListTitle();
}

onMounted(() => {
  // 目前支持的 AMF AUSF MME MOCNGW NSSF SMF UDM UPF PCF
  // 获取网元网元列表
  neInfoStore.fnNelist().then(res => {
    if (res.code === RESULT_CODE_SUCCESS && Array.isArray(res.data)) {
      if (res.data.length > 0) {
        // 过滤不可用的网元
        neCascaderOptions.value = neInfoStore.getNeCascaderOptions.filter(
          (item: any) => {
            return !['OMC', 'NSSF', 'NEF', 'NRF', 'LMF', 'N3IWF'].includes(
              item.value
            );
          }
        );
        if (neCascaderOptions.value.length === 0) {
          message.warning({
            content: t('common.noData'),
            duration: 2,
          });
          return;
        }

        // 无查询参数neType时 默认选择UPF
        const queryNeType = (route.query.neType as string) || 'UPF';
        const item = neCascaderOptions.value.find(s => s.value === queryNeType);
        if (item && item.children) {
          // 设置网元类型
          state.neType = item.value;
          queryParams.neType = item.value;

          // 获取该类型下的网元ID列表
          availableNeIds.value = item.children.map((ne: any) => ({
            label: `${ne.label}`,
            value: ne.neId,
          }));

          // 默认选择第一个网元
          const info = item.children[0];
          state.neIds = [info.neId];
          queryParams.neIds = [info.neId];
          selectedNes.value = [
            {
              neType: item.value,
              neId: info.neId,
            },
          ];
        } else {
          const item = neCascaderOptions.value[0];
          state.neType = item.value;
          queryParams.neType = item.value;

          // 获取该类型下的网元ID列表
          availableNeIds.value = item.children.map((ne: any) => ({
            label: `${ne.label}`,
            value: ne.neId,
          }));

          // 默认选择第一个网元
          const info = item.children[0];
          state.neIds = [info.neId];
          queryParams.neIds = [info.neId];
          selectedNes.value = [
            {
              neType: item.value,
              neId: info.neId,
            },
          ];
        }

        // 查询当前小时
        const now = new Date();
        now.setMinutes(0, 0, 0);
        // 设置起始时间为整点前一小时
        const startTime = new Date(now);
        startTime.setHours(now.getHours() - 1);
        queryRangePicker.value[0] = `${startTime.getTime()}`;
        // 设置结束时间为整点
        const endTime = new Date(now);
        endTime.setMinutes(59, 59, 59);
        queryRangePicker.value[1] = `${endTime.getTime()}`;

        // 绘制空图表
        fnRanderChart();

        // 自动执行一次搜索，获取默认网元的数据
        handleSearch();
      }
    } else {
      message.warning({
        content: t('common.noData'),
        duration: 2,
      });
    }
  });
});

onBeforeUnmount(() => {
  ws.close();
});
</script>

<template>
  <PageContainer>
    <a-card
      v-show="tableState.seached"
      :bordered="false"
      :body-style="{ marginBottom: '24px', paddingBottom: 0 }"
    >
      <!-- 表格搜索栏 -->
      <a-form :model="queryParams" name="queryParamsFrom" layout="horizontal">
        <a-row :gutter="16">
          <a-col :lg="4" :md="8" :xs="24">
            <a-form-item name="neType" :label="t('views.ne.common.neType')">
              <a-select
                v-model:value="state.neType"
                :options="neCascaderOptions"
                :placeholder="t('common.selectPlease')"
                @change="handleNeTypeChange"
                :field-names="{
                  label: 'label',
                  value: 'value',
                }"
                :allow-clear="false"
              />
            </a-form-item>
          </a-col>
          <a-col :lg="6" :md="12" :xs="24">
            <a-form-item name="neIds" :label="t('views.ne.common.neName')">
              <a-select
                v-model:value="state.neIds"
                :options="availableNeIds"
                :placeholder="t('common.selectPlease')"
                @change="handleNeIdsChange"
                mode="multiple"
                :max-tag-count="2"
                :allow-clear="false"
              />
            </a-form-item>
          </a-col>
          <a-col :lg="8" :md="12" :xs="24">
            <a-form-item
              :label="t('views.perfManage.goldTarget.timeFrame')"
              name="timeFrame"
            >
              <a-range-picker
                v-model:value="queryRangePicker"
                bordered
                :presets="ranges"
                :allow-clear="false"
                :show-time="{ format: 'HH:mm:ss' }"
                format="YYYY-MM-DD HH:mm:ss"
                value-format="x"
                style="width: 100%"
              ></a-range-picker>
            </a-form-item>
          </a-col>
          <a-col :lg="4" :md="12" :xs="24">
            <a-form-item
              :label="t('views.perfManage.goldTarget.interval')"
              name="interval"
            >
              <a-select
                v-model:value="queryParams.interval"
                :placeholder="t('common.selectPlease')"
                :options="[
                  { label: '5S', value: 5 },
                  { label: '1M', value: 60 },
                  { label: '5M', value: 300 },
                  { label: '15M', value: 900 },
                  { label: '30M', value: 1800 },
                  { label: '60M', value: 3600 },
                ]"
              />
            </a-form-item>
          </a-col>
          <a-col :lg="2" :md="12" :xs="24">
            <a-form-item>
              <a-space :size="8">
                <a-button
                  type="primary"
                  :loading="tableState.loading"
                  @click.prevent="handleSearch"
                >
                  <template #icon>
                    <SearchOutlined />
                  </template>
                  {{ t('common.search') }}
                </a-button>
              </a-space>
            </a-form-item>
          </a-col>
        </a-row>
      </a-form>
    </a-card>

    <a-card :bordered="false" :body-style="{ padding: '0px' }">
      <!-- 插槽-卡片左侧侧 -->
      <template #title>
        <a-space :size="8" align="center">
          <a-button
            type="primary"
            :loading="tableState.loading"
            @click.prevent="fnChangShowType()"
          >
            <template #icon>
              <AreaChartOutlined />
            </template>
            {{
              tableState.showTable
                ? t('views.perfManage.goldTarget.kpiChartTitle')
                : t('views.perfManage.goldTarget.kpiTableTitle')
            }}
          </a-button>
          <a-button
            type="dashed"
            :loading="tableState.loading"
            @click.prevent="fnRecordExport()"
            v-show="tableState.showTable"
          >
            <template #icon>
              <ExportOutlined />
            </template>
            {{ t('common.export') }}
          </a-button>
        </a-space>
      </template>

      <!-- 插槽-卡片右侧 -->
      <template #extra>
        <a-space :size="8" align="center" v-show="tableState.showTable">
          <a-tooltip>
            <template #title>{{ t('common.reloadText') }}</template>
            <a-button type="text" @click.prevent="fnGetList()">
              <template #icon>
                <ReloadOutlined />
              </template>
            </a-button>
          </a-tooltip>
          <TableColumnsDnd
            v-if="tableColumns.length > 0"
            :columns="tableColumns"
            v-model:columns-dnd="tableColumnsDnd"
          ></TableColumnsDnd>
          <a-tooltip>
            <template #title>{{ t('common.sizeText') }}</template>
            <a-dropdown trigger="click" placement="bottomRight">
              <a-button type="text">
                <template #icon>
                  <ColumnHeightOutlined />
                </template>
              </a-button>
              <template #overlay>
                <a-menu
                  :selected-keys="[tableState.size as string]"
                  @click="fnTableSize"
                >
                  <a-menu-item key="default">
                    {{ t('common.size.default') }}
                  </a-menu-item>
                  <a-menu-item key="middle">
                    {{ t('common.size.middle') }}
                  </a-menu-item>
                  <a-menu-item key="small">
                    {{ t('common.size.small') }}
                  </a-menu-item>
                </a-menu>
              </template>
            </a-dropdown>
          </a-tooltip>
        </a-space>
        <a-form layout="inline" v-show="!tableState.showTable">
          <!-- <a-form-item
            :label="t('views.perfManage.goldTarget.showChartSelected')"
            name="chartLegendSelectedFlag"
          >
            <a-switch
              :disabled="tableState.loading"
              v-model:checked="state.chartLegendSelectedFlag"
              :checked-children="t('common.switch.open')"
              :un-checked-children="t('common.switch.shut')"
              @change="fnLegendSelected"
              size="small"
            />
          </a-form-item> -->
          <a-form-item
            :label="t('views.perfManage.goldTarget.realTimeData')"
            name="chartRealTime"
          >
            <a-switch
              :disabled="tableState.loading"
              v-model:checked="state.chartRealTime"
              :checked-children="t('common.switch.open')"
              :un-checked-children="t('common.switch.shut')"
              @change="fnRealTimeSwitch"
              size="small"
            />
          </a-form-item>
        </a-form>
      </template>

      <!-- 表格列表 -->
      <a-table
        v-show="tableState.showTable"
        class="table"
        row-key="id"
        :columns="tableColumnsDnd"
        :loading="tableState.loading"
        :data-source="tableState.data"
        :size="tableState.size"
        :pagination="tablePagination"
        :scroll="{ x: tableColumnsDnd.length * 200, y: 'calc(100vh - 480px)' }"
        @resizeColumn="(w: number, col: any) => (col.width = w)"
        :show-expand-column="false"
        @change="fnTableChange"
      >
        <template #bodyCell="{ column, record }">
          <template v-if="column.key === 'timeGroup'">
            {{ parseDateToStr(+record.timeGroup) }}
          </template>
        </template>
      </a-table>

      <!-- 图表 -->
      <div style="padding: 24px" v-show="!tableState.showTable">
        <div
          ref="kpiChartDom"
          class="chart-container"
          style="height: 450px; width: 100%"
        ></div>

        <div class="table-container">
          <a-table
            :columns="statsColumns"
            :data-source="kpiStats"
            :pagination="false"
            :scroll="{ y: 250 }"
            size="small"
            :custom-row="
              (record:any) => ({
                onClick: () => handleRowClick(record),
                class: selectedRows.includes(record.kpiId) ? 'selected-row' : '',
              })
            "
          >
            <template #headerCell="{ column }">
              <template v-if="column.key === 'total'">
                <span>
                  {{ t('views.perfManage.kpiOverView.totalValue') }}
                  <a-tooltip placement="bottom">
                    <template #title>
                      <span>
                        {{ t('views.perfManage.kpiOverView.totalValueTip') }}
                      </span>
                    </template>
                    <InfoCircleOutlined />
                  </a-tooltip>
                </span>
              </template>
              <template v-if="column.key === 'avg'">
                <span>
                  {{ t('views.perfManage.kpiOverView.avgValue') }}
                  <a-tooltip placement="bottom">
                    <template #title>
                      <span>
                        {{ t('views.perfManage.kpiOverView.avgValueTip') }}
                      </span>
                    </template>
                    <InfoCircleOutlined />
                  </a-tooltip>
                </span>
              </template>
              <template v-if="column.key === 'max'">
                <span>
                  {{ t('views.perfManage.kpiOverView.maxValue') }}
                  <a-tooltip placement="bottom">
                    <template #title>
                      <span>
                        {{ t('views.perfManage.kpiOverView.maxValueTip') }}
                      </span>
                    </template>
                    <InfoCircleOutlined />
                  </a-tooltip>
                </span>
              </template>
              <template v-if="column.key === 'min'">
                <span>
                  {{ t('views.perfManage.kpiOverView.minValue') }}
                  <a-tooltip placement="bottom">
                    <template #title>
                      <span>
                        {{ t('views.perfManage.kpiOverView.minValueTip') }}
                      </span>
                    </template>
                    <InfoCircleOutlined />
                  </a-tooltip>
                </span>
              </template>
            </template>
          </a-table>
        </div>
      </div>
    </a-card>
  </PageContainer>
</template>

<style scoped>
.chart-container {
  height: 800px;
  width: 100%;
}

.table-container {
  height: 282px;
  width: 100%;
  margin-top: 20px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}

/* 表格布局相关样式 */
:deep(.ant-table-wrapper),
:deep(.ant-table),
:deep(.ant-table-container),
:deep(.ant-table-content) {
  flex: 1;
  display: flex;
  flex-direction: column;
}

:deep(.ant-table-body) {
  flex: 1;
  overflow-y: auto !important;
  min-height: 0;
}

/* 表格行和表头样式 */
:deep(.ant-table-thead tr th),
:deep(.ant-table-tbody tr td) {
  padding: 8px;
  height: 40px;
}

/* 美化滚动条样式 */
:deep(.ant-table-body::-webkit-scrollbar) {
  width: 6px;
  height: 6px;
}

:deep(.ant-table-body::-webkit-scrollbar-thumb) {
  background: #ccc;
  border-radius: 3px;
}

:deep(.ant-table-body::-webkit-scrollbar-track) {
  background: #f1f1f1;
  border-radius: 3px;
}

[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-thumb) {
  background: #4c4c4c;
}

[data-theme='dark'] :deep(.ant-table-body::-webkit-scrollbar-track) {
  background: #2a2a2a;
}

/* 选中行样式 */
:deep(.selected-row) {
  background-color: rgba(24, 144, 255, 0.1);
}

[data-theme='dark'] :deep(.selected-row) {
  background-color: rgba(24, 144, 255, 0.2);
}

/* 鼠标悬停样式 */
:deep(.ant-table-tbody tr:hover) {
  cursor: pointer;
}
</style>
