<!-- SidePanelItem.vue -->
<template>
  <SidePanelItem
    title="水文监测"
    :select="select"
    :scopeDate="datetimePicker"
    @update-values="handlePanelChange1"
  >
    <div class="chart-wrapper">
      <a-spin :spinning="loading">
        <!-- 始终渲染图表容器，确保有固定宽高 -->
        <div ref="chartRef" class="echarts-chart"></div>
        <!-- 无数据时显示Empty，但不影响容器尺寸 -->
        <div v-if="!loading && !hasData" class="empty-overlay">
          <a-empty description="暂无数据" />
        </div>
      </a-spin>
    </div>
  </SidePanelItem>
</template>

<script lang="ts" setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue';
import * as echarts from 'echarts';
import type { EChartsOption } from 'echarts';
import SidePanelItem from '@/components/SidePanelItem/index.vue';
import { useJidiSelectEventStore } from '@/store/modules/jidiSelectEvent';
import { msstbprptGetKendoList, sdriverdaysGetKendoList } from '@/api/qxd';
import { useModelStore } from '@/store/modules/model';
import dayjs from 'dayjs';
// 定义组件名
defineOptions({
  name: 'qixidiliuliangbianhua'
});

// ==================== 选择器配置 ====================
const JidiSelectEventStore = useJidiSelectEventStore();
const baseid = ref('');
const modelStore = useModelStore();

// Loading 状态和数据状态
const loading = ref(false);
const hasData = ref(true); // 初始化为 true，因为 initChart 时会渲染
const select = ref({
  show: true,
  value: undefined,
  options: [],
  picker: undefined,
  format: undefined
});
// 日期选择器配置
const datetimePicker: any = ref({
  show: true,
  value: (() => {
    const now = new Date();
    const currentMonth = `${now.getFullYear()}-${String(
      now.getMonth() + 1
    ).padStart(2, '0')}`;
    const lastMonth = new Date(now.getFullYear(), now.getMonth() - 1, 1);
    const lastMonthStr = `${lastMonth.getFullYear()}-${String(
      lastMonth.getMonth() + 1
    ).padStart(2, '0')}`;
    return [lastMonthStr, currentMonth];
  })(),
  format: 'YY-MM',
  picker: 'month' as const,
  options: []
});

// ==================== 图表相关响应式数据 ====================
const chartRef = ref<HTMLElement | null>(null);
let chartInstance: echarts.ECharts | null = null;

// 图表数据（初始为空数组）
const echartsData = ref<any[]>([]);

// 图表配置引用（用于 legendselectchanged 时读取最新配置）
const echartOptionRef = ref<EChartsOption>({});

// ==================== 工具函数：omit ====================
const omit = (obj: any, key: string) => {
  const newObj = { ...obj };
  delete newObj[key];
  return newObj;
};

// ==================== 多Y轴动态布局算法 ====================
/**
 * 根据图例选中状态动态调整 Y 轴布局和 grid 边距
 * @param selected - 图例选中状态对象 { '系列名': boolean }
 * @param options - ECharts 配置对象
 *
 * 规则：
 * - 左侧最多 1 个 Y 轴（第一个可见系列）
 * - 右侧可以显示多个 Y 轴（其余可见系列）
 */
const yAxisShowDynamic = (selected: Record<string, boolean>, options: any) => {
  const allShow = options.yAxis?.filter((item: any) => item.show);
  const showCount = allShow?.length || 0;

  // 没有显示的Y轴
  if (showCount === 0) {
    return;
  }

  // 只有一个Y轴：统一置于左侧
  if (showCount === 1) {
    options.grid = omit(options.grid, 'right');
    options.grid.left = '60px';

    options.yAxis = options.yAxis.map((item: any) => {
      if (item.show) {
        return {
          ...item,
          position: 'left',
          offset: 0
        };
      }
      return item;
    });
    return;
  }

  // 两个及以上Y轴：左侧1个，右侧其余
  if (showCount >= 2) {
    let leftIndex = 0; // 左侧Y轴索引
    let rightIndex = 0; // 右侧Y轴计数

    options.yAxis = options.yAxis.map((item: any) => {
      if (!item.show) {
        return item;
      }

      // 第一个可见的Y轴放在左侧
      if (leftIndex === 0) {
        leftIndex++;
        options.grid = omit(options.grid, 'right');
        options.grid.left = '60px';

        return {
          ...item,
          position: 'left',
          offset: 0
        };
      } else {
        // 其余Y轴放在右侧
        rightIndex++;

        // 右侧有多个Y轴时，需要增加右边距并设置偏移
        if (rightIndex > 1) {
          options.grid.right = '100px';
          return {
            ...item,
            position: 'right',
            offset: 60
          };
        } else {
          options.grid.right = '60px';
          return {
            ...item,
            position: 'right',
            offset: 0
          };
        }
      }
    });
  }
};

