<template>
  <div class="page redis-monitor">
    <!-- Redis状态概览 -->
    <el-row :gutter="15" class="dashboard-row">
      <el-col :span="6" class="marg-b-15">
        <el-card shadow="hover" class="status-card uptime-card">
          <div class="status-value">{{ sysInfo.server ? timeFormat(sysInfo.server.uptime_in_seconds) : '加载中...' }}</div>
          <div class="status-label">服务运行时间</div>
          <div class="uptime-info" v-if="sysInfo.server">
            <span>版本: {{ sysInfo.server.redis_version }}</span>
          </div>
          <div class="status-icon"><i class="el-icon-time"></i></div>
        </el-card>
      </el-col>
      <el-col :span="6" class="marg-b-15">
        <el-card shadow="hover" class="status-card clients-card">
          <div class="status-value">{{ sysInfo.clients ? sysInfo.clients.connected_clients : '加载中...' }}</div>
          <div class="status-label">客户端连接数</div>
          <div class="clients-info" v-if="sysInfo.clients">
            <span>阻塞: {{ sysInfo.clients.blocked_clients }}</span>
          </div>
          <div class="status-icon"><i class="el-icon-user"></i></div>
        </el-card>
      </el-col>
      <el-col :span="6" class="marg-b-15">
        <el-card shadow="hover" class="status-card keys-card">
          <div class="status-value">{{ sysInfo.stats ? sysInfo.stats.total_commands_processed : '加载中...' }}</div>
          <div class="status-label">已处理命令</div>
          <div class="status-trend">
            <div class="trend-value">+{{ commandsProcessedTrend }}</div>
            <div class="trend-chart">
              <div ref="commandsTrendRef" class="mini-chart"></div>
            </div>
          </div>
          <div class="status-icon"><i class="el-icon-s-operation"></i></div>
        </el-card>
      </el-col>
      <el-col :span="6" class="marg-b-15">
        <el-card shadow="hover" class="status-card memory-card">
          <div class="status-value">{{ sysInfo.memory ? memorySizeFormat(sysInfo.memory.used_memory) : '加载中...' }}</div>
          <div class="status-label">内存使用</div>
          <el-progress
              v-if="sysInfo.memory"
              :percentage="sysInfo.memory.maxmemory && sysInfo.memory.maxmemory > 0 ? parseFloat(((sysInfo.memory.used_memory / sysInfo.memory.maxmemory) * 100).toFixed(1)) : 0"
              :color="memoryColorGetter"
              :stroke-width="8"
              class="memory-progress"
          />
          <div class="status-icon"><i class="el-icon-cpu"></i></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 内存使用图表 & 命令处理图表 -->
    <el-row :gutter="15">
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="hover" class="chart-card">
          <template #header>
            <div class="card-header">
              <span>内存使用监控</span>
              <div class="card-header-right">
                <el-tag size="small" type="info">实时更新</el-tag>
              </div>
            </div>
          </template>
          <div ref="memoryChartRef" class="chart-container"></div>
        </el-card>
      </el-col>
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="hover" class="chart-card">
          <template #header>
            <div class="card-header">
              <span>命令处理监控</span>
              <div class="card-header-right">
                <el-tag size="small" type="info">实时更新</el-tag>
              </div>
            </div>
          </template>
          <div ref="commandsChartRef" class="chart-container"></div>
        </el-card>
      </el-col>
    </el-row>

    <!-- 系统信息卡片 -->
    <el-row :gutter="15">
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="hover" class="data-card">
          <template #header>
            <div class="card-header">
              <span>客户端信息</span>
            </div>
          </template>
          <table cellspacing="0" style="width: 100%">
            <tbody v-if="sysInfo.clients">
              <tr>
                <td>
                  <div class="cell-card">当前客户端连接数: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.clients.connected_clients }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">输出缓冲区中队列对象个数的最大值: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.clients.client_recent_max_output_buffer }}</div>
                </td>
              </tr>

              <tr>
                <td>
                  <div class="cell-card">输入缓冲区中占用的最大容量:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.clients.client_recent_max_input_buffer) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">等待阻塞命令的客户端数量:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.clients.blocked_clients }}</div>
                </td>
              </tr>
            </tbody>
          </table>
        </el-card>
      </el-col>
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="never" class="box-card-height" style="height:auto">
          <template #header>
            <div class="card-header">
              <span>CPU 信息</span>
            </div>
          </template>
          <table cellspacing="0" style="width: 100%">
            <tbody v-if="sysInfo.cpu">
              <tr>
                <td>
                  <div class="cell-card" title="Redis主进程在内核态所占用的CPU时钟总和">主进程内核态占用CPU时钟: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ lengthToFixed2(sysInfo.cpu.used_cpu_sys) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card" title="Redis主进程在用户态所占用的CPU时钟总和">主进程用户态占用CPU时钟: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ lengthToFixed2(sysInfo.cpu.used_cpu_user) }}</div>
                </td>
              </tr>

              <tr>
                <td>
                  <div class="cell-card" title="Redis子进程在内核态所占用的CPU时钟总和">子进程内核态占用CPU时钟:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ lengthToFixed2(sysInfo.cpu.used_cpu_sys_children) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card" title="Redis子进程在用户态所占用的CPU时钟总和">子进程用户态占用CPU时钟:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ lengthToFixed2(sysInfo.cpu.used_cpu_user_children) }}</div>
                </td>
              </tr>
            </tbody>
          </table>
        </el-card>
      </el-col>
    </el-row>
    <el-row :gutter="15">
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="never" class="box-card-height" style="height:auto">
          <template #header>
            <div class="card-header">
              <span>服务信息</span>
            </div>
          </template>
          <table cellspacing="0" style="width: 100%">
            <tbody v-if="sysInfo.clients">
              <tr>
                <td>
                  <div class="cell-card">Redis服务版本: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.redis_version }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">运行模式: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.redis_mode }}</div>
                </td>
              </tr>

              <tr>
                <td>
                  <div class="cell-card">Redis所在机器的操作系统:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.os }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">架构:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.arch_bits }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">Redis所使用的事件处理机制:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.multiplexing_api }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">自Redis服务启动以来，运行的秒数:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.uptime_in_seconds }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">自Redis服务启动以来，运行的天数:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.uptime_in_days }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">serverCron每秒运行次数:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.server.hz }}</div>
                </td>
              </tr>
            </tbody>
          </table>
        </el-card>
      </el-col>
      <el-col :span="12" class="marg-b-15">
        <el-card shadow="never" class="box-card-height" style="height:auto">
          <template #header>
            <div class="card-header">
              <span>内存信息</span>
            </div>
          </template>
          <table v-if='sysInfo.memory' cellspacing="0" style="width: 100%">
            <tbody>
              <tr>
                <td>
                  <div class="cell-card">Redis分配器分配的内存总量: </div>
                </td>
                <td>
                  <div class="cell-card">
                    {{ memorySizeFormat(sysInfo.memory.used_memory) }} -
                    {{ sysInfo.memory.maxmemory && sysInfo.memory.maxmemory > 0 ? lengthToFixed2(sysInfo.memory.used_memory / sysInfo.memory.maxmemory * 100) : '0' }}%
                  </div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">以可读的格式返回used_memory: </div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.memory.used_memory_human) }}</div>
                </td>
              </tr>

              <tr>
                <td>
                  <div class="cell-card">从操作系统的角度，Redis进程占用的物理内存总量:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.memory.used_memory_rss) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">内存使用的最大值:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.memory.used_memory_peak) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">以可读的格式返回used_memory_peak:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.memory.used_memory_peak_human) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">Lua引擎所消耗的内存大小:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ memorySizeFormat(sysInfo.memory.used_memory_lua) }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">内存碎片率:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.memory.mem_fragmentation_ratio }}</div>
                </td>
              </tr>
              <tr>
                <td>
                  <div class="cell-card">Redis所使用的内存分配器:</div>
                </td>
                <td>
                  <div class="cell-card value">{{ sysInfo.memory.mem_allocator }}</div>
                </td>
              </tr>

            </tbody>
          </table>
        </el-card>
      </el-col>
    </el-row>
    <div class="flex-row gap-3">
      <el-col :xs="24" :sm="24" :md="24" class="marg-b-15">
        <el-card shadow="never" class="box-card-height" style="height:auto">
          <template #header>
            <div class="card-header">
              <span>基础统计信息</span>
            </div>
          </template>
          <div class="flex-row">
            <el-form v-if="sysInfo.stats" label-position="right" label-width="160px" class="flex1" style="max-width: 460px">
              <el-form-item label="连接过的客户端总数">{{ sysInfo.stats.total_connections_received }}</el-form-item>
              <el-form-item label="执行过的命令总数">{{ sysInfo.stats.total_commands_processed }}</el-form-item>
              <el-form-item label="每秒处理命令条数">{{ sysInfo.stats.instantaneous_ops_per_sec }}</el-form-item>
              <el-form-item label="拒绝的连接个数">{{ sysInfo.stats.rejected_connections }}</el-form-item>
              <el-form-item label="key数量">{{ sysInfo.stats.evicted_keys }}</el-form-item>
            </el-form>

            <el-form v-if="sysInfo.stats" label-position="right" label-width="160px" class="flex1" style="max-width: 460px">
              <el-form-item label="网络总入流量">{{ memorySizeFormat(sysInfo.stats.total_net_input_bytes) }}</el-form-item>
              <el-form-item label="网络总出流量">{{ memorySizeFormat(sysInfo.stats.total_net_output_bytes) }}</el-form-item>
              <el-form-item label="每秒输入量">{{ sysInfo.stats.instantaneous_input_kbps }} kb/s</el-form-item>
              <el-form-item label="每秒输出量">{{ sysInfo.stats.instantaneous_output_kbps }} kb/s</el-form-item>
              <el-form-item label="最近fork消耗时间">{{ sysInfo.stats.evicted_keys }} μs</el-form-item>
            </el-form>

            <el-form v-if="sysInfo.stats" label-position="right" label-width="160px" class="flex1" style="max-width: 460px">
              <el-form-item label="主从完全同步成功次数">{{ sysInfo.stats.sync_full }}</el-form-item>
              <el-form-item label="主从部分同步成功次数">{{ sysInfo.stats.sync_partial_ok }}</el-form-item>
              <el-form-item label="主从部分同步失败次数">{{ sysInfo.stats.sync_partial_err }}</el-form-item>
              <el-form-item label="正migrate的Redis个数">{{ sysInfo.stats.migrate_cached_sockets }} μs</el-form-item>
              <el-form-item label="过期的key数量">{{ sysInfo.stats.expired_keys }}</el-form-item>
            </el-form>

            <el-form v-if="sysInfo.stats" label-position="right" label-width="160px" class="flex1" style="max-width: 460px">
              <el-form-item label="当前使用中的频道数量">{{ sysInfo.stats.pubsub_channels }}</el-form-item>
              <el-form-item label="当前使用中的模式数量">{{ sysInfo.stats.pubsub_patterns }}</el-form-item>
              <el-form-item label="不命中次数">{{ sysInfo.stats.keyspace_misses }}</el-form-item>
              <el-form-item label="命中次数">{{ sysInfo.stats.keyspace_hits }}</el-form-item>
            </el-form>
          </div>
        </el-card>
      </el-col>
    </div>
    <div class="flex-row gap-3">
      <el-col :xs="24" :sm="24" :md="24">
        <el-card shadow="never" class="box-card-height" style="height:auto">
          <template #header>
            <div class="card-header">
              <span>info Keyspace统计信息</span>
            </div>
          </template>
          <div style="" class="flex-column" v-if="sysInfo.keyspaceList && sysInfo.keyspace">
            <el-form style="display: flex;width: 100%;" v-for="(item, index) in sysInfo.keyspaceList" :key="index" label-position="right" label-width="160px">
              <el-form-item class="flex1" label="key名称">{{ item }}</el-form-item>
              <el-form-item class="flex1" label="当前数据库key总数">{{ sysInfo.keyspace[item].keys }}</el-form-item>
              <el-form-item class="flex1" label="带有过期时间的key总数">{{ sysInfo.keyspace[item].expires }}</el-form-item>
              <el-form-item class="flex1" label="平均存活时间">{{ timeFormat(sysInfo.keyspace[item].avg_ttl / 1000) }}</el-form-item>
            </el-form>
          </div>
        </el-card>
      </el-col>
    </div>
  </div>
