<template>
  <div class="page">
    <el-card>
      <div style="text-align: center; margin-bottom: 8px">
        <h3>叶片疑似故障位置示意图</h3>
      </div>
      <div ref="chartRef" class="chart" />
      <!-- 在图表底部显示叶片长度信息 -->
      <div class="chart-footer">
        <div class="blade-info">
          <span class="blade-length">叶片长度: {{ length }} 米</span>
        </div>
      </div>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, onMounted, onBeforeUnmount, computed } from "vue";
import * as echarts from "echarts";

interface Props {
  /** 可为单个数字或数组（单位：m） */
  faultPoints?: number[] | number | null;
  /** 叶片长度（米） */
  bladeLength?: string | number;
  /** 智选结果字符串 */
  intelligentResult?: string;
}

const props = defineProps<Props>();

const chartRef = ref<HTMLDivElement | null>(null);
let chart: echarts.ECharts | null = null;

const rootThickness = 2;
const tipThickness = 0.2;
const curvature = 0.4;
const points = 300;

/** ✅ 从 props 动态生成疑似故障点数组 */
const highlightPoints = ref<number[]>([]);
/** ✅ 断线位置数组 */
const breakLinePoints = ref<number[]>([]);

// ✅ 计算叶片长度，如果没有传入则默认50米
const length = computed(() => {
  if (props.bladeLength == null || props.bladeLength === "") {
    console.log("📏 bladeLength: 使用默认值 50m");
    return 50;
  }

  const numValue =
    typeof props.bladeLength === "string"
      ? parseFloat(props.bladeLength)
      : props.bladeLength;

  const result = Math.max(10, Math.min(200, numValue || 50));
  console.log(`📏 bladeLength: ${props.bladeLength} -> 计算后: ${result}m`);
  return result;
});

// ✅ 从 intelligentResult 中提取断线位置
const extractBreakLinePosition = computed(() => {
  if (!props.intelligentResult) {
    console.log("🧠 intelligentResult: 为空");
    return null;
  }

  console.log(`🧠 intelligentResult: "${props.intelligentResult}"`);

  // 方法1：提取"断线位置X米"中的数字
  const positionMatch = props.intelligentResult.match(
    /断线位置\s*(\d+(?:\.\d+)?)\s*米/
  );
  if (positionMatch && positionMatch[1]) {
    const result = parseFloat(positionMatch[1]);
    console.log(`✅ 从 intelligentResult 提取到断线位置: ${result}m`);
    return result;
  }

  // 方法2：提取所有数字，取第一个（作为备选）
  const numbers = props.intelligentResult.match(/\d+(?:\.\d+)?/g);
  if (numbers && numbers.length > 0) {
    const result = parseFloat(numbers[0]);
    console.log(`⚠️ 使用备选方法提取断线位置: ${result}m`);
    return result;
  }

  console.log("❌ 未从 intelligentResult 中提取到断线位置");
  return null;
});

/** ✅ 监听 faultPoints 变化 - 修复清空逻辑 */
watch(
  () => props.faultPoints,
  (newVal, oldVal) => {
    console.group("🔄 faultPoints 变化监听");
    console.log("📊 旧值:", oldVal);
    console.log("📊 新值:", newVal);
    console.log("📊 新值类型:", typeof newVal);

    // 处理所有可能的清空情况
    if (
      newVal == null ||
      newVal === "" ||
      newVal === undefined ||
      (Array.isArray(newVal) && newVal.length === 0) ||
      (typeof newVal === "number" && isNaN(newVal)) ||
      newVal === [] // 明确处理空数组
    ) {
      highlightPoints.value = [];
      console.log("✅ 清空疑似故障点");
    } else if (Array.isArray(newVal)) {
      // 过滤掉无效值
      highlightPoints.value = newVal.filter(
        (point) =>
          point != null &&
          !isNaN(point) &&
          typeof point === "number" &&
          point > 0
      );
      console.log("✅ 更新疑似故障点数组:", highlightPoints.value);
    } else if (typeof newVal === "number" && !isNaN(newVal) && newVal > 0) {
      highlightPoints.value = [newVal];
      console.log("✅ 更新单个疑似故障点:", highlightPoints.value);
    } else {
      // 其他意外情况也清空
      highlightPoints.value = [];
      console.log("⚠️ 意外数据格式，清空疑似故障点");
    }

    console.groupEnd();
    renderChart();
  },
  { immediate: true, deep: true }
);