// ==================== 图表初始化 ====================
const initChart = () => {
  if (!chartRef.value) {
    console.warn('图表容器未就绪');
    return;
  }

  // 初始化 ECharts 实例
  chartInstance = echarts.init(chartRef.value);

  // 监听图例选择变化事件
  chartInstance.on('legendselectchanged', (params: any) => {
    const { selected } = params;

    // ✅ 方案A：手动构建新配置对象，保留所有函数引用（包括formatter）
    const currentOptions = echartOptionRef.value as any;

    const options: any = {
      ...currentOptions,
      legend: {
        ...currentOptions.legend,
        selected: selected
      },
      yAxis: Array.isArray(currentOptions.yAxis)
        ? currentOptions.yAxis.map((item: any) => {
            let isShow = true;
            for (const key in selected) {
              if (key === item.name) {
                isShow = selected[key];
              }
            }
            return { ...item, show: isShow }; // ✅ 保留formatter等函数
          })
        : currentOptions.yAxis
    };

    // 触发布局调整
    yAxisShowDynamic(selected, options);

    // 完全替换模式更新配置
    chartInstance?.setOption(options, true);
    echartOptionRef.value = options;
  });

  // 监听数据点点击事件
  chartInstance.on('click', (params: any) => {
    // ✅ 判断是否点击的是数据点（series中的点）
    if (params.componentType === 'series') {
      modelStore.modalVisible = true;
      modelStore.params.sttp = 'fh_zq_point';
      modelStore.title = '水文监测';
      modelStore.params.stcd = select.value.value;
      modelStore.showStcdSelector = true;
      modelStore.stcdOptions = select.value.options;
      modelStore.filter.rangeTm = [
        dayjs(params.name).startOf('day').format('YYYY-MM-DD HH:mm:ss'),
        dayjs(params.name).endOf('day').format('YYYY-MM-DD HH:mm:ss')
      ];
    }
  });
};

