<template>
  <div class="soil-dashboard p-4 bg-white min-h-screen">
    <div class="flex justify-between items-center mb-6">
      <h1 class="text-xl font-bold text-gray-800">有效态 Cd 数据统计分析</h1>
      <div class="flex items-center">
        <div class="stat-card inline-block px-3 py-2">
          <div class="stat-value text-lg">样本数量{{ stats.samples }}</div>
        </div>
      </div>
    </div>
    
    <!-- 加载状态 -->
    <div v-if="isLoading" class="loading-overlay">
      <span class="spinner"></span>
      <span class="ml-3 text-gray-700">数据加载中...</span>
    </div>
    
    <!-- 错误提示 -->
    <div v-if="error" class="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded mb-6">
      <p>数据加载失败: {{ error.message }}</p>
      <button class="mt-2 px-3 py-1 bg-red-500 text-white rounded" @click="initCharts">重试</button>
    </div>
    
    <!-- 1️⃣ 总Cd & 有效态Cd -->
    <section class="mb-4 chart-container">
      <h3 class="section-title text-base font-semibold">污染指标</h3>
      <div ref="cdBarChart" style="width: 100%; height: 415px;"></div>
    </section>

    <!-- 2️⃣ 养分元素 -->
    <section class="mb-4 chart-container">
      <h3 class="section-title text-base font-semibold">主要养分元素</h3>
      <div ref="nutrientBoxChart" style="width: 100%; height: 400px;"></div>
    </section>

    <!-- 3️⃣ 其他理化性质 -->
    <section class="chart-container">
      <div class="flex justify-between items-center mb-3">
        <h3 class="section-title text-base font-semibold">其他理化性质</h3>
      </div>
      <div ref="extraBoxChart" style="height: 400px; width: 100%;"></div>
    </section>
  </div>
</template>

<script setup>
import { ref, onMounted, watch, nextTick } from 'vue';
import * as echarts from 'echarts';
import axios from 'axios';

// 图表实例引用
const cdBarChart = ref(null);
const nutrientBoxChart = ref(null);
const extraBoxChart = ref(null);

// 图表实例变量
let chartInstanceCd = null;
let chartInstanceNutrient = null;
let chartInstanceExtra = null;
const chartInstancePopup =null;


// 响应式状态
const isLoading = ref(true);
const error = ref(null);
const stats = ref({
  totalCdAvg: 0,
  effCdAvg: 0,
  samples: 0
});

// 参考灌溉水代码：按图表类型缓存统计数据（与x轴顺序严格对应）
const pollutionStats = ref([]);       // 污染指标统计（总镉/有效态镉）
const nutrientStats = ref([]);        // 养分元素统计
const extraStats = ref([]);           // 其他理化性质统计

// 字段配置（参考灌溉水的重金属配置方式）
const fieldConfig = {
  pollution: [
    { key: 'TCd_IDW', name: '总镉', color: '#5470c6' ,unit:'mg/kg' , convert: false },
     { key: 'AvaK_IDW', name: '速效钾', color: '#fac858',unit:'mg/kg', convert: false },
    { key: 'AvaP_IDW', name: '有效磷', color: '#fac858' ,unit:'mg/kg' , convert: false},
    { key: 'TMn_IDW', name: '全锰', color: '#73c0de' ,unit:'mg/kg' , convert: false},
    { key: 'TN_IDW', name: '全氮', color: '#fac858' ,unit:'mg/kg' , convert: true, conversionFactor: 1000},
    { key: 'TP_IDW', name: '全磷', color: '#fac858' ,unit:'mg/kg', convert: true, conversionFactor: 1000},
    { key: 'TK_IDW', name: '全钾', color: '#fac858' ,unit:'mg/kg', convert: true, conversionFactor: 1000},
  ],
  nutrient: [
    { key: 'AvaK_IDW', name: '速效钾', color: '#fac858',unit:'mg/kg' , convert: false},
    { key: 'AvaP_IDW', name: '有效磷', color: '#fac858' ,unit:'mg/kg', convert: false },
    { key: 'TMn_IDW', name: '全锰', color: '#73c0de' ,unit:'mg/kg', convert: false },
    { key: 'TN_IDW', name: '全氮', color: '#fac858' ,unit:'mg/kg' , convert: true, conversionFactor: 1000},
    { key: 'TP_IDW', name: '全磷', color: '#fac858' ,unit:'mg/kg' , convert: true, conversionFactor: 1000},
    { key: 'TK_IDW', name: '全钾', color: '#fac858' ,unit:'mg/kg', convert: true, conversionFactor: 1000},
    { key: 'TS_IDW', name: '全硫', unit:'mg/kg',convert:true,conversionFactor:1000}
  ],
  extra: [
    { key: 'TFe_IDW', name: '全铁', color: '#73c0de' ,unit:'%', convert: false},
    { key: 'TCa_IDW', name: '全钙', color: '#73c0de' ,unit:'%', convert: false},
    { key: 'TMg_IDW', name: '全镁', color: '#73c0de' ,unit:'%', convert: false},
    { key: 'TAl_IDW', name: '全铝', color: '#73c0de' ,unit:'%', convert: false}
  ]
};


