<!--
 * @Author: chris
 * @Date: 2025-09-12 17:20:00
 * @LastEditors: chris
 * @LastEditTime: 2025-09-11 17:35:22
 * @Description: 气象曲线图组件，支持7天/30天/90天数据切换
-->
<script setup>
import { ref, watch, onMounted, nextTick } from 'vue'
import * as echarts from 'echarts'

// 定义组件 props
const props = defineProps({
  // 气象类型
  weatherType: {
    type: String,
    required: true,
    validator: (value) => {
      // 支持的气象类型
      const validTypes = ['temperature', 'humidity', 'rainfall', 'windSpeed', 'pressure', 'light']
      return validTypes.includes(value)
    }
  },
  // 图表数据 - 修改为只包含当前时间范围的数据
  chartData: {
    type: Object,
    required: true,
    // 数据格式: { dates: [], values: [] }
    validator: (value) => {
      return value && 
             Array.isArray(value.dates) && 
             Array.isArray(value.values) &&
             value.dates.length === value.values.length
    }
  },
  // 当前选中的时间范围，由父组件控制
  selectedTimeRange: {
    type: Number,
    default: 7,
    validator: (value) => [7, 30, 90].includes(value)
  },
  // 加载状态，由父组件控制
  loading: {
    type: Boolean,
    default: false
  }
})

// 定义组件事件
const emit = defineEmits(['timeRangeChange'])

// 本地同步父组件传入的选中时间范围
const selectedDays = ref(props.selectedTimeRange)

// 监听父组件传入的选中时间范围变化
watch(() => props.selectedTimeRange, (newValue) => {
  selectedDays.value = newValue
})
// ECharts 实例
const chartInstance = ref(null)
// 图表容器
const chartContainer = ref(null)

