<template>
  <div ref="chartElement" class="radar-chart" role="img" :aria-label="ariaLabel"></div>
</template>

<script setup>
import { computed, shallowRef } from 'vue'
import { RadarChart as EChartsRadarChart } from 'echarts/charts'
import { RadarComponent, TooltipComponent } from 'echarts/components'
import { use } from 'echarts/core'
import { CanvasRenderer } from 'echarts/renderers'

import { useEcharts } from '../../composables/useEcharts.js'
import { useThemeColors } from '../../composables/useThemeColors.js'

use([RadarComponent, EChartsRadarChart, TooltipComponent, CanvasRenderer])

const DEFAULT_DIMENSION_COLORS = [
  '#3a7ca5',
  '#0f9f8f',
  '#f59e0b',
  '#7c3aed',
  '#dc2626',
  '#2563eb',
  '#16a34a',
  '#db2777'
]

const props = defineProps({
  items: { type: Array, required: true },
  label: { type: String, default: '行为评分' },
  max: { type: Number, default: 100 }
})

const themeColors = useThemeColors()
const chartElement = shallowRef(null)

const normalizedItems = computed(() =>
  props.items.map((item, index) => ({
    code: String(item.code || item.label || '').trim(),
    label: String(item.label || item.code || '').trim(),
    score: clampScore(item.score),
    color: normalizeColor(item.color, index)
  }))
)

const ariaLabel = computed(() => {
  const summary = normalizedItems.value
    .map((item) => `${item.label}${item.score}分`)
    .join('，')
  return `${props.label}：${summary}`
})

const chartOptions = computed(() => {
  const primary = themeColors.value.chartPrimary || DEFAULT_DIMENSION_COLORS[0]
  const indicators = normalizedItems.value.map((item) => ({
    name: `${item.label}\n${item.score}`,
    min: 0,
    max: props.max,
    color: item.color
  }))

  return {
    backgroundColor: 'transparent',
    animation: true,
    animationDuration: 980,
    animationDurationUpdate: 760,
    animationEasing: 'cubicOut',
    animationEasingUpdate: 'cubicOut',
    color: [primary],
    tooltip: {
      trigger: 'item',
      confine: true,
      appendToBody: true,
      backgroundColor: 'rgba(255, 255, 255, 0.98)',
      borderColor: 'rgba(148, 163, 184, 0.24)',
      borderWidth: 1,
      padding: [9, 10],
      textStyle: {
        color: '#334155',
        fontSize: 12,
        fontWeight: 700
      },
      extraCssText: 'border-radius:4px;box-shadow:0 12px 28px rgba(15,23,42,.12);',
      formatter: formatTooltip
    },
    radar: {
      center: ['50%', '52%'],
      radius: '67%',
      shape: 'polygon',
      splitNumber: 4,
      startAngle: 90,
      axisNameGap: 18,
      indicator: indicators,
      axisName: {
        color: '#475569',
        fontSize: 12,
        fontWeight: 800,
        lineHeight: 16
      },
      axisLine: {
        lineStyle: {
          color: 'rgba(100, 116, 139, 0.18)'
        }
      },
      splitLine: {
        lineStyle: {
          color: [
            'rgba(148, 163, 184, 0.14)',
            'rgba(148, 163, 184, 0.18)',
            'rgba(148, 163, 184, 0.22)',
            'rgba(148, 163, 184, 0.28)'
          ]
        }
      },
      splitArea: {
        areaStyle: {
          color: [
            'rgba(248, 250, 252, 0.58)',
            'rgba(241, 245, 249, 0.34)'
          ]
        }
      }
    },
    series: [
      {
        name: props.label,
        type: 'radar',
        animation: true,
        animationDuration: 980,
        animationDurationUpdate: 760,
        animationEasing: 'cubicOut',
        animationEasingUpdate: 'cubicOut',
        symbol: 'circle',
        symbolSize: 7,
        data: [
          {
            value: normalizedItems.value.map((item) => item.score),
            name: props.label,
            lineStyle: {
              width: 2.5,
              color: primary,
              shadowColor: toRgba(primary, 0.22),
              shadowBlur: 7
            },
            areaStyle: {
              color: {
                type: 'radial',
                x: 0.5,
                y: 0.5,
                r: 0.7,
                colorStops: [
                  { offset: 0, color: toRgba(primary, 0.28) },
                  { offset: 1, color: toRgba(primary, 0.08) }
                ]
              }
            },
            itemStyle: {
              color: '#ffffff',
              borderColor: primary,
              borderWidth: 2.5,
              shadowColor: toRgba(primary, 0.2),
              shadowBlur: 5
            },
            emphasis: {
              lineStyle: {
                width: 3
              },
              itemStyle: {
                borderWidth: 3
              }
            }
          }
        ]
      }
    ]
  }
})

useEcharts(chartElement, chartOptions)

function formatTooltip() {
  const rows = normalizedItems.value.map((item) => (
    `<div class="profile-radar-tooltip-row">`
    + `<span style="background:${escapeHtml(item.color)}"></span>`
    + `<em>${escapeHtml(item.label)}</em>`
    + `<strong>${item.score}</strong>`
    + `</div>`
  ))
  return `<div class="profile-radar-tooltip"><b>${escapeHtml(props.label)}</b>${rows.join('')}</div>`
}

function clampScore(value) {
  const score = Number(value || 0)
  if (!Number.isFinite(score)) {
    return 0
  }
  return Math.max(0, Math.min(props.max, score))
}

function normalizeColor(value, index) {
  const color = String(value || '').trim()
  if (color) {
    return color
  }
  return DEFAULT_DIMENSION_COLORS[index % DEFAULT_DIMENSION_COLORS.length]
}

function toRgba(color, alpha) {
  const normalized = String(color || '').trim()
  const hex = normalized.replace('#', '')

  if (/^[\da-f]{3}$/i.test(hex)) {
    const [r, g, b] = hex.split('').map((part) => parseInt(part + part, 16))
    return `rgba(${r}, ${g}, ${b}, ${alpha})`
  }

  if (/^[\da-f]{6}$/i.test(hex)) {
    const r = parseInt(hex.slice(0, 2), 16)
    const g = parseInt(hex.slice(2, 4), 16)
    const b = parseInt(hex.slice(4, 6), 16)
    return `rgba(${r}, ${g}, ${b}, ${alpha})`
  }

  if (normalized.startsWith('rgb(')) {
    return normalized.replace('rgb(', 'rgba(').replace(')', `, ${alpha})`)
  }

  return `rgba(58, 124, 165, ${alpha})`
}

function escapeHtml(value) {
  return String(value || '').replace(/[&<>"']/g, (char) => ({
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
  })[char])
}
</script>

<style scoped>
.radar-chart {
  position: relative;
  width: 100%;
  min-width: 0;
  height: 100%;
}
</style>

<style>
.profile-radar-tooltip {
  display: grid;
  gap: 7px;
  min-width: 150px;
}

.profile-radar-tooltip b {
  color: #0f172a;
  font-size: 12px;
  font-weight: 850;
}

.profile-radar-tooltip-row {
  display: grid;
  grid-template-columns: 8px minmax(0, 1fr) auto;
  align-items: center;
  gap: 7px;
}

.profile-radar-tooltip-row span {
  width: 8px;
  height: 8px;
  border-radius: 999px;
}

.profile-radar-tooltip-row em {
  overflow: hidden;
  color: #475569;
  font-size: 11.5px;
  font-style: normal;
  font-weight: 700;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.profile-radar-tooltip-row strong {
  color: #0f172a;
  font-size: 12px;
  font-weight: 850;
}
</style>
