<template>
  <div class="pie-chart-container">
    <div v-if="!data || data.length === 0" class="empty-state">
      <n-empty description="暂无命令统计数据">
        <template #icon>
          <n-icon><IconParkOutlineChartPie /></n-icon>
        </template>
      </n-empty>
    </div>
    <div v-else class="chart-content">
      <!-- SVG饼图 -->
      <svg class="pie-chart" :width="chartSize" :height="chartSize" :viewBox="`0 0 ${chartSize} ${chartSize}`">
        <!-- 饼图扇形 -->
        <g :transform="`translate(${chartSize / 2}, ${chartSize / 2})`">
          <path
            v-for="(segment, index) in pieSegments"
            :key="index"
            :d="segment.path"
            :fill="segment.color"
            stroke="var(--card-color)"
            :stroke-width="2"
            class="pie-segment"
            @mouseenter="hoveredIndex = index"
            @mouseleave="hoveredIndex = -1"
          />
        </g>

        <!-- 中心文本 -->
        <g :transform="`translate(${chartSize / 2}, ${chartSize / 2})`">
          <text
            class="center-text-title"
            text-anchor="middle"
            :y="-8"
            fill="var(--text-color-1)"
          >
            命令统计
          </text>
          <text
            class="center-text-value"
            text-anchor="middle"
            :y="12"
            fill="var(--text-color-2)"
          >
            {{ totalCommands.toLocaleString() }}
          </text>
        </g>
      </svg>

      <!-- 图例 -->
      <div class="chart-legend">
        <div
          v-for="(item, index) in topCommands"
          :key="index"
          class="legend-item"
          :class="{ active: hoveredIndex === index }"
          @mouseenter="hoveredIndex = index"
          @mouseleave="hoveredIndex = -1"
        >
          <div class="legend-color" :style="{ backgroundColor: colors[index] }" />
          <div class="legend-content">
            <div class="legend-name">
              {{ item.name }}
            </div>
            <div class="legend-value">
              {{ Number(item.value).toLocaleString() }} ({{ item.percentage }}%)
            </div>
          </div>
        </div>

        <div v-if="otherCommands > 0" class="legend-item">
          <div class="legend-color" :style="{ backgroundColor: colors[topCommands.length] }" />
          <div class="legend-content">
            <div class="legend-name">
              其他
            </div>
            <div class="legend-value">
              {{ otherCommands.toLocaleString() }} ({{ otherPercentage }}%)
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { computed, ref } from 'vue'
import type { RedisCommandStatVo } from '@/service/api/monitor/redis'

// Props
interface Props {
  data: RedisCommandStatVo[]
}

const props = defineProps<Props>()

// 响应式数据
const hoveredIndex = ref(-1)
const chartSize = 240
const radius = 80

// 颜色配置
const colors = [
  '#18a058',
  '#2080f0',
  '#f0a020',
  '#d03050',
  '#722ed1',
  '#eb2f96',
  '#fa8c16',
  '#52c41a',
  '#13c2c2',
  '#1890ff',
]

// 计算属性
const totalCommands = computed(() => {
  return props.data.reduce((sum, item) => sum + Number(item.value), 0)
})

// 取前8个命令，其余归为"其他"
const topCommands = computed(() => {
  const sorted = [...props.data]
    .sort((a, b) => Number(b.value) - Number(a.value))
    .slice(0, 8)

  return sorted.map(item => ({
    ...item,
    percentage: totalCommands.value > 0
      ? ((Number(item.value) / totalCommands.value) * 100).toFixed(1)
      : '0.0',
  }))
})

const otherCommands = computed(() => {
  if (props.data.length <= 8)
    return 0

  const topTotal = topCommands.value.reduce((sum, item) => sum + Number(item.value), 0)
  return totalCommands.value - topTotal
})

const otherPercentage = computed(() => {
  if (otherCommands.value === 0 || totalCommands.value === 0)
    return '0.0'
  return ((otherCommands.value / totalCommands.value) * 100).toFixed(1)
})

// 饼图扇形数据
const pieSegments = computed(() => {
  const segments = []
  let currentAngle = -Math.PI / 2 // 从12点钟方向开始

  // 添加主要命令扇形
  topCommands.value.forEach((item, index) => {
    const percentage = Number(item.value) / totalCommands.value
    const angle = percentage * 2 * Math.PI

    if (angle > 0) {
      const path = createArcPath(currentAngle, currentAngle + angle, radius)
      segments.push({
        path,
        color: colors[index],
        percentage: item.percentage,
      })
      currentAngle += angle
    }
  })

  // 添加"其他"扇形
  if (otherCommands.value > 0) {
    const percentage = otherCommands.value / totalCommands.value
    const angle = percentage * 2 * Math.PI

    if (angle > 0) {
      const path = createArcPath(currentAngle, currentAngle + angle, radius)
      segments.push({
        path,
        color: colors[topCommands.value.length],
        percentage: otherPercentage.value,
      })
    }
  }

  return segments
})

// 创建弧形路径
function createArcPath(startAngle: number, endAngle: number, radius: number): string {
  const x1 = Math.cos(startAngle) * radius
  const y1 = Math.sin(startAngle) * radius
  const x2 = Math.cos(endAngle) * radius
  const y2 = Math.sin(endAngle) * radius

  const largeArcFlag = endAngle - startAngle > Math.PI ? 1 : 0

  return [
    'M',
    0,
    0,
    'L',
    x1,
    y1,
    'A',
    radius,
    radius,
    0,
    largeArcFlag,
    1,
    x2,
    y2,
    'Z',
  ].join(' ')
}
</script>

<style scoped>
.pie-chart-container {
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 20px;
}

.empty-state {
  height: 200px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.chart-content {
  display: flex;
  align-items: center;
  gap: 32px;
  width: 100%;
  max-width: 600px;
  justify-content: center;
}

.pie-chart {
  flex-shrink: 0;
}

.pie-segment {
  cursor: pointer;
  transition: all 0.3s ease;
}

.pie-segment:hover {
  filter: brightness(1.1);
  transform: scale(1.02);
}

.center-text-title {
  font-size: 14px;
  font-weight: 500;
}

.center-text-value {
  font-size: 18px;
  font-weight: 600;
}

.chart-legend {
  flex: 1;
  max-height: 280px;
  overflow-y: auto;
  padding-right: 8px;
}

.legend-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 8px 12px;
  border-radius: 6px;
  transition: all 0.2s ease;
  cursor: pointer;
}

.legend-item:hover,
.legend-item.active {
  background-color: var(--hover-color);
}

.legend-color {
  width: 12px;
  height: 12px;
  border-radius: 2px;
  flex-shrink: 0;
}

.legend-content {
  flex: 1;
  min-width: 0;
}

.legend-name {
  font-size: 14px;
  font-weight: 500;
  color: var(--text-color-1);
  margin-bottom: 2px;
  text-transform: uppercase;
}

.legend-value {
  font-size: 12px;
  color: var(--text-color-3);
}

/* 滚动条样式 */
.chart-legend::-webkit-scrollbar {
  width: 4px;
}

.chart-legend::-webkit-scrollbar-track {
  background: var(--scrollbar-track-color);
  border-radius: 2px;
}

.chart-legend::-webkit-scrollbar-thumb {
  background: var(--scrollbar-thumb-color);
  border-radius: 2px;
}

.chart-legend::-webkit-scrollbar-thumb:hover {
  background: var(--scrollbar-thumb-hover-color);
}
</style>
