<script setup lang="ts">
import * as echarts from 'echarts'

type ClassifyItem = {
  category?: string
  name?: string
  deviceCode?: string
  value?: number | string
}

const props = defineProps<{
  data: ClassifyItem[]
  loading?: boolean
}>()

const chartRef = ref<HTMLDivElement>()
let chart: echarts.ECharts | null = null
let resizeObserver: ResizeObserver | null = null

const barPalette = [
  ['#47b5ff', '#147ff3'],
  ['#5f8dff', '#6a5cff'],
  ['#34d3b3', '#12a99d'],
  ['#ffbd59', '#f58b2d'],
  ['#8c7cff', '#6854ee']
]

const displayData = computed(() => {
  const topData = props.data.filter((item) => item.deviceCode === 'top')
  return topData.length > 0 ? topData : props.data
})
const categories = computed(() =>
  displayData.value.map((item) => item.category || item.name || '未分类')
)
const values = computed(() => displayData.value.map((item) => Number(item.value ?? 0)))

const escapeHtml = (value: string) =>
  value.replace(/[&<>"']/g, (char) => {
    const entities: Record<string, string> = {
      '&': '&amp;',
      '<': '&lt;',
      '>': '&gt;',
      '"': '&quot;',
      "'": '&#39;'
    }
    return entities[char]
  })

const formatTooltip = (params: {
  color?: string
  marker?: string
  name?: string
  value?: number | string
}) => {
  const marker =
    params.marker ||
    '<span style="display:inline-block;width:8px;height:8px;margin-right:7px;border-radius:50%;background:#1688f5;"></span>'
  const name = escapeHtml(params.name || '未分类')
  const value = params.value ?? 0

  return `<div style="line-height:1.8;font-size:14px;">${marker}<span>${name}</span><br/><span style="padding-left:15px;">设备数量&nbsp;&nbsp;<strong>${value}</strong></span></div>`
}

const seriesData = computed(() =>
  values.value.map((value, index) => {
    const colors = barPalette[index % barPalette.length]
    return {
      value,
      itemStyle: {
        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
          { offset: 0, color: colors[0] },
          { offset: 1, color: colors[1] }
        ])
      }
    }
  })
)

const chartOption = computed(() => ({
  grid: {
    top: 16,
    right: 18,
    bottom: 50,
    left: 38
  },
  tooltip: {
    trigger: 'item',
    backgroundColor: '#fff',
    borderColor: '#e8edf5',
    borderWidth: 1,
    padding: [10, 13],
    textStyle: {
      color: '#172033',
      fontSize: 14
    },
    extraCssText: 'box-shadow: 0 12px 28px rgba(15, 23, 42, 0.14); border-radius: 12px;',
    formatter: formatTooltip
  },
  xAxis: {
    type: 'category',
    data: categories.value,
    axisTick: { show: false },
    axisLine: { lineStyle: { color: '#e8edf5' } },
    axisLabel: {
      color: '#738199',
      rotate: 30,
      interval: 0,
      fontSize: 11,
      margin: 10
    }
  },
  yAxis: {
    type: 'value',
    splitLine: {
      lineStyle: {
        color: '#edf1f6',
        type: 'dashed'
      }
    },
    axisLabel: {
      color: '#8b98ac',
      fontSize: 11
    }
  },
  series: [
    {
      name: '设备数量',
      type: 'bar',
      data: seriesData.value,
      barWidth: 16,
      barMinHeight: 6,
      showBackground: true,
      backgroundStyle: {
        color: 'rgba(22, 136, 245, 0.055)'
      },
      itemStyle: {},
      emphasis: {
        scale: true,
        itemStyle: {
          shadowBlur: 12,
          shadowColor: 'rgba(22, 136, 245, 0.22)'
        }
      }
    }
  ]
}))

const renderChart = () => {
  if (!chartRef.value || props.loading || displayData.value.length === 0) return
  if (!chart) {
    chart = echarts.init(chartRef.value, undefined, { renderer: 'canvas' })
  }
  chart.setOption(chartOption.value, true)
}

watch(
  () => [props.loading, props.data],
  () => nextTick(renderChart),
  { deep: true, immediate: true }
)

onMounted(() => {
  nextTick(renderChart)
  if (chartRef.value) {
    resizeObserver = new ResizeObserver(() => chart?.resize())
    resizeObserver.observe(chartRef.value)
  }
})

onBeforeUnmount(() => {
  resizeObserver?.disconnect()
  chart?.dispose()
  chart = null
})
</script>

<template>
  <section class="device-classify-card">
    <div class="card-header">
      <div>
        <h3>分类 Top</h3>
      </div>
      <span class="soft-badge">Top {{ displayData.length }}</span>
    </div>

    <div v-show="displayData.length > 0 && !loading" ref="chartRef" class="chart-el"></div>
    <div v-if="displayData.length === 0 || loading" class="empty-state">
      {{ loading ? '加载中...' : '暂无分类数据' }}
    </div>
  </section>
</template>

<style scoped lang="scss">
.device-classify-card {
  position: relative;
  min-width: 0;
  min-height: 164px;
  padding: 12px 14px 6px;
  overflow: hidden;
  background: radial-gradient(circle at 92% 18%, rgb(22 136 245 / 9%) 0, transparent 28%),
    linear-gradient(180deg, #fff 0%, #fbfdff 100%);
  border: 1px solid #e8edf5;
  border-radius: 16px;
  box-shadow: 0 10px 26px rgb(15 23 42 / 8%);
}

.device-classify-card::before,
.device-classify-card::after {
  position: absolute;
  pointer-events: none;
  border-radius: 999px;
  content: '';
}

.device-classify-card::before {
  top: -52px;
  right: 120px;
  width: 112px;
  height: 112px;
  background: rgb(53 205 178 / 8%);
}

.device-classify-card::after {
  right: -42px;
  bottom: -48px;
  width: 132px;
  height: 132px;
  background: rgb(140 124 255 / 7%);
  border: 1px solid rgb(140 124 255 / 10%);
}

.card-header {
  position: relative;
  z-index: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

h3 {
  margin: 0;
  font-size: 16px;
  font-weight: 700;
  color: #25324a;
}

.soft-badge {
  padding: 5px 11px;
  font-size: 12px;
  color: #1688f5;
  background: #edf7ff;
  border: 1px solid #d8ecff;
  border-radius: 999px;
}

.chart-el,
.empty-state {
  position: relative;
  z-index: 1;
  height: 168px;
}

.empty-state {
  display: flex;
  font-size: 13px;
  color: #9aa6b8;
  align-items: center;
  justify-content: center;
}
</style>