// 数据请求
const fetchData = async () => {
  try {
    // 实际项目中替换为真实API
     const res = await axios.get("http://localhost:8000/api/vector/stats/EffCd_input_data");
     return res.data.data;

  } catch (err) {
    throw new Error('数据加载失败: ' + err.message);
  }
};

// 计算单个字段的箱线图统计量（带顺序校正）
const calculateFieldStats = (statsData, fieldKey, fieldName, fieldConfigItem) => {
  const fieldStats = statsData[fieldKey]; // 从接口数据中取当前字段的统计结果
  if (!fieldStats) {
    return { key: fieldKey, name: fieldName, min: null, q1: null, median: null, q3: null, max: null, mean: null };
  }

  // 提取原始统计值
  let min = fieldStats.min;
  let q1 = fieldStats.q1;
  let median = fieldStats.median;
  let q3 = fieldStats.q3;
  let max = fieldStats.max;
  let mean = fieldStats.mean;

  // 处理「单位转换」（与原代码逻辑一致，若配置了convert则乘以系数）
  if (fieldConfigItem?.convert && fieldConfigItem.conversionFactor) {
    min *= fieldConfigItem.conversionFactor;
    q1 *= fieldConfigItem.conversionFactor;
    median *= fieldConfigItem.conversionFactor;
    q3 *= fieldConfigItem.conversionFactor;
    max *= fieldConfigItem.conversionFactor;
    mean *= fieldConfigItem.conversionFactor;
  }

  // 强制校正统计量顺序（确保 min ≤ q1 ≤ median ≤ q3 ≤ max）
  const sortedStats = [min, q1, median, q3, max].sort((a, b) => a - b);
  return {
    key: fieldKey,
    name: fieldName,
    min: sortedStats[0],
    q1: sortedStats[1],
    median: sortedStats[2],
    q3: sortedStats[3],
    max: sortedStats[4],
    mean: mean
  };
};

// 批量计算所有字段的统计量（按图表类型缓存）
const calculateAllStats = (statsData) => {
  // 1. 污染指标统计（与x轴顺序一致）
  pollutionStats.value = fieldConfig.pollution.map(field => 
    calculateFieldStats(statsData, field.key, field.name, field)
  );
  
  // 2. 养分元素统计（与x轴顺序一致）
  nutrientStats.value = fieldConfig.nutrient.map(field => 
    calculateFieldStats(statsData, field.key, field.name, field)
  );
  
  // 3. 其他理化性质统计（与x轴顺序一致）
  extraStats.value = fieldConfig.extra.map(field => 
    calculateFieldStats(statsData, field.key, field.name, field)
  );
  
  // 更新「样本数量、平均值」统计（从接口数据中取mean更准确）
  const totalCdStats = pollutionStats.value.find(s => s.key === 'TCd_IDW'); // 替换为实际「总Cd」字段名
  const effCdStats = pollutionStats.value.find(s => s.key === 'Cdsolution'); // 替换为实际「有效态Cd」字段名
  stats.value = {
    totalCdAvg: totalCdStats ? totalCdStats.mean : 0,
    effCdAvg: effCdStats ? effCdStats.mean : 0,
    samples: statsData[Object.keys(statsData)[0]]?.count || 0 // 取第一个字段的count作为样本数
  };
};

