<script lang="ts" setup>
import * as echarts from 'echarts'
import { IotStatApi } from '@/api/pms/stat'
import { ANIMATION, CHART_RENDERER, createTooltip, FONT_FAMILY, THEME } from '@/utils/kb'

interface DeviceCategoryItem {
  name: string
  count: number
  type: string
  code?: string | number
}

interface DeviceCategoryResponseItem {
  className?: string
  count?: number | string
  type?: string
  code?: string | number
}

const { push } = useRouter()
const chartRef = ref<HTMLDivElement>()
const loading = ref(false)
const categoryData = ref<DeviceCategoryItem[]>([])
let chart: echarts.ECharts | null = null

const TOP_BAR_COLOR = new echarts.graphic.LinearGradient(0, 0, 1, 0, [
  { offset: 0, color: '#ffd166' },
  { offset: 0.58, color: '#ff9f43' },
  { offset: 1, color: '#f76707' }
])
const DEFAULT_BAR_COLOR = new echarts.graphic.LinearGradient(0, 0, 1, 0, [
  { offset: 0, color: THEME.color.blue.light },
  { offset: 0.58, color: THEME.color.blue.mid },
  { offset: 1, color: THEME.color.blue.line }
])

function sortCategoryData(data: DeviceCategoryItem[]) {
  const typeOrder = (type: string) => {
    if (type === 'top') return 0
    if (type === '') return 1
    return 2
  }

  return data.sort((a, b) => typeOrder(a.type) - typeOrder(b.type))
}

function getChartLayout() {
  const { clientWidth = 0, clientHeight = 0 } = chartRef.value ?? {}
  const compact = clientHeight > 0 && (clientHeight < 210 || clientWidth < 520)

  return {
    gridTop: compact ? 20 : 26,
    gridRight: compact ? 32 : 40,
    gridBottom: compact ? 22 : 28,
    gridLeft: compact ? 12 : 12,
    barWidth: compact ? 10 : 14,
    axisFontSize: compact ? 10 : 12,
    labelFontSize: compact ? 10 : 12
  }
}

function formatValue(value: number) {
  return Number(value || 0).toLocaleString('en-US')
}

function getChartOption(): echarts.EChartsOption {
  const layout = getChartLayout()
  const values = categoryData.value.map((item) => item.count)
  const maxValue = Math.max(...values, 1)
  const xAxisMax = Math.ceil((maxValue * 1.12) / 10) * 10

  return {
    ...ANIMATION,
    grid: {
      ...THEME.grid,
      top: layout.gridTop,
      right: layout.gridRight,
      bottom: layout.gridBottom,
      left: layout.gridLeft
    },
    tooltip: createTooltip({
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: THEME.split
        }
      },
      formatter(params: any[]) {
        const first = params[0]
        const row = categoryData.value[first?.dataIndex ?? 0]
        if (!row) return ''

        return [
          `<div style="min-width:132px;font-weight:700;color:#24364f;margin-bottom:6px;">${row.name}</div>`,
          `<div style="display:flex;justify-content:space-between;gap:18px;line-height:22px;"><span>设备数量</span><b style="color:#1f5bb8;">${row.count} 台</b></div>`
        ].join('')
      }
    }),
    xAxis: {
      type: 'value',
      name: '台',
      max: xAxisMax,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: THEME.text.regular,
        fontSize: layout.axisFontSize,
        fontFamily: FONT_FAMILY,
        formatter(value: number) {
          return formatValue(value)
        }
      },
      nameTextStyle: {
        color: '#4c6c9b',
        fontSize: layout.axisFontSize,
        fontWeight: 600,
        fontFamily: FONT_FAMILY
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(31, 91, 184, 0.24)',
          type: 'dashed'
        }
      }
    },
    yAxis: {
      type: 'category',
      data: categoryData.value.map((item) => item.name),
      inverse: true,
      axisLine: {
        show: false
      },
      axisTick: {
        show: false
      },
      axisLabel: {
        color: '#102a43',
        fontSize: layout.axisFontSize,
        fontWeight: 600,
        fontFamily: FONT_FAMILY,
        width: 80,
        overflow: 'truncate'
      }
    },
    series: [
      {
        name: '设备数量',
        type: 'bar',
        data: categoryData.value.map((item) => ({
          value: item.count,
          code: item.code,
          itemStyle: {
            color: item.type === 'top' ? TOP_BAR_COLOR : DEFAULT_BAR_COLOR
          }
        })),
        barWidth: layout.barWidth,
        cursor: 'pointer',
        showBackground: true,
        backgroundStyle: {
          color: 'rgba(31, 91, 184, 0.08)',
          borderRadius: 999
        },
        itemStyle: {
          borderRadius: 999
        },
        label: {
          show: true,
          position: 'right',
          distance: 8,
          color: THEME.text.strong,
          fontSize: layout.labelFontSize,
          fontWeight: 700,
          fontFamily: FONT_FAMILY,
          formatter(params: any) {
            return `${formatValue(params.value)}`
          }
        },
        emphasis: {
          itemStyle: {
            shadowBlur: 2
            // shadowColor: THEME.color.blue.shadow
          }
        }
      }
    ]
  }
}

function initChart() {
  if (!chartRef.value) return

  chart?.dispose()
  chart = echarts.init(chartRef.value, undefined, {
    renderer: CHART_RENDERER
  })
  bindChartEvents()
  renderChart()
}

function bindChartEvents() {
  chart?.off('click')
  chart?.on('click', (params) => {
    const row = categoryData.value[params.dataIndex ?? -1]
    if (!row?.code) return

    push({
      name: 'IotDevicePms',
      query: {
        code: String(row.code)
      }
    })
  })
}

function renderChart() {
  chart?.setOption(getChartOption(), true)
}

function resizeChart() {
  chart?.resize()
  renderChart()
}

function destroyChart() {
  chart?.dispose()
  chart = null
}

async function getDeviceCategory() {
  loading.value = true

  try {
    const res = await IotStatApi.getRdNewClassify()
    categoryData.value = Array.isArray(res)
      ? sortCategoryData(
          res.map((item: DeviceCategoryResponseItem) => ({
            name: item.className || '未知',
            count: Number(item.count ?? 0),
            type: item.type || '',
            code: item.code
          }))
        ).slice(0, 10)
      : []
    renderChart()
  } catch (error) {
    console.error('获取瑞都设备分类失败:', error)
    categoryData.value = []
    renderChart()
  } finally {
    loading.value = false
  }
}

onMounted(() => {
  initChart()
  getDeviceCategory()
  window.addEventListener('resize', resizeChart)
  window.addEventListener('rdkb:resize', resizeChart)
})

onUnmounted(() => {
  window.removeEventListener('resize', resizeChart)
  window.removeEventListener('rdkb:resize', resizeChart)
  destroyChart()
})
</script>

<template>
  <div class="panel flex flex-col">
    <div class="panel-title">
      <div class="icon-decorator">
        <span></span>
        <span></span>
      </div>
      设备分类
    </div>
    <div
      v-loading="loading"
      element-loading-text="加载中..."
      element-loading-background="rgb(222 236 252 / 72%)"
      class="device-category-body">
      <div ref="chartRef" class="device-category-chart"></div>
    </div>
  </div>
</template>

<style lang="scss" scoped>
@import url('@/styles/kb.scss');

.device-category-body {
  display: flex;
  width: 100%;
  min-height: 0;
  flex: 1;
}

.device-category-chart {
  width: 100%;
  min-height: 0;
  flex: 1;
}
</style>
