<script setup lang='ts'>
import { ref, onMounted, nextTick, onUnmounted, defineProps } from 'vue';
import VueEcharts from 'vue-echarts';
import 'echarts';
import request from '../../../utils/request';

interface HistoryDataItem {
  dataset_id: number;
  row_count: number;
  model_id: number;
  model_name: string;
  performance_score: number;
  timestamp: string;
}

interface HistoryDataResponse {
  data_type: string;
  timestamps: string[];
  row_counts: number[];
  performance_scores: number[];
  model_details: HistoryDataItem[];
}

interface ScatterDataResponse {
  scatter_data: [number, number][];
  r2_score: number;
  y_range: [number, number];
  model_name: string;
  model_type: string;
}

const props = defineProps({
  showLineChart: {
    type: Boolean,
    default: true
  },
  showInitScatterChart: {
    type: Boolean,
    default: true
  },
  showMidScatterChart: {
    type: Boolean,
    default: true
  },
  showFinalScatterChart: {
    type: Boolean,
    default: true
  },
  lineChartPathParam: {
    type: String,
    default: 'reduce'
  },
  initScatterModelId: {
    type: Number,
    default: 6
  },
  midScatterModelId: {
    type: Number,
    default: 7
  },
  finalScatterModelId: {
    type: Number,
    default: 17
  }
});

// 定义响应式变量
const ecLineOption = ref({});
const ecInitScatterOption = ref({});
const ecMidScatterOption = ref({});
const ecFinalScatterOption = ref({});

// 定义图表引用
const ecLineOptionRef = ref<InstanceType<typeof VueEcharts>>();
const ecInitScatterOptionRef = ref<InstanceType<typeof VueEcharts>>();
const ecMidScatterOptionRef = ref<InstanceType<typeof VueEcharts>>();
const ecFinalScatterOptionRef = ref<InstanceType<typeof VueEcharts>>();

// 计算数据范围的函数
const calculateDataRange = (data: [number, number][]) => {
  const xValues = data.map(item => item[0]);
  const yValues = data.map(item => item[1]);
  return {
    xMin: Math.min(...xValues),
    xMax: Math.max(...xValues),
    yMin: Math.min(...yValues),
    yMax: Math.max(...yValues)
  };
};

// 获取折线图数据
const fetchLineData = async () => {
  try {
    const response = await request.get<HistoryDataResponse>(`/get-model-history/${props.lineChartPathParam}`);
    const data = response.data;

    const timestamps = data.timestamps;
    const performanceScores: Record<string, number[]> = {};

    data.model_details.forEach((item: HistoryDataItem) => {
      const score = Number(item.performance_score);
      if (!performanceScores[item.model_name]) {
        performanceScores[item.model_name] = [];
      }
      performanceScores[item.model_name].push(score);
    });

    const series = Object.keys(performanceScores).map(modelName => ({
      name: modelName,
      type: 'line',
      data: performanceScores[modelName]
    }));

    ecLineOption.value = {
      tooltip: {
        trigger: 'axis'
      },
      legend: {
        data: Object.keys(performanceScores)
      },
      grid: {
        left: '3%',
        right: '17%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        name: '模型迭代',
        type: 'category',
        boundaryGap: false,
        data: timestamps.map((_, index) => `${index + 1}代`)
      },
      yAxis: {
        name: 'Score (R^2)',
        type: 'value'
      },
      series
    };
    console.log('ecLineOption updated:', ecLineOption.value);
  } catch (error) {
    console.error('获取折线图数据失败:', error);
  }
};