// 构建箱线图数据（将统计量转换为ECharts所需格式）
const buildBoxplotData = (statsArray) => {
  return statsArray.map(stat => {
    if (!stat.min) return [null, null, null, null, null];
    return [stat.min, stat.q1, stat.median, stat.q3, stat.max];
  });
};

// 初始化污染指标图表（柱状图）
const initPollutionChart = () => {
  if (chartInstanceCd) chartInstanceCd.dispose();
  chartInstanceCd = echarts.init(cdBarChart.value);
  
  // 提取x轴标签和数据
  const xAxisData = fieldConfig.pollution.map(f => f.name);
  const barData = pollutionStats.value.map(stat =>stat.mean);
  
  chartInstanceCd.setOption({
    title: { text: '主要指标含量对比', left: 'center', textStyle: { fontSize: 14 } },
    tooltip: {
      trigger: 'axis',
      formatter: (params) => `${params[0].name}<br/>平均值: ${params[0].value.toFixed(4)} mg/kg`
    },
    grid: { top: 40, right: 15, bottom: 30, left: 40 },
    xAxis: { type: "category", data: xAxisData, axisLabel: { fontSize: 12 ,rotate:30 } },
    yAxis: { type: "value", name: '含量 (mg/kg)', nameTextStyle: { fontSize: 12  }, axisLabel: { fontSize: 11 ,rotate:30} },
    series: [{
      name: '平均值', type: "bar",
      itemStyle: {color: '#5470c6' },
      data: barData
    }]
  });
};

// 初始化养分元素图表（箱线图）
const initNutrientChart = () => {
  if (chartInstanceNutrient) chartInstanceNutrient.dispose();
  chartInstanceNutrient = echarts.init(nutrientBoxChart.value);
  
  const xAxisData = fieldConfig.nutrient.map(f => f.name);
  const boxData = buildBoxplotData(nutrientStats.value);
  
  chartInstanceNutrient.setOption({
    title: { text: "主要养分元素分布", left: 'center', textStyle: { fontSize: 14 } },
    tooltip: {
      trigger: "item",
      formatter: (params) => formatTooltip(nutrientStats.value[params.dataIndex])
    },
    grid: { top: 40, right: 15, bottom: 40, left: 40 },
    xAxis: { type: "category", data: xAxisData, axisLabel: { fontSize: 11, rotate: 30 } },
    yAxis: { type: "value", name: '含量(mg/kg)', nameTextStyle: { fontSize: 12 }, axisLabel: { fontSize: 11 , rotate: 30 } },
    series: [{
      name: '养分元素', type: "boxplot",
      itemStyle: { color: '#fac858', borderColor: '#ee6666' },
      data: boxData
    }]
  });
};

// 初始化其他理化性质图表（箱线图）
const initExtraChart = () => {
  const xAxisData = fieldConfig.extra.map(f => f.name);
  const boxData = buildBoxplotData(extraStats.value);
  
      nextTick(() => {
        if (chartInstanceExtra) chartInstanceExtra.dispose();
        chartInstanceExtra = echarts.init(extraBoxChart.value);
        chartInstanceExtra.setOption({
          title: { text: "其他理化性质分布", left: 'center', textStyle: { fontSize: 14 } },
          tooltip: {
            trigger: "item",
            formatter: (params) => formatTooltip(extraStats.value[params.dataIndex])
          },
          grid: { top: 40, right: 15, bottom: 40, left: 40 },
          xAxis: { type: "category", data: xAxisData, axisLabel: { fontSize: 11 } },
          yAxis: { type: "value", name: '%', nameTextStyle: { fontSize: 12 }, axisLabel: { fontSize: 11 } },
          series: [{
            name: '理化性质', type: "boxplot",
            itemStyle: { color: '#73c0de', borderColor: '#5470c6' },
            data: boxData
          }]
        });
  });
};