/** ✅ 监听 intelligentResult 变化 */
watch(
  () => props.intelligentResult,
  (newVal, oldVal) => {
    console.group("🔄 intelligentResult 变化监听");
    console.log("📝 旧值:", oldVal);
    console.log("📝 新值:", newVal);

    if (newVal) {
      const breakLinePos = extractBreakLinePosition.value;
      if (breakLinePos !== null && !isNaN(breakLinePos)) {
        breakLinePoints.value = [breakLinePos];
        console.log("✅ 更新断线位置:", breakLinePoints.value);
      } else {
        breakLinePoints.value = [];
        console.log("❌ 未提取到有效的断线位置");
      }
    } else {
      breakLinePoints.value = [];
      console.log("✅ 清空断线位置");
    }
    console.groupEnd();
    renderChart();
  },
  { immediate: true }
);

/** ✅ 监听 bladeLength 变化 */
watch(
  () => props.bladeLength,
  (newVal, oldVal) => {
    console.group("🔄 bladeLength 变化监听");
    console.log("📏 旧值:", oldVal);
    console.log("📏 新值:", newVal);
    console.log("📏 计算后长度:", length.value);
    console.groupEnd();
    renderChart();
  }
);

// 初始化时打印所有props的初始值
console.group("🎯 Props 初始值");
console.log("📊 faultPoints:", props.faultPoints);
console.log("📏 bladeLength:", props.bladeLength);
console.log("🧠 intelligentResult:", props.intelligentResult);
console.groupEnd();

function generateBladeOutline(len: number) {
  const upper: [number, number][] = [];
  const lower: [number, number][] = [];

  const peakRatio = 0.2;
  const peakX = len * peakRatio;
  const peakHeight = 2;

  const slopeStartRatio = 0.04;
  const slopeStartX = len * slopeStartRatio;
  const endX = len;
  const lowerEndY = 0;

  const halfThicknessPeak =
    rootThickness - (rootThickness - tipThickness) * (peakX / len);
  const curveFactorPeak = curvature * Math.exp(-peakX / (len * 0.4));
  const yOffsetPeak = curveFactorPeak * Math.sin((peakX / len) * Math.PI);
  const yPeak = halfThicknessPeak + yOffsetPeak + peakHeight;

  for (let i = 0; i <= points; i++) {
    const x = (i / points) * len;
    const halfThickness =
      rootThickness - (rootThickness - tipThickness) * (x / len);
    const curveFactor = curvature * Math.exp(-x / (len * 0.4));
    const yOffset = curveFactor * Math.sin((x / len) * Math.PI);
    let upperY = halfThickness + yOffset;

    if (x >= slopeStartX && x <= peakX) {
      const t = (x - slopeStartX) / (peakX - slopeStartX);
      upperY += peakHeight * Math.sin(t * (Math.PI / 2));
    } else if (x > peakX) {
      const slope = (lowerEndY - yPeak) / (endX - peakX);
      upperY = yPeak + slope * (x - peakX);
    }

    upper.push([x, upperY]);
    lower.push([x, 0]);
  }

  return { upper, lower };
}

