<template>
  <div class="echarts-wrapper">
    <!-- 加载状态 -->
    <div v-if="loading" class="loading-mask">
      <div class="loading-spinner"></div>
    </div>
    
    <div 
      ref="chartRef" 
      :style="{ 
        width: width, 
        height: height,
        minHeight: '100px'
      }" 
      class="echarts-container"
    />
  </div>
</template>

<script>
import { ref, onMounted, onBeforeUnmount, watch } from 'vue'
import * as echarts from 'echarts'
import debounce from 'lodash/debounce'

export default {
  name: 'EChartsComponent',
  props: {
    // 图表配置项
    options: {
      type: Object,
      required: true
    },
    // 图表主题
    theme: {
      type: String,
      default: ''
    },
    // 图表宽度
    width: {
      type: String,
      default: '100%'
    },
    // 图表高度
    height: {
      type: String,
      default: '400px'
    },
    // 是否自动调整大小
    autoResize: {
      type: Boolean,
      default: true
    },
    // 加载状态
    loading: {
      type: Boolean,
      default: false
    },
    // 动画时长
    animationDuration: {
      type: Number,
      default: 1000
    },
    // 是否平滑曲线（用于折线图）
    smooth: {
      type: Boolean,
      default: false
    },
    // 图表类型
    chartType: {
      type: String,
      default: 'line',
      validator: (value) => ['line', 'bar', 'pie', 'scatter'].includes(value)
    }
  },
  emits: ['chartReady', 'click', 'legendselectchanged'],
  setup(props, { emit }) {
    const chartRef = ref(null)
    let chartInstance = null

    // 处理配置项
    const processOptions = (options) => {
      const defaultOptions = {
        tooltip: {
          trigger: 'axis',
          axisPointer: {
            type: 'cross'
          }
        },
        grid: {
          right: '3%',
          left: '3%',
          bottom: '3%',
          top: '3%',
          containLabel: true
        },
        animation: true,
        animationDuration: props.animationDuration
      }

      // 处理折线图的平滑设置
      if (props.chartType === 'line' && options.series) {
        options.series = options.series.map(series => ({
          ...series,
          smooth: props.smooth
        }))
      }

      return {
        ...defaultOptions,
        ...options
      }
    }

    // 初始化图表
    const initChart = () => {
      if (!chartRef.value) return
      
      chartInstance = echarts.init(chartRef.value, props.theme)
      
      // 绑定事件
      chartInstance.on('click', (params) => {
        emit('click', params)
      })
      
      chartInstance.on('legendselectchanged', (params) => {
        emit('legendselectchanged', params)
      })

      const processedOptions = processOptions(props.options)
      chartInstance.setOption(processedOptions)
      emit('chartReady', chartInstance)
    }

    // 更新图表
    const updateChart = () => {
      if (!chartInstance) return
      
      const processedOptions = processOptions(props.options)
      chartInstance.setOption(processedOptions)
    }

    // 调整图表大小
    const resizeChart = debounce(() => {
      if (!chartInstance) return
      chartInstance.resize()
    }, 100)

    // 监听配置变化
    watch(
      () => props.options,
      () => updateChart(),
      { deep: true }
    )

    // 监听主题变化
    watch(
      () => props.theme,
      () => {
        if (chartInstance) {
          chartInstance.dispose()
        }
        initChart()
      }
    )

    // 监听加载状态
    watch(
      () => props.loading,
      (val) => {
        if (chartInstance) {
          val ? chartInstance.showLoading() : chartInstance.hideLoading()
        }
      }
    )

    onMounted(() => {
      initChart()
      if (props.autoResize) {
        window.addEventListener('resize', resizeChart)
      }
    })

    onBeforeUnmount(() => {
      if (props.autoResize) {
        window.removeEventListener('resize', resizeChart)
      }
      if (chartInstance) {
        chartInstance.dispose()
        chartInstance = null
      }
    })

    return {
      chartRef
    }
  }
}
</script>

<style scoped>
.echarts-wrapper {
  position: relative;
  width: 100%;
}

.echarts-container {
  position: relative;
}

.loading-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.7);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 3px solid #f3f3f3;
  border-top: 3px solid #3498db;
  border-radius: 50%;
  animation: spin 1s linear infinite;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}
</style> 