// 气象类型配置
const weatherTypeConfig = {
  temperature: {
    name: '温度',
    unit: '℃',
    color: '#FF6B6B',
    yAxis: {
      name: '温度 (℃)',
      min: function(value) { return value.min - 2; },
      max: function(value) { return value.max + 2; },
      show: true,
      axisLabel: {
        show: true,
        formatter: '{value}',
        color: '#333',
        fontSize: 12
      },
      axisTick: {
        show: true
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  },
  humidity: {
    name: '湿度',
    unit: '%',
    color: '#4ECDC4',
    yAxis: {
      name: '湿度 (%)',
      min: 0,
      max: 100,
      show: true,
      axisLabel: {
        show: true,
        formatter: '{value}'
      },
      axisTick: {
        show: true
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  },
  rainfall: {
    name: '降雨量',
    unit: 'mm',
    color: '#6A0572',
    yAxis: {
      name: '降雨量 (mm)',
      min: 0,
      show: true,
      axisLabel: {
        show: true,
        formatter: '{value}'
      },
      axisTick: {
        show: true
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  },
  windSpeed: {
    name: '风速',
    unit: 'm/s',
    color: '#77DD77',
    yAxis: {
      name: '风速 (m/s)',
      min: 0,
      show: true,
      axisLabel: {
        show: true,
        formatter: '{value}'
      },
      axisTick: {
        show: true
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  },
  pressure: {
    name: '气压',
    unit: 'hPa',
    color: '#845EC2',
    yAxis: {
      name: '气压 (hPa)',
      min: function(value) { return value.min - 5; },
      max: function(value) { return value.max + 5; },
      show: true,
      axisLabel: {
        show: true,
        formatter: '{value}',
        color: '#333',
        fontSize: 12
      },
      axisTick: {
        show: true
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  },
  light: {
    name: '光照',
    unit: 'lux',
    color: '#FFD166',
    yAxis: {
      name: '光照 (lux)',
      min: 0,
      show: true, // 明确显示Y轴
      axisLabel: {
        show: true, // 显示刻度标签
        formatter: '{value}'
      },
      axisTick: {
        show: true // 显示刻度线
      },
      axisLine: {
        show: true // 显示轴线
      },
      splitLine: {
        show: true, // 显示分隔线
        lineStyle: {
          type: 'dashed'
        }
      }
    }
  }
}

// 初始化图表
const initChart = () => {
  if (!chartContainer.value) return
  
  // 销毁已存在的实例
  if (chartInstance.value) {
    chartInstance.value.dispose()
  }
  
  // 创建新实例
  chartInstance.value = echarts.init(chartContainer.value)
  
  // 设置图表配置
  updateChart()
  
  // 监听窗口大小变化，自动调整图表大小
  window.addEventListener('resize', handleResize)
}

// 更新图表数据和配置
const updateChart = () => {
  if (!chartInstance.value || !props.chartData) return
  
  const config = weatherTypeConfig[props.weatherType]
  const data = props.chartData
  
  const option = {
    title: {
      text: `${config.name}趋势图 (近${props.selectedTimeRange}天)`,
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'normal'
      }
    },
    tooltip: {
      trigger: 'item',
      show: true,
      alwaysShowContent: false,
      backgroundColor: 'rgba(0, 0, 0, 0.8)',
      borderColor: '#555',
      borderWidth: 1,
      padding: 10,
      textStyle: {
        color: '#fff',
        fontSize: 12
      },
      formatter: function(params) {
        return `日期: ${params.name}<br/>${params.seriesName}: ${params.value} ${config.unit}`
      },
      axisPointer: {
        type: 'cross',
        label: {
          backgroundColor: '#6a7985'
        },
        crossStyle: {
          color: '#999'
        }
      }
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '3%',
      containLabel: true
    },
    xAxis: {
      type: 'category',
      boundaryGap: false,
      data: data.dates,
      axisLabel: {
        // 根据数据量调整显示间隔
        interval: Math.ceil(data.dates.length / 10),
        rotate: data.dates.length > 15 ? 45 : 0
      }
    },
    yAxis: {
      type: 'value',
      ...config.yAxis
    },
    series: [
      {
        name: config.name,
        type: 'line',
        data: data.values,
        smooth: true,
        symbol: 'circle',
        symbolSize: 6,
        showSymbol: true, // 平时不显示数据点
        lineStyle: {
          width: 3,
          color: config.color
        },
        itemStyle: {
          color: config.color,
          borderWidth: 2,
          borderColor: '#fff'
        },
        areaStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            {
              offset: 0,
              color: `${config.color}40`
            },
            {
              offset: 1,
              color: `${config.color}10`
            }
          ])
        },
        emphasis: {
          focus: 'item', // 只高亮当前鼠标悬停的点
          showSymbol: true, // 鼠标悬停时显示数据点
          itemStyle: {
            symbolSize: 10,
            borderWidth: 3,
            borderColor: '#fff'
          }
        },
        // 确保鼠标能准确捕捉到数据点
        triggerLineEvent: true,
      }
    ]
  }
  
  chartInstance.value.setOption(option, true)
}

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance.value) {
    chartInstance.value.resize()
  }
}

// 监听选中的时间范围变化
watch(selectedDays, (newValue) => {
  // 向父组件发送时间范围变化事件
  emit('timeRangeChange', newValue)
  // 当数据加载完成后，updateChart会在props.chartData变化时被调用
})

// 监听props变化
watch(
  () => [props.chartData, props.selectedTimeRange],
  () => {
    nextTick(() => {
      updateChart()
    })
  },
  { deep: true }
)

// 组件挂载时初始化图表
onMounted(() => {
  initChart()
})

// 组件卸载时清理
onUnmounted(() => {
  window.removeEventListener('resize', handleResize)
  if (chartInstance.value) {
    chartInstance.value.dispose()
  }
})

// 暴露更新图表的方法，供父组件调用
defineExpose({
  refreshChart: updateChart
})
</script>

<template>
  <div class="weather-chart-container">
    <!-- 时间选择器 -->
    <div class="chart-controls">
      <el-radio-group v-model="selectedDays" class="time-range-selector">
        <el-radio-button :value="7" :disabled="loading">近7天</el-radio-button>
        <el-radio-button :value="30" :disabled="loading">近30天</el-radio-button>
        <el-radio-button :value="90" :disabled="loading">近90天</el-radio-button>
      </el-radio-group>
      
      <!-- 加载状态指示器 -->
      <!-- <div v-if="loading" class="loading-indicator">
        <span class="loading-text">数据加载中...</span>
      </div> -->
    </div>
    
    <!-- 图表容器 -->
    <div 
      ref="chartContainer" 
      class="chart-wrapper" 
    ></div>
  </div>
</template>

<style lang="scss" scoped>
// 使用unocss原子化类和scss结合的方案
.weather-chart-container {
  @apply w-full h-full bg-white rounded-md p-4 shadow-md;
}

.chart-controls {
  @apply mb-4 flex justify-end items-center gap-4;
}

.loading-indicator {
  @apply text-xs text-[#606266];
}

.loading-text {
  @apply inline-block ml-1;
  animation: fadeInOut 1.5s infinite;
}

// 保留自定义动画
@keyframes fadeInOut {
  0%, 100% { opacity: 0.3; }
  50% { opacity: 1; }
}

.time-range-selector {
  @apply bg-[#f5f7fa] rounded-md p-1;
}

.chart-wrapper {
  @apply w-full transition-all duration-300 ease-in-out;
  height: calc(100% - 50px);
}
</style>