// 格式化Tooltip（复用缓存的统计数据）
const formatTooltip = (stat) => {
  if (!stat || !stat.min) {
    return `<div style="font-weight:bold;color:#f56c6c">${stat?.name || '未知'}</div><div>无有效数据</div>`;
  }
  return `<div style="font-weight:bold">${stat.name}</div>
    <div style="margin-top:8px">
      <div>最小值：<span style="color:#5a5;">${stat.min.toFixed(4)}</span></div>
      <div>下四分位：<span style="color:#d87a80;">${stat.q1.toFixed(4)}</span></div>
      <div>中位数：<span style="color:#f56c6c;font-weight:bold;">${stat.median.toFixed(4)}</span></div>
      <div>上四分位：<span style="color:#d87a80;">${stat.q3.toFixed(4)}</span></div>
      <div>最大值：<span style="color:#5a5;">${stat.max.toFixed(4)}</span></div>
    </div>`;
};

// 初始化图表主流程
const initCharts = async () => {
  try {
    isLoading.value = true;
    error.value = null;
    
    const data = await fetchData();
    calculateAllStats(data); // 计算并缓存所有统计数据
    
    // 初始化图表
    initPollutionChart();
    initNutrientChart();
    initExtraChart();
    
    isLoading.value = false;
  } catch (err) {
    isLoading.value = false;
    error.value = err;
    console.error('初始化失败:', err);
  }
};

// 组件挂载
onMounted(() => {
  initCharts();
  
  // 窗口 resize 处理
  const handleResize = () => {
    [chartInstanceCd, chartInstanceNutrient, chartInstanceExtra, chartInstancePopup]
      .forEach(inst => inst && inst.resize());
  };
  window.addEventListener('resize', handleResize);
  
  // 组件卸载清理
  return () => {
    window.removeEventListener('resize', handleResize);
    [chartInstanceCd, chartInstanceNutrient, chartInstanceExtra, chartInstancePopup]
      .forEach(inst => inst && inst.dispose());
  };
});
</script>

<style>
.soil-dashboard {
  font-family: 'PingFang SC', 'Microsoft YaHei', sans-serif;
  max-width: 1200px;
  margin: 0 auto;
  font-size: 14px;
}
.chart-container {
  background: white;
  border-radius: 6px;
  box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
  padding: 12px;
  margin-bottom: 16px;
}
.section-title {
  color: #2c3e50;
  border-left: 3px solid #3498db;
  padding-left: 10px;
  margin-bottom: 12px;
}
.toggle-btn {
  background: #f8f9fa;
  border: 1px solid #e9ecef;
  padding: 6px 12px;
  border-radius: 3px;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  transition: all 0.3s;
}
.toggle-btn:hover {
  background: #e9ecef;
}
.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.8);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 10;
}
.spinner {
  width: 30px;
  height: 30px;
  border: 3px solid rgba(0, 0, 0, 0.1);
  border-radius: 50%;
  border-left-color: #3498db;
  animation: spin 1s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.stat-card {
  background: linear-gradient(135deg, #f5f7fa 0%, #e4edf5 100%);
  border-radius: 6px;
  padding: 8px 12px;
  box-shadow: 0 1px 3px rgba(0,0,0,0.05);
}
.stat-value {
  font-size: 16px;
  font-weight: bold;
  color: #2c3e50;
}
.stat-label {
  font-size: 12px;
  color: #7f8c8d;
}
.legend-item {
  display: flex;
  align-items: center;
  margin-right: 12px;
  font-size: 13px;
}
.legend-color {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  margin-right: 5px;
}
</style>