// ==================== 图表配置生成 ====================
const updateChart = () => {
  if (!chartInstance) return;

  // ✅ 计算数据统计值（用于Y轴动态范围）
  const qValues = echartsData.value
    .map(item => item.q)
    .filter(v => v != null && !isNaN(v));
  const zValues = echartsData.value
    .map(item => item.z)
    .filter(v => v != null && !isNaN(v));
  const vValues = echartsData.value
    .map(item => item.v)
    .filter(v => v != null && !isNaN(v));

  const minQ = qValues.length > 0 ? Math.min(...qValues) : 0;
  const maxQ = qValues.length > 0 ? Math.max(...qValues) : 0;
  const minZ = zValues.length > 0 ? Math.min(...zValues) : 0;
  const maxZ = zValues.length > 0 ? Math.max(...zValues) : 0;
  const minV = vValues.length > 0 ? Math.min(...vValues) : 0;
  const maxV = vValues.length > 0 ? Math.max(...vValues) : 0;

  // ✅ 颜色和Y轴配置
  const Color = ['#9556a4', '#56c2e3', '#78c300'];

  const _legendData = ['流量(m³/s)', '水位(m)', '流速(m/s)'];

  const setting: EChartsOption = {
    // Tooltip 配置
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.5)',
      borderColor: 'transparent',
      textStyle: {
        color: '#ffffff'
      },
      valueFormatter: (value: any) => (value === undefined ? '-' : value),
      formatter: (params: any) => {
        let res = `${params[0].name}<br/>`;
        params.forEach((item: any) => {
          const seriesName = item.seriesName ?? '';
          const regx = /\(([^()]+?)\)/;
          const unit = seriesName.match(regx);

          if (item.value !== undefined && item.value !== null) {
            // ✅ 保留两位小数
            const formattedValue = Number(item.value).toFixed(2);
            res += `<span style="background: ${
              item.color
            }; height:10px; width: 10px; border-radius: 50%; display: inline-block; margin-right:10px;"></span>${
              item.seriesName
            } ${formattedValue}${unit?.[1] || ''}<br/>`;
          } else {
            res += `<span style="background: ${
              item.color
            }; height:10px; width: 10px; border-radius: 50%; display: inline-block; margin-right:10px;"></span>${
              item.seriesName
            } -${unit?.[1] || ''}<br/>`;
          }
        });
        return res;
      }
    },

    // ✅ 颜色配置：流量-紫色，水位-青色，流速-绿色
    color: Color,

    // 图例配置
    legend: {
      data: _legendData,
      selectedMode: 'multiple',
      top: 0,
      left: 'center',
      itemGap: 15,
      // 默认只选中"水温"，其他系列隐藏
      selected: {
        '流速(m/s)': false,
        '流量(m³/s)': true,
        '水位(m)': false
      }
    },
    axisPointer: {
      type: 'shadow',
      label: {
        show: false
      },
      shadowStyle: {
        color: 'rgba(84, 112, 198, 0.2)'
      }
    },
    // 网格配置 - 为三个Y轴预留空间
    grid: {
      left: '0px',
      right: '60px',
      bottom: '10%',
      top: '65px'
    },

    // 数据缩放配置
    dataZoom: {
      type: 'inside',
      start: 0,
      end: 100
    },

    // X轴配置
    xAxis: {
      type: 'category',
      data: echartsData.value.map(item => item.dt),
      boundaryGap: true,
      axisLabel: {
        show: true,
        // ✅ X轴标签显示策略：最多显示5个标签，强制显示首尾
        interval: (index: number) => {
          const total = echartsData.value.length;
          if (total <= 5) return true; // 数据少于等于5个，全部显示
          if (index === 0 || index === total - 1) return true; // 首尾必显

          // 中间标签均匀分布
          const step = Math.floor((total - 1) / 3); // 中间显示3个
          return index % step === 0;
        }
      },
      axisLine: {
        show: true
      },
      splitLine: {
        show: true,
        lineStyle: {
          type: 'solid',
          color: '#e0e0e0'
        }
      },
      axisPointer: {
        type: 'shadow',
        shadowStyle: {
          color: 'rgba(84, 112, 198, 0.2)'
        }
      }
    },

    // Y轴配置 - 三个独立Y轴（按期望顺序：流量、水位、流速）
    yAxis: [
      {
        type: 'value',
        name: '流量(m³/s)',
        position: 'left',
        offset: 0,
        show: true,
        // ✅ 动态范围：floor(min) ~ ceil(max)+5
        min: qValues.length > 0 ? Math.floor(minQ) : undefined,
        max: qValues.length > 0 ? Math.ceil(maxQ) : undefined,
        splitLine: {
          show: true,
          lineStyle: {
            type: 'solid',
            color: '#e0e0e0'
          }
        },
        axisTick: {
          show: true
        },
        axisLabel: {
          show: true,
          formatter: '{value}',
          color: '#9556a4'
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#6e7079',
            width: 2
          }
        },
        nameTextStyle: {
          color: '#9556a4',
          fontSize: 12
        }
      },
      {
        type: 'value',
        name: '水位(m)',
        position: 'left',
        offset: 60,
        show: false,
        // ✅ 动态范围：min-0.01 ~ max+0.04
        min: zValues.length > 0 ? minZ : undefined,
        max: zValues.length > 0 ? maxZ : undefined,
        splitLine: { show: false },
        axisTick: {
          show: true
        },
        axisLabel: {
          show: true,
          // ✅ Y轴刻度保留两位小数（使用函数形式）
          formatter: (value: any) => value.toFixed(2),
          color: '#56c2e3'
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#6e7079',
            width: 2
          }
        },
        nameTextStyle: {
          color: '#56c2e3',
          fontSize: 12
        }
      },
      {
        type: 'value',
        name: '流速(m/s)',
        position: 'right',
        offset: 0,
        show: false,
        // ✅ 动态范围：min-0.2 ~ max+0.5
        min: vValues.length > 0 ? minV - 0.02 : undefined,
        max: vValues.length > 0 ? maxV + 0.02 : undefined,
        splitLine: { show: false },
        axisTick: {
          show: true
        },
        axisLabel: {
          show: true,
          // ✅ Y轴刻度保留三位小数
          formatter: (value: any) => value.toFixed(3),
          color: '#78c300'
        },
        axisLine: {
          show: true,
          lineStyle: {
            color: '#6e7079',
            width: 2
          }
        },
        nameTextStyle: {
          color: '#78c300',
          fontSize: 12
        }
      }
    ],

    // 系列配置（按期望顺序：流量、水位、流速）
    series: [
      {
        name: '流量(m³/s)',
        data: echartsData.value.map(item => item.q),
        type: 'line',
        smooth: true,
        // connectNulls: true,
        symbolSize: 3,
        symbol: 'circle',
        itemStyle: {
          color: '#9556a4'
        },
        lineStyle: {
          width: 2
        },
        yAxisIndex: 0
      },
      {
        name: '水位(m)',
        data: echartsData.value.map(item => item.z),
        type: 'line',
        smooth: true,
        // connectNulls: true,
        symbolSize: 3,
        symbol: 'circle',
        itemStyle: {
          color: '#56c2e3'
        },
        lineStyle: {
          width: 2
        },
        yAxisIndex: 1
      },
      {
        name: '流速(m/s)',
        data: echartsData.value.map(item => item.v),
        type: 'line',
        smooth: true,
        // connectNulls: true,
        symbolSize: 3,
        symbol: 'circle',
        itemStyle: {
          color: '#78c300'
        },
        lineStyle: {
          width: 2
        },
        yAxisIndex: 2
      }
    ]
  };

  // 保存配置引用
  echartOptionRef.value = setting;

  // 完全替换模式更新图表
  chartInstance.setOption(setting, true);

  // ✅ 初始化时应用动态布局算法，确保只有流量Y轴显示
  yAxisShowDynamic(
    {
      '流量(m³/s)': true,
      '水位(m)': false,
      '流速(m/s)': false
    },
    setting
  );

  // 再次应用调整后的配置
  chartInstance.setOption(setting, true);
};