</template>

<script lang="ts">
import { toRefs, reactive, defineComponent, ref, onMounted, onBeforeUnmount, computed } from 'vue';
import 'echarts-wordcloud';
import { getSSEOrigin } from '/@/utils/origin'
import * as echarts from 'echarts';

let interval: any = null;
let es: any = null;
export default defineComponent({
  name: 'monitor',
  components: {},
  setup() {
    const state: any = reactive({
      myCharts: [],
      sysInfo: {},
      memoryChartData: {
        times: [] as string[],
        values: [] as number[]
      },
      commandsChartData: {
        times: [] as string[],
        values: [] as number[],
        lastValue: 0,
        trend: [] as number[]
      },
      topCommands: [] as { name: string, value: number }[]
    });

    const memoryChartRef = ref<HTMLElement | null>(null);
    const commandsChartRef = ref<HTMLElement | null>(null);
    const commandsTrendRef = ref<HTMLElement | null>(null);
    const commandsPieChartRef = ref<HTMLElement | null>(null);

    let memoryChart: echarts.ECharts | null = null;
    let commandsChart: echarts.ECharts | null = null;
    let commandsTrendChart: echarts.ECharts | null = null;
    let commandsPieChart: echarts.ECharts | null = null;

    // 引入memorySizeFormat和timeFormat方法到setup作用域
    function memorySizeFormat(size: any) {
      size = parseFloat(size);
      let rank = 0;
      let rankchar = 'Bytes';
      while (size > 1024 && rankchar != 'TB') {
        size = size / 1024;
        rank++;
        if (rank == 1) {
          rankchar = 'KB';
        } else if (rank == 2) {
          rankchar = 'MB';
        } else if (rank == 3) {
          rankchar = 'GB';
        } else if (rank == 4) {
          rankchar = 'TB';
        }
      }
      return size.toFixed(2) + ' ' + rankchar;
    }

    function lengthToFixed2(size: any) {
      size = parseFloat(size);
      return size.toFixed(2);
    }

    function timeFormat(second: any) {
      if (!second) return '-'
      second = parseFloat(second);
      let rank = 0;
      let rankchar = '秒';
      while ((second > 60 && rankchar != '小时' && rankchar != '天') || (second > 24 && rankchar == '小时')) {
        if (rankchar == '小时') {
          second = second / 24;
        } else {
          second = second / 60;
        }
        rank++;
        if (rank == 1) {
          rankchar = '分';
        } else if (rank == 2) {
          rankchar = '小时';
        } else if (rank == 3) {
          rankchar = '天';
        }
      }
      return second.toFixed(2) + ' ' + rankchar;
    }

    const commandsProcessedTrend = computed(() => {
      const trend = state.commandsChartData.trend;
      if (trend.length === 0) return 0;
      return trend[trend.length - 1];
    });

    const memoryColorGetter = computed(() => {
      if (!state.sysInfo.memory) return '#409EFF';
      if (!state.sysInfo.memory.maxmemory || state.sysInfo.memory.maxmemory === 0) return '#409EFF';

      const percentage = (state.sysInfo.memory.used_memory / state.sysInfo.memory.maxmemory) * 100;
      if (percentage < 50) return '#67C23A';
      if (percentage < 80) return '#E6A23C';
      return '#F56C6C';
    });

    onMounted(() => {
      initCharts();

      // 每5秒更新一次图表数据
      interval = setInterval(() => {
        updateMemoryChart();
        updateCommandsChart();
        updateCommandsPieChart();
      }, 5000);
    });

    onBeforeUnmount(() => {
      if (interval) {
        clearInterval(interval);
        interval = null;
      }

      if (es) {
        es.close();
      }

      destroyCharts();
    });

    function destroyCharts() {
      if (memoryChart) {
        memoryChart.dispose();
        memoryChart = null;
      }

      if (commandsChart) {
        commandsChart.dispose();
        commandsChart = null;
      }

      if (commandsTrendChart) {
        commandsTrendChart.dispose();
        commandsTrendChart = null;
      }

      if (commandsPieChart) {
        commandsPieChart.dispose();
        commandsPieChart = null;
      }
    }

    function initCharts() {
      if (memoryChartRef.value) {
        // 判断当前是否为深色模式
        const isDarkMode = document.documentElement.classList.contains('dark');

        // 根据深色模式初始化图表
        memoryChart = echarts.init(memoryChartRef.value, isDarkMode ? 'dark' : '');

        const option = {
          backgroundColor: 'transparent',
          grid: {
            top: 20,
            right: 20,
            bottom: 40,
            left: 80
          },
          tooltip: {
            trigger: 'axis',
            formatter: function(params: any) {
              const time = params[0].axisValue;
              const value = memorySizeFormat(params[0].data);
              return `${time}<br />内存使用: ${value}`;
            }
          },
          xAxis: {
            type: 'category',
            data: [],
            axisLabel: {
              rotate: 45
            }
          },
          yAxis: {
            type: 'value',
            axisLabel: {
              formatter: function(value: number) {
                return memorySizeFormat(value);
              }
            }
          },
          series: [
            {
              data: [],
              type: 'line',
              smooth: true,
              areaStyle: {
                opacity: 0.3,
                color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                  { offset: 0, color: isDarkMode ? 'rgba(64, 158, 255, 0.7)' : 'rgba(64, 158, 255, 0.7)' },
                  { offset: 1, color: isDarkMode ? 'rgba(64, 158, 255, 0.1)' : 'rgba(64, 158, 255, 0.1)' }
                ])
              },
              lineStyle: {
                width: 3
              },
              itemStyle: {
                color: isDarkMode ? '#5ea8ff' : '#409EFF'
              }
            }
          ]
        };
        memoryChart.setOption(option);
      }

      // 判断当前是否为深色模式
      const isDarkMode = document.documentElement.classList.contains('dark');

      if (commandsChartRef.value) {
        commandsChart = echarts.init(commandsChartRef.value, isDarkMode ? 'dark' : '');
        const option = {
          backgroundColor: 'transparent',
          grid: {
            top: 20,
            right: 20,
            bottom: 40,
            left: 50
          },
          tooltip: {
            trigger: 'axis'
          },
          xAxis: {
            type: 'category',
            data: [],
            axisLabel: {
              rotate: 45
            }
          },
          yAxis: {
            type: 'value'
          },
          series: [
            {
              data: [],
              type: 'bar',
              itemStyle: {
                color: isDarkMode ? '#8ece67' : '#67C23A'
              }
            }
          ]
        };
        commandsChart.setOption(option);
      }

      if (commandsTrendRef.value) {
        commandsTrendChart = echarts.init(commandsTrendRef.value, isDarkMode ? 'dark' : '');
        const option = {
          backgroundColor: 'transparent',
          grid: {
            top: 0,
            right: 0,
            bottom: 0,
            left: 0
          },
          xAxis: {
            type: 'category',
            show: false,
            data: [1, 2, 3, 4, 5]
          },
          yAxis: {
            type: 'value',
            show: false
          },
          series: [
            {
              data: [0, 0, 0, 0, 0],
              type: 'line',
              smooth: true,
              symbol: 'none',
              lineStyle: {
                width: 2,
                color: isDarkMode ? '#8ece67' : '#67C23A'
              }
            }
          ]
        };
        commandsTrendChart.setOption(option);
      }

      if (commandsPieChartRef.value) {
        commandsPieChart = echarts.init(commandsPieChartRef.value, isDarkMode ? 'dark' : '');
        updateCommandsPieChart();
      }
    }

    function getCurrentTime() {
      const now = new Date();
      const hours = now.getHours().toString().padStart(2, '0');
      const minutes = now.getMinutes().toString().padStart(2, '0');
      const seconds = now.getSeconds().toString().padStart(2, '0');
      return `${hours}:${minutes}:${seconds}`;
    }

    function updateMemoryChart() {
      if (!memoryChart || !state.sysInfo.memory) return;

      const currentTime = getCurrentTime();
      state.memoryChartData.times.push(currentTime);
      state.memoryChartData.values.push(state.sysInfo.memory.used_memory);

      // 保持最多显示20个数据点
      if (state.memoryChartData.times.length > 20) {
        state.memoryChartData.times.shift();
        state.memoryChartData.values.shift();
      }

      memoryChart.setOption({
        xAxis: {
          data: state.memoryChartData.times
        },
        series: [
          {
            data: state.memoryChartData.values
          }
        ]
      });
    }

    function updateCommandsChart() {
      if (!commandsChart || !state.sysInfo.stats) return;

      const currentTime = getCurrentTime();
      const currentValue = state.sysInfo.stats.total_commands_processed;

      // 计算增量
      let increment = 0;
      if (state.commandsChartData.lastValue > 0) {
        increment = currentValue - state.commandsChartData.lastValue;
      }

      state.commandsChartData.lastValue = currentValue;
      state.commandsChartData.times.push(currentTime);
      state.commandsChartData.values.push(increment);

      // 添加到趋势数据
      state.commandsChartData.trend.push(increment);
      if (state.commandsChartData.trend.length > 5) {
        state.commandsChartData.trend.shift();
      }

      // 保持最多显示20个数据点
      if (state.commandsChartData.times.length > 20) {
        state.commandsChartData.times.shift();
        state.commandsChartData.values.shift();
      }

      commandsChart.setOption({
        xAxis: {
          data: state.commandsChartData.times
        },
        series: [
          {
            data: state.commandsChartData.values
          }
        ]
      });

      // 更新小趋势图
      if (commandsTrendChart) {
        commandsTrendChart.setOption({
          series: [
            {
              data: state.commandsChartData.trend
            }
          ]
        });
      }
    }

    function updateCommandsPieChart() {
      if (!commandsPieChart || !state.sysInfo.stats) return;

      // 判断当前是否为深色模式
      const isDarkMode = document.documentElement.classList.contains('dark');

      // 构建命令统计数据
      if (state.sysInfo.stats.commandstats) {
        const commandsData = [];
        for (const cmd in state.sysInfo.stats.commandstats) {
          if (Object.prototype.hasOwnProperty.call(state.sysInfo.stats.commandstats, cmd)) {
            const cmdName = cmd.replace('cmdstat_', '').toUpperCase();
            const calls = state.sysInfo.stats.commandstats[cmd].calls;
            commandsData.push({
              name: cmdName,
              value: calls
            });
          }
        }

        // 按调用次数排序并取前10个
        commandsData.sort((a, b) => b.value - a.value);
        state.topCommands = commandsData.slice(0, 10);

        // 设置默认颜色等配置
        const pieColors = [
          '#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399',
          '#9B5DE5', '#2D69F0', '#44B3C2', '#F15C5C', '#FCBC51'
        ];

        // 深色模式下使用更亮的颜色
        const darkModeColors = [
          '#5ea8ff', '#8ece67', '#f0b25e', '#f78989', '#b4b8bf',
          '#bb8ef0', '#5c89f5', '#65c6d2', '#f78989', '#ffd780'
        ];

        commandsPieChart.setOption({
          backgroundColor: 'transparent',
          color: isDarkMode ? darkModeColors : pieColors,
          tooltip: {
            trigger: 'item',
            formatter: '{a} <br/>{b}: {c} ({d}%)'
          },
          legend: {
            orient: 'vertical',
            right: 10,
            top: 'center',
            data: state.topCommands.map((item: { name: string }) => item.name)
          },
          series: [
            {
              name: '命令调用次数',
              type: 'pie',
              radius: ['40%', '70%'],
              avoidLabelOverlap: false,
              itemStyle: {
                borderRadius: 10,
                borderColor: isDarkMode ? 'rgba(0, 0, 0, 0.2)' : '#fff',
                borderWidth: 2
              },
              label: {
                show: false,
                position: 'center'
              },
              emphasis: {
                label: {
                  show: true,
                  fontSize: 16,
                  fontWeight: 'bold'
                }
              },
              labelLine: {
                show: false
              },
              data: state.topCommands
            }
          ]
        });
      }
    }

    function startWs() {
      es = new EventSource(getSSEOrigin("/subscribe/redisinfo"));

      es.addEventListener("stats", statsInfoMsg);
      es.addEventListener("clients", clientsInfoMsg);
      es.addEventListener("cpu", cpuInfoMsg);
      es.addEventListener("server", serverInfoMsg);
      es.addEventListener("memory", memoryInfoMsg);
      es.addEventListener("keyspace", keyspaceInfoMsg);
    }

    startWs();

    function keyspaceInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.keyspaceList = Object.keys(data);
      state.sysInfo.keyspace = data

    }

    function memoryInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.memory = data;
      updateMemoryChart();
    }

    function serverInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.server = data
    }

    function cpuInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.cpu = data
    }


    function statsInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.stats = data;
      updateCommandsChart();
      updateCommandsPieChart();
    }

    function clientsInfoMsg(event: { data: any; }) {
      const data = JSON.parse(event.data);
      state.sysInfo.clients = data
    }

    return {
      ...toRefs(state),
      memoryChartRef,
      commandsChartRef,
      commandsTrendRef,
      commandsPieChartRef,
      commandsProcessedTrend,
      memoryColorGetter,
      memorySizeFormat,
      lengthToFixed2,
      timeFormat
    };
  },
  unmounted() {
    if (interval) {
      clearInterval(interval);
      interval = null;
    }
    if (es) {
      es.close()
    }
  },
  data() {
    return {};
  },
  methods: {
  },
});