// 获取散点图数据
const fetchScatterData = async (modelId: number, optionRef: any) => {
  try {
    const response = await request.get<ScatterDataResponse>(`/model-scatter-data/${modelId}`);
    const data = response.data;

    const scatterData = data.scatter_data;
    const range = calculateDataRange(scatterData);
    const padding = 0.1;
    const xMin = range.xMin - Math.abs(range.xMin * padding);
    const xMax = range.xMax + Math.abs(range.xMax * padding);
    const yMin = range.yMin - Math.abs(range.yMin * padding);
    const yMax = range.yMax + Math.abs(range.yMax * padding);
    const min = Math.min(xMin, yMin);
    const max = Math.max(xMax, yMax);

    optionRef.value = {
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'cross'
        }
      },
      legend: {
        data: ['True vs Predicted']
      },
      grid: {
        left: '3%',
        right: '22%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        name: 'True Values',
        type: 'value',
        min: min,
        max: max
      },
      yAxis: {
        name: 'Predicted Values',
        type: 'value',
        min: parseFloat(min.toFixed(2)),
        max: parseFloat(max.toFixed(2))
      },
      series: [
        {
          name: 'True vs Predicted',
          type: 'scatter',
          data: scatterData,
          symbolSize: 10,
          itemStyle: {
            color: '#1f77b4',
            opacity: 0.7
          }
        },
        {
          name: 'Trendline',
          type: 'line',
          data: [
            [min, min],
            [max, max]
          ],
          lineStyle: {
            type: 'dashed',
            color: '#ff7f0e',
            width: 2
          }
        }
      ]
    };
  } catch (error) {
    console.error('获取散点图数据失败:', error);
  }
};

// 定义调整图表大小的函数
const resizeCharts = () => {
  nextTick(() => {
    if (props.showLineChart) ecLineOptionRef.value?.resize();
    if (props.showInitScatterChart) ecInitScatterOptionRef.value?.resize();
    if (props.showMidScatterChart) ecMidScatterOptionRef.value?.resize();
    if (props.showFinalScatterChart) ecFinalScatterOptionRef.value?.resize();
  });
};

onMounted(async () => {
  if (props.showLineChart) await fetchLineData();
  if (props.showInitScatterChart) await fetchScatterData(props.initScatterModelId, ecInitScatterOption);
  if (props.showMidScatterChart) await fetchScatterData(props.midScatterModelId, ecMidScatterOption);
  if (props.showFinalScatterChart) await fetchScatterData(props.finalScatterModelId, ecFinalScatterOption);

  // 页面加载完成后调整图表大小
  resizeCharts();

  // 监听窗口大小变化，调整图表大小
  window.addEventListener('resize', resizeCharts);
});

// 组件卸载时移除事件监听器
onUnmounted(() => {
  window.removeEventListener('resize', resizeCharts);
});
</script>

<template>
  <div class="container">
    <template v-if="showLineChart">
      <!-- 折线图表头 -->
      <div class="chart-container">
        <VueEcharts :option="ecLineOption" ref="ecLineOptionRef" />
      </div>
    </template>
    <template v-if="showInitScatterChart">
      <!-- 初代散点图表头 -->
      <h2 class="chart-header">初代散点图</h2>
      <div class="chart-container">
        <VueEcharts :option="ecInitScatterOption" ref="ecInitScatterOptionRef" />
      </div>
    </template>
    <template v-if="showMidScatterChart">
      <!-- 中间代散点图表头 -->
      <h2 class="chart-header">中间代散点图</h2>
      <div class="chart-container">
        <VueEcharts :option="ecMidScatterOption" ref="ecMidScatterOptionRef" />
      </div>
    </template>
    <template v-if="showFinalScatterChart">
      <!-- 最终代散点图表头 -->
      <h2 class="chart-header">最终代散点图</h2>
      <div class="chart-container">
        <VueEcharts :option="ecFinalScatterOption" ref="ecFinalScatterOptionRef" />
      </div>
    </template>
  </div>
</template>

<style scoped>
.container {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  gap: 20px;
}

.chart-header {
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 10px;
}

.sub-title {
  font-size: 14px;
  font-weight: 700;
}

.chart-container {
  width: 85%;
  height: 450px;
  margin: 0 auto;
  margin-bottom: 20px;
}

.VueEcharts {
  width: 100%;
  height: 100%;
  margin: 0 10px;
}
</style>