function buildOption(len: number) {
  const { upper, lower } = generateBladeOutline(len);

  const sparStart = len * 0.1;
  const sparEnd = len * 0.75;
  const sparTop = upper.filter(([x]) => x >= sparStart && x <= sparEnd);
  const sparBottom = lower.filter(([x]) => x >= sparStart && x <= sparEnd);
  const spar = sparTop.concat(sparBottom.reverse());

  // === 疑似故障点 ===
  const highlightData = highlightPoints.value
    .filter((x) => x != null && !isNaN(x) && x <= len)
    .map((x) => {
      const y = upper.find(([x0]) => Math.abs(x0 - x) < len / points)?.[1] ?? 0;
      return {
        value: [x, y + 0.3],
        symbolSize: 10,
        itemStyle: { color: "#0070B2" },
        label: {
          show: true,
          formatter: `疑似故障点\n${x.toFixed(1)} m`,
          position: "top",
          color: "#0070B2",
          fontWeight: "bold",
        },
      };
    });

  // === 断线位置点 ===
  const breakLineData = breakLinePoints.value
    .filter((x) => x != null && !isNaN(x) && x <= len)
    .map((x) => {
      return {
        value: [x, 0],
        symbolSize: 16,
        itemStyle: { color: "#ff0000" },
        label: {
          show: true,
          formatter: `故障点\n${x.toFixed(1)} m`,
          position: "bottom",
          color: "#ff0000",
          fontWeight: "bold",
          backgroundColor: "rgba(255,255,255,0.8)",
          borderColor: "#ff0000",
          borderWidth: 1,
          borderRadius: 4,
          padding: [4, 4],
        },
      };
    });

  // === 红色虚线（疑似故障点）===
  const guideLines = highlightPoints.value
    .filter((x) => x != null && !isNaN(x) && x <= len)
    .map((x) => ({
      coords: [
        [x, -4],
        [x, 4],
      ],
      lineStyle: {
        color: "#0070B2",
        width: 2,
        type: "dashed",
      },
    }));

  // === 蓝色虚线（断线位置）===
  const breakLines = breakLinePoints.value
    .filter((x) => x != null && !isNaN(x) && x <= len)
    .map((x) => ({
      coords: [
        [x, -4],
        [x, 4],
      ],
      lineStyle: {
        color: "#ff0000",
        width: 3,
        type: "dashed",
      },
    }));

  return {
    tooltip: { show: false },
    xAxis: {
      type: "value",
      // name: "位置 (m)",
      min: 0,
      max: len,
      splitLine: { show: false },
    },
    yAxis: {
      type: "value",
      min: -3,
      max: 4,
      splitLine: { show: false },
      // 隐藏Y轴的值
      axisLabel: {
        show: false,
      },
      axisTick: { show: false }, // 隐藏刻度
      axisLine: { show: false }, // 隐藏轴线
    },
    series: [
      {
        type: "line",
        smooth: true,
        data: upper,
        lineStyle: { color: "#C0C0C0", width: 5},
        showSymbol: false,
      },
      {
        type: "line",
        smooth: true,
        data: lower,
        lineStyle: { color: "#C0C0C0", width: 5 },
        showSymbol: false,
      },
      // {
      //   type: "line",
      //   data: upper.concat(lower.slice().reverse()),
      //   lineStyle: { width: 0 },
      //   areaStyle: { color: "rgba(120,160,220,0.2)" },
      //   silent: true,
      // },
      // 红色虚线（疑似故障点）
      {
        type: "lines",
        coordinateSystem: "cartesian2d",
        data: guideLines,
        silent: true,
      },
      // 蓝色虚线（断线位置）
      {
        type: "lines",
        coordinateSystem: "cartesian2d",
        data: breakLines,
        silent: true,
      },
      // 疑似故障点标注
      {
        type: "scatter",
        data: highlightData,
        symbol: "circle",
        emphasis: { disabled: true },
      },
      {
        smooth: true,  
        type: "line",
        data: [
          [0, 0],
          [0, upper[0][1]], // 连接到上轮廓线的起点高度
        ],
        lineStyle: {
          color: "#C0C0C0",
          width: 5,
        },
        showSymbol: false,
      },

      // 断线位置标注
      {
        type: "scatter",
        data: breakLineData,
        symbol: "circle",
        emphasis: { disabled: true },
      },
    ],
    grid: { left: 20, right: 20, top: 40, bottom: 20 },
  };
}

function renderChart() {
  if (!chartRef.value) return;
  if (!chart) {
    chart = echarts.init(chartRef.value);
  }
  chart.setOption(buildOption(length.value), true);
}

onMounted(() => {
  console.log("🎯 组件挂载完成");
  renderChart();
  window.addEventListener("resize", resize);
});

function resize() {
  chart?.resize();
}

onBeforeUnmount(() => {
  console.log("🧹 组件卸载清理");
  window.removeEventListener("resize", resize);
  chart?.dispose();
});
</script>

<style scoped>
.page {
  padding: 6px 0 0 0;
}
.chart {
  width: 100%;
  height: 220px;
}
.chart-footer {
  margin-top: 8px;
  text-align: center;
}
.blade-info {
  display: inline-block;
  padding: 4px 12px;
  background-color: #f5f7fa;
  border-radius: 4px;
  border: 1px solid #e4e7ed;
}
.blade-length {
  font-size: 14px;
  font-weight: 500;
  color: #606266;
}
</style>