</script>

<style scoped lang="scss">
.redis-monitor {
  .dashboard-row {
    margin-bottom: 10px;
  }

  .status-card {
    height: 120px;
    position: relative;
    overflow: visible;
    transition: all 0.3s;

    &:hover {
      transform: translateY(-5px);
      box-shadow: 0 10px 20px rgba(0, 0, 0, 0.1);
    }

    .status-value {
      font-size: 26px;
      font-weight: bold;
      line-height: 1.2;
      margin-bottom: 5px;
    }

    .status-label {
      font-size: 14px;
      color: var(--el-text-color-secondary, #909399);
      margin-bottom: 10px;
    }

    .status-icon {
      position: absolute;
      right: 15px;
      top: 15px;
      font-size: 24px;
      opacity: 0.2;
    }

    .status-trend {
      display: flex;
      align-items: center;
      margin-top: 10px;

      .trend-value {
        color: var(--el-color-success, #67C23A);
        font-weight: bold;
        margin-right: 10px;
      }

      .trend-chart {
        flex: 1;
      }
    }

    .clients-info, .uptime-info {
      font-size: 12px;
      color: var(--el-text-color-secondary, #909399);
      margin-top: 15px;
    }

    .memory-progress {
      margin-top: 5px;
    }

    &.memory-card { border-top: 3px solid var(--el-color-primary, #409EFF); }
    &.keys-card { border-top: 3px solid var(--el-color-success, #67C23A); }
    &.clients-card { border-top: 3px solid var(--el-color-warning, #E6A23C); }
    &.uptime-card { border-top: 3px solid var(--el-color-danger, #F56C6C); }
  }

  .chart-card, .data-card {
    margin-bottom: 15px;

    .card-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
    }

    .chart-container {
      height: 300px;
      width: 100%;
    }

    .commands-chart-container {
      height: 350px;
      width: 100%;
    }
  }

  .data-card {
    .db-card {
      margin-bottom: 15px;
      transition: all 0.3s;

      &:hover {
        transform: translateY(-3px);
        box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
      }

      .db-title {
        font-size: 16px;
        font-weight: bold;
        margin-bottom: 15px;
        color: var(--el-color-primary, #409EFF);
      }

      .db-info {
        .db-item {
          margin-bottom: 8px;
          display: flex;
          justify-content: space-between;

          .db-label {
            color: var(--el-text-color-regular, #606266);
          }

          .db-value {
            font-weight: bold;
          }
        }
      }
    }
  }

  .mini-chart {
    height: 30px;
    width: 100%;
  }

  .marg-b-15 {
    margin-bottom: 15px;
  }

  .cell {
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-all;
    line-height: 36px;
    padding-left: 10px;
    padding-right: 10px;
  }

  .cell-card {
    box-sizing: border-box;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: normal;
    word-break: break-all;
    line-height: 1.2;
    margin: 10px 0;
  }
  .cell-card.value {
    width: 200px;
    white-space: nowrap;
    text-align: right;
  }

  table {
    width: 100%;
    border-collapse: collapse;

    td {
      padding: 8px;
      &:first-child {
        width: 65%;
        color: var(--el-text-color-regular, #606266);
      }
      &:last-child {
        width: 35%;
        font-weight: 500;
        text-align: right;
      }
    }

    tr:nth-child(even) {
      background-color: var(--el-fill-color-light, #f9f9f9);
    }
  }
}
</style>