// ==================== 生命周期钩子 ====================
onMounted(async () => {
  // 双重等待机制：nextTick + setTimeout
  await nextTick();
  setTimeout(() => {
    initChart();
    updateChart();
  }, 50);
});

onUnmounted(() => {
  // 销毁图表实例，防止内存泄漏
  if (chartInstance) {
    chartInstance.dispose();
    chartInstance = null;
  }
});
//获取水温监测下拉框
const getselsectData = async () => {
  let params = {
    filter: {
      logic: 'and',
      filters: [
        baseid.value != 'all'
          ? {
              field: 'baseId',
              operator: 'eq',
              dataType: 'string',
              value: baseid.value
            }
          : null,
        {
          field: 'fhstcd',
          operator: 'isnotnull'
        },
        {
          logic: 'or',
          filters: [
            {
              field: 'sttpCode',
              operator: 'eq',
              dataType: 'string',
              value: 'ZQ'
            }
          ]
        }
      ].filter(Boolean)
    },
    select: ['stcd', 'stnm', 'fhstcd', 'fhstnm', 'sttpCode']
  };
  let res = await msstbprptGetKendoList(params);
  console.log(res);
  if (!res?.data?.data || res.data.data.length == 0) {
    select.value.value = '';
    select.value.options = [];
    return;
  }
  select.value.value = res.data.data[0].stcd;
  select.value.options = res.data.data.map((item: any) => {
    return {
      label: item.stnm,
      value: item.stcd
    };
  });
  // debugger
};
const convertDateRange = (dateRange: string[]) => {
  if (!dateRange || dateRange.length !== 2) {
    return null;
  }
  // debugger

  const [startStr, endStr] = dateRange;

  // 获取今天的日期（日部分）
  const today = new Date();
  const currentDay = today.getDate();

  // 解析开始日期 YY-MM
  const [startYearStr, startMonthStr] = startStr.split('-');
  const startYear = parseInt(startYearStr);
  const startMonth = parseInt(startMonthStr);
  const fullStartYear = startYear < 100 ? 2000 + startYear : startYear;

  // 解析结束日期 YY-MM
  const [endYearStr, endMonthStr] = endStr.split('-');
  const endYear = parseInt(endYearStr);
  const endMonth = parseInt(endMonthStr);
  const fullEndYear = endYear < 100 ? 2000 + endYear : endYear;

  // 开始日期：基于第一个值的年月 + 今天的日期 + 00:00:00
  // 需要处理月份天数边界问题（如今天是31号，但2月只有28天）
  const startMonthLastDay = new Date(fullStartYear, startMonth, 0).getDate();
  const actualStartDay = Math.min(currentDay, startMonthLastDay);
  const startDate = `${fullStartYear}-${String(startMonth).padStart(
    2,
    '0'
  )}-${String(actualStartDay).padStart(2, '0')} 00:00:00`;

  // 结束日期：基于第二个值的年月 + 今天的日期 + 23:59:59
  // 同样需要处理月份天数边界问题
  const endMonthLastDay = new Date(fullEndYear, endMonth, 0).getDate();
  const actualEndDay = Math.min(currentDay, endMonthLastDay);
  const endDate = `${fullEndYear}-${String(endMonth).padStart(2, '0')}-${String(
    actualEndDay
  ).padStart(2, '0')} 23:59:59`;

  return {
    startDate,
    endDate
  };
};

/**
 * 加载图表数据
 * @param startDate 开始日期 (格式: YYYY-MM-DD HH:mm:ss)
 * @param endDate 结束日期 (格式: YYYY-MM-DD HH:mm:ss)
 * @param stcd 测站代码
 */
const getChartData = async (
  startDate: string,
  endDate: string,
  stcd: string
) => {
  try {
    console.log('=== 开始加载图表数据 ===');
    console.log('请求参数:', { startDate, endDate, stcd });

    // 设置 loading 状态
    loading.value = true;
    hasData.value = false;

    const params = {
      filter: {
        logic: 'and',
        filters: [
          {
            field: 'DT',
            operator: 'gte',
            value: startDate
          },
          {
            field: 'DT',
            operator: 'lte',
            value: endDate
          },
          {
            field: 'stcd',
            operator: 'eq',
            dataType: 'string',
            value: stcd
          }
        ]
      },
      sort: [
        {
          field: 'dt',
          dir: 'asc'
        }
      ]
    };

    // 调用实际的API获取数据
    const res = await sdriverdaysGetKendoList(params);
    console.log('API返回结果:', res);

    let data = res?.data?.data || [];
    console.log('原始数据条数:', data.length);

    // 处理空数据情况
    if (!data || data.length === 0) {
      echartsData.value = [];
      hasData.value = false;
      await nextTick();
      updateChart();
      console.warn('未查询到水文数据');
      return;
    }

    // ✅ 数据预处理：验证字段存在性并转换类型
    const processedData = data
      .map(item => {
        // 验证必要字段
        if (!item.dt || typeof item.dt !== 'string') {
          console.warn('无效的日期数据:', item);
          return null;
        }

        // 确保数值类型
        const q = typeof item.q === 'number' ? item.q : parseFloat(item.q);
        const z = typeof item.z === 'number' ? item.z : parseFloat(item.z);
        const v = typeof item.v === 'number' ? item.v : parseFloat(item.v);

        if (isNaN(q) || isNaN(z) || isNaN(v)) {
          console.warn('无效的水文数据:', item);
          return null;
        }

        return {
          dt: item.dt.split(' ')[0], // 提取日期部分 "2026-05-03"
          v: v, // 确保数值类型
          q: q,
          z: z
        };
      })
      .filter(Boolean); // 过滤掉无效数据

    console.log('处理后数据条数:', processedData.length);
    console.log('处理后数据示例:', processedData[0]);

    // ✅ 更新响应式数据
    echartsData.value = processedData;

    // 判断是否有数据
    hasData.value = echartsData.value.length > 0;
    console.log('hasData 设置为:', hasData.value);

    // ✅ 刷新图表（确保DOM更新后执行）
    await nextTick();
    updateChart();
    console.log('图表已更新');
  } catch (error) {
    console.error('获取图表数据失败:', error);
    hasData.value = false;
  } finally {
    // 关闭 loading 状态
    await nextTick();
    console.log('关闭 loading 状态');
    loading.value = false;
  }
};

const handlePanelChange1 = async data => {
  console.log('=== 用户交互触发 ===');
  console.log('当前所有控件状态:', data);
  // scopeDate: ['26-05', '26-06']
  // select: "0836000011"
  if (data.scopeDate && data.scopeDate.length > 0 && data.select) {
    console.log('参数验证通过，开始加载数据');
    // 转换日期格式并加载数据
    const dateRange = convertDateRange(data.scopeDate);
    if (dateRange) {
      console.log('日期转换结果:', dateRange);
      await getChartData(dateRange.startDate, dateRange.endDate, data.select);
    } else {
      console.error('日期转换失败');
    }
  } else {
    loading.value = false;
    hasData.value = false;
    // 清空图表数据
    echartsData.value = [];
    // 更新图表显示空状态
    await nextTick();
    updateChart();
    console.warn('参数不完整:', {
      scopeDate: data.scopeDate,
      select: data.select
    });
  }
};
watch(
  () => JidiSelectEventStore.selectedItem,
  newVal => {
    baseid.value = newVal.wbsCode;
    getselsectData();
  },
  { deep: true, immediate: true }
);
</script>

<style lang="scss" scoped>
.chart-wrapper {
  width: 100%;
  height: 231px;
  min-height: 231px;
  position: relative;
  /* 为empty-overlay提供定位上下文 */

  .echarts-chart {
    width: 100% !important;
    height: 100% !important;
    min-width: 100%;
    min-height: 231px;
  }

  .empty-overlay {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background: rgba(255, 255, 255);
    z-index: 10;
  }
}
</style>
