import React, { useState, useEffect, useCallback, useRef } from "react";

// 导入Material-UI图标和组件
import ColorLensIcon from "@mui/icons-material/ColorLens";
import ApplyIcon from "@mui/icons-material/Check";
import ResetIcon from "@mui/icons-material/Refresh";
import {
  Select,
  MenuItem,
  FormControl,
  InputLabel,
  Slider,
  Typography,
  Button,
  TextField,
  Box,
  Checkbox,
  FormControlLabel,
} from "@mui/material";

// 导入OpenLayers样式相关模块
import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile";
import VectorTileSource from "ol/source/VectorTile";
import { useData, useMap } from "../MapComponent";

import { LegendStyleConfig } from "./StyleLegend";
import { FlatStyleLike } from "ol/style/flat";

import { calculateClassification } from "@utils/breaks_classification";
import { parseColor } from "@utils/parseColor";
import { VectorTile } from "ol";
import { useNotification } from "@refinedev/core";
import { config } from "@/config/config";

interface StyleConfig {
  property: string;
  classificationMethod: string; // 分类方法
  segments: number;
  minSize: number; // 最小点尺寸
  maxSize: number; // 最大点尺寸
  minStrokeWidth: number; // 最小线宽
  maxStrokeWidth: number; // 最大线宽
  fixedStrokeWidth: number; // 固定线宽
  colorType: string; // 颜色类型
  singlePaletteIndex: number;
  gradientPaletteIndex: number;
  rainbowPaletteIndex: number;
  showLabels: boolean;
  opacity: number;
  adjustWidthByProperty: boolean; // 是否根据属性调整线条宽度
  customBreaks?: number[]; // 自定义断点（用于 custom_breaks）
  customColors?: string[]; // 自定义颜色（用于 colorType="custom"）
}

// 图层样式状态接口
export interface LayerStyleState {
  layerId: string;
  layerName: string;
  styleConfig: StyleConfig;
  legendConfig: LegendStyleConfig;
  isActive: boolean;
}

// StyleEditorPanel 组件 Props 接口
interface StyleEditorPanelProps {
  layerStyleStates: LayerStyleState[];
  setLayerStyleStates: React.Dispatch<React.SetStateAction<LayerStyleState[]>>;
}

// 预设颜色方案
const SINGLE_COLOR_PALETTES = [
  {
    color: "rgba(51, 153, 204, 1)",
  },
  {
    color: "rgba(255, 138, 92, 1)",
  },
  {
    color: "rgba(204, 51, 51, 1)",
  },
  {
    color: "rgba(255, 235, 59, 1)",
  },
  {
    color: "rgba(44, 160, 44, 1)",
  },
  {
    color: "rgba(227, 119, 194, 1)",
  },
  {
    color: "rgba(148, 103, 189, 1)",
  },
];
const GRADIENT_PALETTES = [
  {
    name: "蓝-红",
    start: "rgba(51, 153, 204, 1)",
    end: "rgba(204, 51, 51, 1)",
  },
  {
    name: "黄-绿",
    start: "rgba(255, 235, 59, 1)",
    end: "rgba(44, 160, 44, 1)",
  },
  {
    name: "粉-紫",
    start: "rgba(227, 119, 194, 1)",
    end: "rgba(148, 103, 189, 1)",
  },
];
// 离散彩虹色系 - 提供高区分度的颜色
const RAINBOW_PALETTES = [
  {
    name: "正向彩虹",
    colors: [
      "rgba(255, 0, 0, 1)", // 红 #FF0000
      "rgba(255, 127, 0, 1)", // 橙 #FF7F00
      "rgba(255, 215, 0, 1)", // 金黄 #FFD700
      "rgba(199, 224, 0, 1)", // 黄绿 #C7E000
      "rgba(76, 175, 80, 1)", // 中绿 #4CAF50
      "rgba(0, 158, 115, 1)", // 青绿/翡翠 #009E73
      "rgba(0, 188, 212, 1)", // 青/青色 #00BCD4
      "rgba(33, 150, 243, 1)", // 天蓝 #2196F3
      "rgba(63, 81, 181, 1)", // 靛青 #3F51B5
      "rgba(142, 68, 173, 1)", // 紫 #8E44AD
    ],
  },
  {
    name: "反向彩虹",
    colors: [
      "rgba(142, 68, 173, 1)", // 紫 #8E44AD
      "rgba(63, 81, 181, 1)", // 靛青 #3F51B5
      "rgba(33, 150, 243, 1)", // 天蓝 #2196F3
      "rgba(0, 188, 212, 1)", // 青/青色 #00BCD4
      "rgba(0, 158, 115, 1)", // 青绿/翡翠 #009E73
      "rgba(76, 175, 80, 1)", // 中绿 #4CAF50
      "rgba(199, 224, 0, 1)", // 黄绿 #C7E000
      "rgba(255, 215, 0, 1)", // 金黄 #FFD700
      "rgba(255, 127, 0, 1)", // 橙 #FF7F00
      "rgba(255, 0, 0, 1)", // 红 #FF0000
    ],
  },
];

// 预设分类方法
const CLASSIFICATION_METHODS = [
  { name: "优雅分段", value: "pretty_breaks" },
  // 浏览器中实现Jenks算法性能较差，暂时移除
  // { name: "自然间断", value: "jenks_optimized" },
  { name: "自定义", value: "custom_breaks" },
];

const rgbaToHex = (rgba: string) => {
  try {
    const c = parseColor(rgba);
    const toHex = (n: number) => {
      const hex = Math.round(n).toString(16);
      return hex.length === 1 ? "0" + hex : hex;
    };
    return `#${toHex(c.r)}${toHex(c.g)}${toHex(c.b)}`;
  } catch (e) {
    return "#000000";
  }
};

const hexToRgba = (hex: string) => {
  const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
  return result
    ? `rgba(${parseInt(result[1], 16)}, ${parseInt(result[2], 16)}, ${parseInt(
        result[3],
        16
      )}, 1)`
    : "rgba(0, 0, 0, 1)";
};

const StyleEditorPanel: React.FC<StyleEditorPanelProps> = ({
  layerStyleStates,
  setLayerStyleStates,
}) => {
  const map = useMap();
  const data = useData();
  if (!data) {
    return <div>Loading...</div>; // 或其他占位符
  }
  const {
    currentJunctionCalData,
    currentPipeCalData,
    junctionText,
    pipeText,
    setShowJunctionTextLayer,
    setShowPipeTextLayer,
    setContourLayerAvailable,
    setWaterflowLayerAvailable,
    setJunctionText,
    setPipeText,
    deckLayer,
  } = data;

  const { open } = useNotification();

  const [applyJunctionStyle, setApplyJunctionStyle] = useState(false);
  const [applyPipeStyle, setApplyPipeStyle] = useState(false);
  const [styleUpdateTrigger, setStyleUpdateTrigger] = useState(0); // 用于触发样式更新的状态
  const prevStyleUpdateTriggerRef = useRef<number>(0);

  const [renderLayers, setRenderLayers] = useState<WebGLVectorTileLayer[]>([]);
  const [selectedRenderLayer, setSelectedRenderLayer] =
    useState<WebGLVectorTileLayer>();
  const [availableProperties, setAvailableProperties] = useState<
    { name: string; value: string }[]
  >([]);
  const [styleConfig, setStyleConfig] = useState<StyleConfig>({
    property: "",
    classificationMethod: "pretty_breaks",
    segments: 5,
    minSize: 4,
    maxSize: 12,
    minStrokeWidth: 2,
    maxStrokeWidth: 6,
    fixedStrokeWidth: 3,
    colorType: "single",
    singlePaletteIndex: 0,
    gradientPaletteIndex: 0,
    rainbowPaletteIndex: 0,
    showLabels: false,
    opacity: 0.9,
    adjustWidthByProperty: true,
    customBreaks: [],
    customColors: [],
  });

  // 根据分段数生成相应数量的渐进颜色
  const generateGradientColors = useCallback(
    (segments: number): string[] => {
      const { start, end } =
        GRADIENT_PALETTES[styleConfig.gradientPaletteIndex];
      const colors: string[] = [];
      const startColor = parseColor(start);
      const endColor = parseColor(end);

      for (let i = 0; i < segments; i++) {
        const ratio = segments > 1 ? i / (segments - 1) : 1;
        const r = Math.round(
          startColor.r + (endColor.r - startColor.r) * ratio
        );
        const g = Math.round(
          startColor.g + (endColor.g - startColor.g) * ratio
        );
        const b = Math.round(
          startColor.b + (endColor.b - startColor.b) * ratio
        );
        colors.push(`rgba(${r}, ${g}, ${b}, 1)`);
      }
      return colors;
    },
    [styleConfig.gradientPaletteIndex, parseColor]
  );

  // 根据分段数生成彩虹色
  const generateRainbowColors = useCallback(
    (segments: number): string[] => {
      const baseColors =
        RAINBOW_PALETTES[styleConfig.rainbowPaletteIndex].colors;
      // 严格按顺序返回 N 个颜色
      return Array.from(
        { length: segments },
        (_, i) => baseColors[i % baseColors.length]
      );
    },
    [styleConfig.rainbowPaletteIndex]
  );
  // 保存当前图层的样式状态
  const saveLayerStyle = useCallback(
    (layerId?: string, newLegendConfig?: LegendStyleConfig) => {
      if (!selectedRenderLayer || !styleConfig.property) {
        console.warn("无法保存样式：缺少必要的图层或样式配置");
        return;
      }
      if (!layerId) return; // 如果没有传入 layerId，则不保存
      // 如果没有传入图例配置，则创建一个默认的空配置
      const layerName =
        newLegendConfig?.layerName ||
        selectedRenderLayer.get("name") ||
        `图层${layerId}`;
      const property = availableProperties.find(
        (p) => p.value === styleConfig.property
      );
      let legendConfig: LegendStyleConfig = newLegendConfig || {
        layerId,
        layerName,
        property: property?.name || styleConfig.property,
        colors: [],
        type: selectedRenderLayer.get("type"),
        dimensions: [],
        breaks: [],
      };

      const newStyleState: LayerStyleState = {
        layerId,
        layerName,
        styleConfig: { ...styleConfig },
        legendConfig: { ...legendConfig },
        isActive: true,
      };
      setLayerStyleStates((prev) => {
        // 检查是否已存在该图层的样式状态
        const existingIndex = prev.findIndex(
          (state) => state.layerId === layerId
        );

        if (existingIndex !== -1) {
          // 更新已存在的状态
          const updated = [...prev];
          updated[existingIndex] = newStyleState;
          return updated;
        } else {
          // 添加新的状态
          return [...prev, newStyleState];
        }
      });
    },
    [selectedRenderLayer, styleConfig]
  );
  // 设置分类样式参数，触发样式应用
  const setStyleState = () => {
    if (!selectedRenderLayer) return;
    const layerId = selectedRenderLayer.get("value");
    const property = styleConfig.property;
    if (layerId !== undefined && property !== undefined) {
      // 验证自定义断点设置
      if (styleConfig.classificationMethod === "custom_breaks") {
        const expected = styleConfig.segments;
        const custom = styleConfig.customBreaks || [];
        if (
          custom.length !== expected ||
          custom.some((v) => v === undefined || v === null || isNaN(v))
        ) {
          open?.({
            type: "error",
            message: `请设置 ${expected} 个有效的自定义阈值（数字）`,
          });
          return;
        }
        if (custom.some((v) => v < 0)) {
          open?.({ type: "error", message: "自定义阈值必须大于等于 0" });
          return;
        }
        // 升序排序
        setStyleConfig((prev) => ({
          ...prev,
          customBreaks: (prev.customBreaks || [])
            .slice(0, expected)
            .sort((a, b) => a - b),
        }));
      }
      // 更新文字标签设置
      if (layerId === "junctions") {
        if (setJunctionText && setShowJunctionTextLayer) {
          setJunctionText(property);
          setShowJunctionTextLayer(styleConfig.showLabels);
          setApplyJunctionStyle(true);
          setContourLayerAvailable && setContourLayerAvailable(true);
          saveLayerStyle(layerId);
          open?.({
            type: "success",
            message: "节点图层样式设置成功，等待数据更新。",
          });
        }
      }
      if (layerId === "pipes") {
        if (setPipeText && setShowPipeTextLayer) {
          setPipeText(property);
          setShowPipeTextLayer(styleConfig.showLabels);
          setApplyPipeStyle(true);
          setWaterflowLayerAvailable && setWaterflowLayerAvailable(true);
          saveLayerStyle(layerId);
          open?.({
            type: "success",
            message: "管道图层样式设置成功，等待数据更新。",
          });
        }
      }
      // 触发样式更新
      setStyleUpdateTrigger((prev) => prev + 1);
    }
  };
  // 计算分类样式，并应用到对应图层
  const applyClassificationStyle = (
    layerType: "junctions" | "pipes",
    styleConfig: any
  ) => {
    if (
      layerType === "junctions" &&
      currentJunctionCalData &&
      currentJunctionCalData.length > 0
    ) {
      // 应用节点样式
      let junctionStyleConfigState = layerStyleStates.find(
        (s) => s.layerId === "junctions"
      );

      // 更新节点数据属性
      const segments = junctionStyleConfigState?.styleConfig.segments ?? 5;
      let breaks: number[] = [];
      if (
        junctionStyleConfigState?.styleConfig.classificationMethod ===
        "custom_breaks"
      ) {
        // 使用自定义断点（保证为 segments 个断点，按升序）
        const desired = segments;
        breaks = (
          junctionStyleConfigState?.styleConfig.customBreaks || []
        ).slice(0, desired);
        breaks.sort((a, b) => a - b);
        // 过滤出 >= 0
        breaks = breaks.filter((v) => v >= 0);
        // 如果不足则补齐最后一个值
        while (breaks.length < desired)
          breaks.push(breaks[breaks.length - 1] ?? 0);
      } else {
        const calc = calculateClassification(
          currentJunctionCalData.map((d) => d.value),
          segments,
          styleConfig.classificationMethod
        );
        breaks = calc;
      }
      if (breaks.length === 0) {
        console.warn("计算的 breaks 为空，无法应用样式");
        return;
      }
      // 计算最大最小值,判断是否包含并插入 breaks
      const data = currentJunctionCalData.map((d) => d.value);
      const min_val = Math.max(
        data.reduce((min, val) => Math.min(min, val), Infinity),
        0
      );
      const max_val = data.reduce((max, val) => Math.max(max, val), -Infinity);
      if (breaks.includes(min_val) === false) {
        breaks.push(min_val);
        breaks.sort((a, b) => a - b);
      }
      if (breaks.includes(max_val) === false) {
        breaks.push(max_val);
        breaks.sort((a, b) => a - b);
      }
      if (junctionStyleConfigState)
        applyLayerStyle(junctionStyleConfigState, breaks);
    } else if (
      layerType === "pipes" &&
      currentPipeCalData &&
      currentPipeCalData.length > 0
    ) {
      // 应用管道样式
      let pipeStyleConfigState = layerStyleStates.find(
        (s) => s.layerId === "pipes"
      );
      // 更新管道数据属性
      const segments = pipeStyleConfigState?.styleConfig.segments ?? 5;
      let breaks: number[] = [];
      if (
        pipeStyleConfigState?.styleConfig.classificationMethod ===
        "custom_breaks"
      ) {
        // 使用自定义断点（保证为 segments 个断点，按升序）
        const desired = segments;
        breaks = (pipeStyleConfigState?.styleConfig.customBreaks || []).slice(
          0,
          desired
        );
        breaks.sort((a, b) => a - b);
        breaks = breaks.filter((v) => v >= 0);
        while (breaks.length < desired)
          breaks.push(breaks[breaks.length - 1] ?? 0);
      } else {
        const calc = calculateClassification(
          currentPipeCalData.map((d) => d.value),
          segments,
          styleConfig.classificationMethod
        );
        breaks = calc;
      }
      if (breaks.length === 0) {
        console.warn("计算的 breaks 为空，无法应用样式");
        return;
      }
      // 计算最大最小值,判断是否包含并插入 breaks
      const data = currentPipeCalData.map((d) => d.value);
      const min_val = Math.max(
        data.reduce((min, val) => Math.min(min, val), Infinity),
        0
      );
      const max_val = data.reduce((max, val) => Math.max(max, val), -Infinity);
      if (breaks.includes(min_val) === false) {
        breaks.push(min_val);
        breaks.sort((a, b) => a - b);
      }
      if (breaks.includes(max_val) === false) {
        breaks.push(max_val);
        breaks.sort((a, b) => a - b);
      }
      if (pipeStyleConfigState) applyLayerStyle(pipeStyleConfigState, breaks);
    }
  };
  // 应用样式函数，传入 breaks 数据
  const applyLayerStyle = (
    layerStyleConfig: LayerStyleState,
    breaks?: number[]
  ) => {
    // 使用传入的 breaks 数据
    if (!breaks || breaks.length === 0) {
      console.warn("没有有效的 breaks 数据");
      return;
    }
    const styleConfig = layerStyleConfig.styleConfig;
    const renderLayer = renderLayers.filter((layer) => {
      return layer.get("value") === layerStyleConfig.layerId;
    })[0];
    if (!renderLayer || !styleConfig?.property) return;
    const layerType: string = renderLayer?.get("type");
    const source = renderLayer.getSource();
    if (!source) return;

    const breaksLength = breaks.length;
    // 根据 breaks 计算每个分段的颜色，线条粗细
    const colors: string[] =
      styleConfig.colorType === "single"
        ? // 单一色重复多次
          Array.from({ length: breaksLength }, () => {
            return SINGLE_COLOR_PALETTES[styleConfig.singlePaletteIndex].color;
          })
        : styleConfig.colorType === "gradient"
        ? generateGradientColors(breaksLength)
        : styleConfig.colorType === "rainbow"
        ? generateRainbowColors(breaksLength)
        : (() => {
            // 自定义颜色
            const custom = styleConfig.customColors || [];
            // 如果自定义颜色数量不足，用反向彩虹色填充
            const result = [...custom];
            const reverseRainbowColors = RAINBOW_PALETTES[1].colors;
            while (result.length < breaksLength) {
              result.push(
                reverseRainbowColors[
                  (result.length - custom.length) % reverseRainbowColors.length
                ]
              );
            }
            return result.slice(0, breaksLength);
          })();
    // 计算每个分段的线条粗细和点大小
    const dimensions: number[] =
      layerType === "linestring"
        ? styleConfig.adjustWidthByProperty
          ? Array.from({ length: breaksLength }, (_, i) => {
              const ratio = i / (breaksLength - 1);
              return (
                styleConfig.minStrokeWidth +
                (styleConfig.maxStrokeWidth - styleConfig.minStrokeWidth) *
                  ratio
              );
            })
          : Array.from(
              { length: breaksLength },
              () => styleConfig.fixedStrokeWidth
            ) // 使用固定宽度
        : Array.from({ length: breaksLength }, (_, i) => {
            const ratio = i / (breaksLength - 1);
            return (
              styleConfig.minSize +
              (styleConfig.maxSize - styleConfig.minSize) * ratio
            );
          });

    // 动态生成颜色条件表达式
    const generateColorConditions = (property: string): any[] => {
      const conditions: any[] = ["case"];
      for (let i = 1; i < breaks.length; i++) {
        // 添加条件：属性值 <= 当前断点
        conditions.push(["<=", ["get", property], breaks[i]]);
        // 添加对应的颜色值
        const colorObj = parseColor(colors[i - 1]);
        const color = `rgba(${colorObj.r}, ${colorObj.g}, ${colorObj.b}, ${styleConfig.opacity})`;
        conditions.push(color);
      }
      const colorObj = parseColor(colors[0]);
      const color = `rgba(${colorObj.r}, ${colorObj.g}, ${colorObj.b}, ${styleConfig.opacity})`;
      // 添加默认值（首个颜色）
      conditions.push(color);
      return conditions;
    };
    // 动态生成尺寸条件表达式
    const generateDimensionConditions = (property: string): any[] => {
      const conditions: any[] = ["case"];
      for (let i = 0; i < breaks.length; i++) {
        conditions.push(["<=", ["get", property], breaks[i]]);
        conditions.push(dimensions[i]);
      }
      conditions.push(dimensions[dimensions.length - 1]);
      return conditions;
    };
    const generateDimensionPointConditions = (property: string): any[] => {
      const conditions: any[] = ["case"];
      for (let i = 0; i < breaks.length; i++) {
        conditions.push(["<=", ["get", property], breaks[i]]);
        conditions.push([
          "interpolate",
          ["linear"],
          ["zoom"],
          12,
          1, // 使用配置的最小尺寸
          24,
          dimensions[i],
        ]);
      }
      conditions.push(dimensions[dimensions.length - 1]);
      return conditions;
    };
    // 创建基于 breaks 的动态 FlatStyle
    const dynamicStyle: FlatStyleLike = {};

    // 根据图层类型设置不同的样式属性
    if (layerType === "linestring") {
      dynamicStyle["stroke-color"] = generateColorConditions(
        styleConfig.property
      );
      dynamicStyle["stroke-width"] = generateDimensionConditions(
        styleConfig.property
      );
    } else if (layerType === "point") {
      dynamicStyle["circle-fill-color"] = generateColorConditions(
        styleConfig.property
      );
      dynamicStyle["circle-radius"] = generateDimensionPointConditions(
        styleConfig.property
      );
      dynamicStyle["circle-stroke-color"] = generateColorConditions(
        styleConfig.property
      );
      dynamicStyle["circle-stroke-width"] = 2;
    }

    renderLayer.setStyle(dynamicStyle);
    // 用初始化时的样式配置更新图例配置，避免覆盖已有的图例名称和属性
    const layerId = renderLayer.get("value");
    const initLayerStyleState = layerStyleStates.find(
      (s) => s.layerId === layerId
    );
    // 创建图例配置对象
    const legendConfig: LegendStyleConfig = {
      layerName: initLayerStyleState?.layerName || `图层${layerId}`,
      layerId: layerId,
      property: initLayerStyleState?.legendConfig.property || "",
      colors: colors,
      type: layerType,
      dimensions: dimensions,
      breaks: breaks,
    };
    // 自动保存样式状态，直接传入图例配置
    setTimeout(() => {
      saveLayerStyle(renderLayer.get("value"), legendConfig);
    }, 100);
  };
  // 重置样式
  const resetStyle = useCallback(() => {
    if (!selectedRenderLayer) return;
    // 重置 WebGL 图层样式
    const defaultFlatStyle: FlatStyleLike = config.MAP_DEFAULT_STYLE;
    selectedRenderLayer.setStyle(defaultFlatStyle);

    // 删除对应图层的样式状态，从而移除图例显示
    const layerId = selectedRenderLayer.get("value");
    if (layerId !== undefined) {
      setLayerStyleStates((prev) =>
        prev.filter((state) => state.layerId !== layerId)
      );
      // 重置样式应用状态
      if (layerId === "junctions") {
        setApplyJunctionStyle(false);
        if (setShowJunctionTextLayer) setShowJunctionTextLayer(false);
        if (setJunctionText) setJunctionText("");
        setContourLayerAvailable && setContourLayerAvailable(false);
      } else if (layerId === "pipes") {
        setApplyPipeStyle(false);
        if (setShowPipeTextLayer) setShowPipeTextLayer(false);
        if (setPipeText) setPipeText("");
        setWaterflowLayerAvailable && setWaterflowLayerAvailable(false);
      }
    }
  }, [selectedRenderLayer]);
  // 更新当前 VectorTileSource 中的所有缓冲要素属性
  const updateVectorTileSource = (property: string, data: any[]) => {
    if (!map) return;
    const vectorTileSources = map
      .getAllLayers()
      .filter((layer) => layer instanceof WebGLVectorTileLayer)
      .map((layer) => layer.getSource() as VectorTileSource)
      .filter((source) => source);

    if (!vectorTileSources.length) return;

    // 创建 id 到 value 的映射
    const dataMap = new Map<string, number>();
    data.forEach((d: any) => {
      dataMap.set(d.ID, d.value || 0);
    });

    // 直接遍历所有瓦片和要素，无需分批处理
    vectorTileSources.forEach((vectorTileSource) => {
      const sourceTiles = vectorTileSource.sourceTiles_;

      Object.values(sourceTiles).forEach((vectorTile) => {
        const renderFeatures = vectorTile.getFeatures();
        if (!renderFeatures || renderFeatures.length === 0) return;
        // 直接更新要素属性
        renderFeatures.forEach((renderFeature) => {
          const featureId = renderFeature.get("id");
          const value = dataMap.get(featureId);
          if (value !== undefined) {
            if (property === "flow") {
              // 特殊处理流量属性，取绝对值
              (renderFeature as any).properties_[property] = Math.abs(value);
            } else {
              (renderFeature as any).properties_[property] = value;
            }
          }
        });
      });
    });
  };
  // 新增事件，监听 VectorTileSource 的 tileloadend 事件，为新增瓦片数据动态更新要素属性
  const [tileLoadListeners, setTileLoadListeners] = useState<
    Map<VectorTileSource, (event: any) => void>
  >(new Map());

  const attachVectorTileSourceLoadedEvent = (
    layerId: string,
    property: string,
    data: any[]
  ) => {
    if (!map) return;
    const vectorTileSource = map
      .getAllLayers()
      .filter((layer) => layer.get("value") === layerId)
      .map((layer) => layer.getSource() as VectorTileSource)
      .filter((source) => source)[0];
    if (!vectorTileSource) return;
    // 创建 id 到 value 的映射
    const dataMap = new Map<string, number>();
    data.forEach((d: any) => {
      dataMap.set(d.ID, d.value || 0);
    });
    // 新增监听器并保存
    const newListeners = new Map<VectorTileSource, (event: any) => void>();

    const listener = (event: any) => {
      try {
        if (event.tile instanceof VectorTile) {
          const renderFeatures = event.tile.getFeatures();
          if (!renderFeatures || renderFeatures.length === 0) return;
          // 直接更新要素属性
          renderFeatures.forEach((renderFeature: any) => {
            const featureId = renderFeature.get("id");
            const value = dataMap.get(featureId);
            if (value !== undefined) {
              if (property === "flow") {
                // 特殊处理流量属性，取绝对值
                (renderFeature as any).properties_[property] = Math.abs(value);
              } else {
                (renderFeature as any).properties_[property] = value;
              }
            }
          });
        }
      } catch (error) {
        console.error("Error processing tile load event:", error);
      }
    };

    vectorTileSource.on("tileloadend", listener);
    newListeners.set(vectorTileSource, listener);
    setTileLoadListeners(newListeners);
  };
  // 新增函数：取消对应 layerId 已添加的 on 事件
  const removeVectorTileSourceLoadedEvent = (layerId: string) => {
    if (!map) return;
    const vectorTileSource = map
      .getAllLayers()
      .filter((layer) => layer.get("value") === layerId)
      .map((layer) => layer.getSource() as VectorTileSource)
      .filter((source) => source)[0];
    if (!vectorTileSource) return;
    const listener = tileLoadListeners.get(vectorTileSource);
    if (listener) {
      vectorTileSource.un("tileloadend", listener);
      setTileLoadListeners((prev) => {
        const newMap = new Map(prev);
        newMap.delete(vectorTileSource);
        return newMap;
      });
    }
  };

  // 监听数据变化，重新应用样式。由样式应用按钮触发，或由数据变化触发
  useEffect(() => {
    // 判断此次触发是否由用户点击“应用”按钮引起
    const isUserTrigger =
      styleUpdateTrigger !== prevStyleUpdateTriggerRef.current;
    // 更新 prevStyleUpdateTrigger
    prevStyleUpdateTriggerRef.current = styleUpdateTrigger;

    const updateJunctionStyle = () => {
      if (!currentJunctionCalData) return;
      const junctionStyleConfigState = layerStyleStates.find(
        (s) => s.layerId === "junctions"
      );
      // setStyle() 会清除渲染器缓存，这是闪烁的主要原因 WebGLVectorTile.js:114-118
      // 尝试考虑使用 updateStyleVariables() 更新
      applyClassificationStyle(
        "junctions",
        junctionStyleConfigState?.styleConfig
      );
      // 更新现有的 VectorTileSource
      updateVectorTileSource(junctionText, currentJunctionCalData);
      // 移除旧的监听器，并添加新的监听器
      removeVectorTileSourceLoadedEvent("junctions");
      attachVectorTileSourceLoadedEvent(
        "junctions",
        junctionText,
        currentJunctionCalData
      );
    };
    const updatePipeStyle = () => {
      if (!currentPipeCalData) return;
      const pipeStyleConfigState = layerStyleStates.find(
        (s) => s.layerId === "pipes"
      );
      applyClassificationStyle("pipes", pipeStyleConfigState?.styleConfig);
      // 更新现有的 VectorTileSource
      updateVectorTileSource(pipeText, currentPipeCalData);
      // 移除旧的监听器，并添加新的监听器
      removeVectorTileSourceLoadedEvent("pipes");
      attachVectorTileSourceLoadedEvent("pipes", pipeText, currentPipeCalData);
    };
    if (isUserTrigger) {
      if (selectedRenderLayer?.get("value") === "junctions") {
        updateJunctionStyle();
      } else if (selectedRenderLayer?.get("value") === "pipes") {
        updatePipeStyle();
      }
      return;
    }
    if (
      applyJunctionStyle &&
      currentJunctionCalData &&
      currentJunctionCalData.length > 0
    ) {
      updateJunctionStyle();
    }
    if (applyPipeStyle && currentPipeCalData && currentPipeCalData.length > 0) {
      updatePipeStyle();
    }
    if (!applyJunctionStyle) {
      removeVectorTileSourceLoadedEvent("junctions");
    }
    if (!applyPipeStyle) {
      removeVectorTileSourceLoadedEvent("pipes");
    }
  }, [
    styleUpdateTrigger,
    applyJunctionStyle,
    applyPipeStyle,
    currentJunctionCalData,
    currentPipeCalData,
  ]);

  // 获取地图中的矢量图层，用于选择图层选项
  useEffect(() => {
    if (!map) return;

    const updateVisibleLayers = () => {
      const layers = map.getAllLayers();
      // 筛选矢量瓦片图层
      const webGLVectorTileLayers = layers.filter(
        (layer) =>
          layer.get("value") === "junctions" || layer.get("value") === "pipes" // 暂时只处理这两个图层
      ) as WebGLVectorTileLayer[];

      setRenderLayers(webGLVectorTileLayers);
    };

    updateVisibleLayers();
  }, [map]);
  // 获取选中图层的属性，并检查是否有已缓存的样式状态
  useEffect(() => {
    // 如果没有矢量图层或没有选中图层，清空属性列表
    if (!renderLayers || renderLayers.length === 0) {
      setAvailableProperties([]);
      return;
    }
    // 如果没有选中图层，清空属性列表
    if (!selectedRenderLayer) {
      setAvailableProperties([]);
      return;
    }

    // 获取第一个要素的数值型属性
    const properties = selectedRenderLayer.get("properties") || {};
    setAvailableProperties(properties);

    // 设置选中的渲染图层
    const renderLayer = renderLayers.filter((layer) => {
      return layer.get("value") === selectedRenderLayer?.get("value");
    })[0];
    setSelectedRenderLayer(renderLayer);

    // 检查是否有已缓存的样式状态，如果有则自动恢复
    const layerId = selectedRenderLayer.get("value");
    const cachedStyleState = layerStyleStates.find(
      (state) => state.layerId === layerId
    );
    if (cachedStyleState) {
      setStyleConfig(cachedStyleState.styleConfig);
    }
  }, [renderLayers, selectedRenderLayer, map, renderLayers, layerStyleStates]);

  // 监听颜色类型变化，当切换到单一色时自动勾选宽度调整选项
  useEffect(() => {
    if (styleConfig.colorType === "single") {
      setStyleConfig((prev) => ({
        ...prev,
        adjustWidthByProperty: true,
      }));
    }
  }, [styleConfig.colorType]);

  // 初始化或调整自定义断点数组长度，默认使用 pretty_breaks 生成若存在数据
  useEffect(() => {
    if (styleConfig.classificationMethod !== "custom_breaks") return;

    const numBreaks = styleConfig.segments;
    setStyleConfig((prev) => {
      const prevBreaks = prev.customBreaks || [];
      if (prevBreaks.length === numBreaks) return prev;

      const selectedLayerId = selectedRenderLayer?.get("value");
      let dataArr: number[] = [];
      if (selectedLayerId === "junctions" && currentJunctionCalData)
        dataArr = currentJunctionCalData.map((d) => d.value);
      else if (selectedLayerId === "pipes" && currentPipeCalData)
        dataArr = currentPipeCalData.map((d) => d.value);

      let defaultBreaks: number[] = Array.from({ length: numBreaks }, () => 0);
      if (dataArr && dataArr.length > 0) {
        defaultBreaks = calculateClassification(
          dataArr,
          styleConfig.segments,
          "pretty_breaks"
        );
        defaultBreaks = defaultBreaks.slice(0, numBreaks);
        if (defaultBreaks.length < numBreaks)
          while (defaultBreaks.length < numBreaks)
            defaultBreaks.push(defaultBreaks[defaultBreaks.length - 1] ?? 0);
      }

      return { ...prev, customBreaks: defaultBreaks };
    });
  }, [
    styleConfig.classificationMethod,
    styleConfig.segments,
    selectedRenderLayer,
    currentJunctionCalData,
    currentPipeCalData,
  ]);

  // 初始化或调整自定义颜色数组长度
  useEffect(() => {
    const numColors = styleConfig.segments;
    setStyleConfig((prev) => {
      const prevColors = prev.customColors || [];
      if (prevColors.length === numColors) return prev;

      const newColors = [...prevColors];
      const baseColors = RAINBOW_PALETTES[0].colors;
      while (newColors.length < numColors) {
        newColors.push(baseColors[newColors.length % baseColors.length]);
      }
      return { ...prev, customColors: newColors.slice(0, numColors) };
    });
  }, [styleConfig.segments]);

  const getColorSetting = () => {
    if (styleConfig.colorType === "single") {
      return (
        <FormControl
          variant="standard"
          fullWidth
          margin="dense"
          className="mt-3"
        >
          <InputLabel>单一色方案</InputLabel>
          <Select
            value={styleConfig.singlePaletteIndex}
            onChange={(e) =>
              setStyleConfig((prev) => ({
                ...prev,
                singlePaletteIndex: Number(e.target.value),
              }))
            }
          >
            {SINGLE_COLOR_PALETTES.map((p, idx) => {
              return (
                <MenuItem key={idx} value={idx}>
                  <Box
                    width="100%"
                    sx={{ display: "flex", alignItems: "center" }}
                  >
                    <Box
                      key={idx}
                      sx={{
                        width: "80%",
                        height: 16,
                        borderRadius: 2,
                        background: p.color,
                        marginRight: 1,
                        border: "1px solid #ccc",
                      }}
                    />
                  </Box>
                </MenuItem>
              );
            })}
          </Select>
        </FormControl>
      );
    }
    if (styleConfig.colorType === "gradient") {
      return (
        <FormControl
          variant="standard"
          fullWidth
          margin="dense"
          className="mt-3"
        >
          <InputLabel>渐进色方案</InputLabel>
          <Select
            value={styleConfig.gradientPaletteIndex}
            onChange={(e) =>
              setStyleConfig((prev) => ({
                ...prev,
                gradientPaletteIndex: Number(e.target.value),
              }))
            }
          >
            {GRADIENT_PALETTES.map((p, idx) => {
              const numColors = styleConfig.segments + 1;
              const previewColors = Array.from(
                { length: numColors },
                (_, i) => {
                  const ratio = numColors > 1 ? i / (numColors - 1) : 1;
                  const startColor = parseColor(p.start);
                  const endColor = parseColor(p.end);
                  const r = Math.round(
                    startColor.r + (endColor.r - startColor.r) * ratio
                  );
                  const g = Math.round(
                    startColor.g + (endColor.g - startColor.g) * ratio
                  );
                  const b = Math.round(
                    startColor.b + (endColor.b - startColor.b) * ratio
                  );
                  return `rgba(${r}, ${g}, ${b}, 1)`;
                }
              );
              return (
                <MenuItem key={idx} value={idx}>
                  <Box
                    width="100%"
                    sx={{ display: "flex", alignItems: "center" }}
                  >
                    <Box
                      sx={{
                        width: "80%",
                        height: 16,
                        borderRadius: 2,
                        display: "flex",
                        overflow: "hidden",
                        marginRight: 1,
                        border: "1px solid #ccc",
                      }}
                    >
                      {previewColors.map((color, colorIdx) => (
                        <Box
                          key={colorIdx}
                          sx={{
                            flex: 1,
                            backgroundColor: color,
                          }}
                        />
                      ))}
                    </Box>
                  </Box>
                </MenuItem>
              );
            })}
          </Select>
        </FormControl>
      );
    }
    if (styleConfig.colorType === "rainbow") {
      return (
        <FormControl
          variant="standard"
          fullWidth
          margin="dense"
          className="mt-3"
        >
          <InputLabel>离散彩虹方案</InputLabel>
          <Select
            value={styleConfig.rainbowPaletteIndex}
            onChange={(e) =>
              setStyleConfig((prev) => ({
                ...prev,
                rainbowPaletteIndex: Number(e.target.value),
              }))
            }
          >
            {RAINBOW_PALETTES.map((p, idx) => {
              // 根据当前分段数+1生成该方案的预览颜色
              const baseColors = p.colors;
              const numColors = styleConfig.segments + 1;
              const previewColors = Array.from(
                { length: numColors },
                (_, i) => baseColors[i % baseColors.length]
              );

              return (
                <MenuItem key={idx} value={idx}>
                  <Box
                    width="100%"
                    sx={{ display: "flex", alignItems: "center" }}
                  >
                    <Typography sx={{ marginRight: 1 }}>{p.name}</Typography>
                    <Box
                      sx={{
                        width: "60%",
                        height: 16,
                        borderRadius: 2,
                        display: "flex",
                        border: "1px solid #ccc",
                        overflow: "hidden",
                      }}
                    >
                      {previewColors.map((color, colorIdx) => (
                        <Box
                          key={colorIdx}
                          sx={{
                            flex: 1,
                            backgroundColor: color,
                          }}
                        />
                      ))}
                    </Box>
                  </Box>
                </MenuItem>
              );
            })}
          </Select>
        </FormControl>
      );
    }
    if (styleConfig.colorType === "custom") {
      return (
        <Box className="mt-3">
          <Typography variant="subtitle2" gutterBottom>
            自定义颜色
          </Typography>
          <Box
            className="flex flex-col gap-2"
            sx={{ maxHeight: "160px", overflowY: "auto", paddingTop: "4px" }}
          >
            {Array.from({ length: styleConfig.segments }).map((_, idx) => {
              const color =
                (styleConfig.customColors && styleConfig.customColors[idx]) ||
                "rgba(0,0,0,1)";
              return (
                <Box key={idx} className="flex items-center gap-2">
                  <Typography variant="caption" sx={{ width: 40 }}>
                    分段{idx + 1}
                  </Typography>
                  <input
                    type="color"
                    value={rgbaToHex(color)}
                    onChange={(e) => {
                      const hex = e.target.value;
                      const newColor = hexToRgba(hex);
                      setStyleConfig((prev) => {
                        const newColors = [...(prev.customColors || [])];
                        while (newColors.length < styleConfig.segments)
                          newColors.push("rgba(0,0,0,1)");
                        newColors[idx] = newColor;
                        return { ...prev, customColors: newColors };
                      });
                    }}
                    style={{
                      width: "100%",
                      height: "32px",
                      cursor: "pointer",
                      border: "1px solid #ccc",
                      borderRadius: "4px",
                    }}
                  />
                </Box>
              );
            })}
          </Box>
        </Box>
      );
    }
  };
  // 根据不同图层的类型和颜色分类方案显示不同的大小设置
  const getSizeSetting = () => {
    let colors: string[] = [];
    if (styleConfig.colorType === "single") {
      const color = SINGLE_COLOR_PALETTES[styleConfig.singlePaletteIndex].color;
      colors = [color, color];
    } else if (styleConfig.colorType === "gradient") {
      const { start, end } =
        GRADIENT_PALETTES[styleConfig.gradientPaletteIndex];
      colors = [start, end];
    } else if (styleConfig.colorType === "rainbow") {
      const rainbowColors =
        RAINBOW_PALETTES[styleConfig.rainbowPaletteIndex].colors;
      colors = [rainbowColors[0], rainbowColors[rainbowColors.length - 1]];
    } else if (styleConfig.colorType === "custom") {
      const customColors = styleConfig.customColors || [];
      colors = [
        customColors[0] || "rgba(0,0,0,1)",
        customColors[customColors.length - 1] || "rgba(0,0,0,1)",
      ];
    }

    if (selectedRenderLayer?.get("type") === "point") {
      return (
        <Box className="mt-3">
          <Typography gutterBottom>
            点大小范围: {styleConfig.minSize} - {styleConfig.maxSize} 像素
          </Typography>
          <Box className="flex items-center gap-4">
            <Box className="flex-1">
              <Typography variant="caption" gutterBottom>
                最小值
              </Typography>
              <Slider
                value={styleConfig.minSize}
                onChange={(_, value) =>
                  setStyleConfig((prev) => ({
                    ...prev,
                    minSize: value as number,
                  }))
                }
                min={2}
                max={8}
                step={1}
                size="small"
              />
            </Box>
            <Box className="flex-1">
              <Typography variant="caption" gutterBottom>
                最大值
              </Typography>
              <Slider
                value={styleConfig.maxSize}
                onChange={(_, value) =>
                  setStyleConfig((prev) => ({
                    ...prev,
                    maxSize: value as number,
                  }))
                }
                min={10}
                max={16}
                step={1}
                size="small"
              />
            </Box>
          </Box>
          {/* 点大小预览 */}
          <Box className="flex items-center gap-2 mt-2 p-2 bg-gray-50 rounded">
            <Typography variant="caption">预览:</Typography>
            <Box
              sx={{
                width: styleConfig.minSize,
                height: styleConfig.minSize,
                borderRadius: "50%",
                backgroundColor: colors[0],
              }}
            />
            <Typography variant="caption">到</Typography>
            <Box
              sx={{
                width: styleConfig.maxSize,
                height: styleConfig.maxSize,
                borderRadius: "50%",
                backgroundColor: colors[colors.length - 1],
              }}
            />
          </Box>
        </Box>
      );
    }
    if (selectedRenderLayer?.get("type") === "linestring") {
      return (
        <Box className="mt-3">
          {/* 勾选项：是否根据属性调整线条宽度 */}
          <FormControlLabel
            control={
              <Checkbox
                checked={styleConfig.adjustWidthByProperty}
                onChange={(e) =>
                  setStyleConfig((prev) => ({
                    ...prev,
                    adjustWidthByProperty: e.target.checked,
                  }))
                }
                disabled={styleConfig.colorType === "single"}
              />
            }
            label="根据数值分段调整线条宽度"
          />
          {styleConfig.adjustWidthByProperty && (
            <>
              <Typography gutterBottom>
                线条宽度范围: {styleConfig.minStrokeWidth} -{" "}
                {styleConfig.maxStrokeWidth}px
              </Typography>
              <Box className="flex items-center gap-4">
                <Box className="flex-1">
                  <Typography variant="caption" gutterBottom>
                    最小值
                  </Typography>
                  <Slider
                    value={styleConfig.minStrokeWidth}
                    onChange={(_, value) =>
                      setStyleConfig((prev) => ({
                        ...prev,
                        minStrokeWidth: value as number,
                      }))
                    }
                    min={1}
                    max={4}
                    step={0.5}
                    size="small"
                  />
                </Box>
                <Box className="flex-1">
                  <Typography variant="caption" gutterBottom>
                    最大值
                  </Typography>
                  <Slider
                    value={styleConfig.maxStrokeWidth}
                    onChange={(_, value) =>
                      setStyleConfig((prev) => ({
                        ...prev,
                        maxStrokeWidth: value as number,
                      }))
                    }
                    min={6}
                    max={12}
                    step={0.5}
                    size="small"
                  />
                </Box>
              </Box>
              {/* 线条宽度预览 */}
              <Box className="flex items-center gap-2 mt-2 p-2 bg-gray-50 rounded">
                <Typography variant="caption">预览:</Typography>
                <Box
                  sx={{
                    width: 50,
                    height: styleConfig.minStrokeWidth,
                    backgroundColor: colors[0],
                    border: `1px solid ${colors[0]}`,
                    borderRadius: 1,
                  }}
                />
                <Typography variant="caption">到</Typography>
                <Box
                  sx={{
                    width: 50,
                    height: styleConfig.maxStrokeWidth,
                    backgroundColor: colors[colors.length - 1],
                    border: `1px solid ${colors[colors.length - 1]}`,
                    borderRadius: 1,
                  }}
                />
              </Box>
            </>
          )}
          {!styleConfig.adjustWidthByProperty && (
            <>
              <Typography gutterBottom>
                固定线条宽度: {styleConfig.fixedStrokeWidth}px
              </Typography>
              <Slider
                value={styleConfig.fixedStrokeWidth}
                onChange={(_, value) =>
                  setStyleConfig((prev) => ({
                    ...prev,
                    fixedStrokeWidth: value as number,
                  }))
                }
                min={1}
                max={10}
                step={0.5}
                size="small"
              />
              {/* 固定宽度预览 */}
              <Box className="flex items-center gap-2 mt-2 p-2 bg-gray-50 rounded">
                <Typography variant="caption">预览:</Typography>
                <Box
                  sx={{
                    width: 50,
                    height: styleConfig.fixedStrokeWidth,
                    backgroundColor: colors[0],
                    border: `1px solid ${colors[0]}`,
                    borderRadius: 1,
                  }}
                />
              </Box>
            </>
          )}
        </Box>
      );
    }
  };

  return (
    <>
      <div className="absolute top-20 left-4 bg-white p-4 rounded-xl shadow-lg opacity-95 hover:opacity-100 transition-opacity w-80 z-10">
        {/* 图层选择 */}
        <FormControl variant="standard" fullWidth margin="dense">
          <InputLabel>选择图层</InputLabel>
          <Select
            value={
              selectedRenderLayer
                ? renderLayers.indexOf(selectedRenderLayer)
                : ""
            }
            onChange={(e) => {
              const index = e.target.value as number;
              const newLayer = index >= 0 ? renderLayers[index] : undefined;
              setSelectedRenderLayer(newLayer);

              // 检查新图层是否有缓存的样式,没有才清空
              if (newLayer) {
                const layerId = newLayer.get("value");
                const cachedStyleState = layerStyleStates.find(
                  (state) => state.layerId === layerId
                );
                // 只有在没有缓存时才清空属性
                if (!cachedStyleState) {
                  setStyleConfig((prev) => ({ ...prev, property: "" }));
                }
              }
            }}
          >
            {renderLayers.map((layer, index) => {
              const name = layer.get("name");
              return (
                <MenuItem key={index} value={index}>
                  {name}
                </MenuItem>
              );
            })}
          </Select>
        </FormControl>
        {/* 属性选择 */}
        <FormControl variant="standard" fullWidth margin="dense">
          <InputLabel>分级属性</InputLabel>
          <Select
            value={styleConfig.property}
            onChange={(e) => {
              setStyleConfig((prev) => ({ ...prev, property: e.target.value }));
            }}
            disabled={!selectedRenderLayer}
          >
            {availableProperties.map((prop) => (
              <MenuItem key={prop.name} value={prop.value}>
                {prop.name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
        {/* 分类选择 */}
        <FormControl variant="standard" fullWidth margin="dense">
          <InputLabel>分类方法</InputLabel>
          <Select
            value={styleConfig.classificationMethod}
            onChange={(e) => {
              setStyleConfig((prev) => ({
                ...prev,
                classificationMethod: e.target.value,
              }));
            }}
          >
            {CLASSIFICATION_METHODS.map((method) => (
              <MenuItem key={method.value} value={method.value}>
                {method.name}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
        {/* 分类数量 */}
        <Box className="mt-3">
          <Typography gutterBottom>分类数量: {styleConfig.segments}</Typography>
          <Slider
            value={styleConfig.segments}
            onChange={(_, value) =>
              setStyleConfig((prev) => {
                const newSegments = value as number;
                const newCustomColors = [...(prev.customColors || [])];
                if (newSegments > newCustomColors.length) {
                  const baseColors = RAINBOW_PALETTES[0].colors;
                  for (let i = newCustomColors.length; i < newSegments; i++) {
                    newCustomColors.push(baseColors[i % baseColors.length]);
                  }
                }
                return {
                  ...prev,
                  segments: newSegments,
                  customColors: newCustomColors,
                };
              })
            }
            min={2}
            max={10}
            step={1}
            marks
            size="small"
          />
        </Box>
        {/* 自定义分类：手动填写区间分段（仅当选择自定义方式时显示） */}
        {styleConfig.classificationMethod === "custom_breaks" && (
          <Box className="mt-3 p-2 bg-gray-50 rounded">
            <Typography variant="subtitle2" gutterBottom>
              手动设置区间阈值（按升序填写，最小值 {">="} 0）
            </Typography>
            <Box
              className="flex flex-col gap-2"
              sx={{ maxHeight: "160px", overflowY: "auto", paddingTop: "12px" }}
            >
              {Array.from({ length: styleConfig.segments }).map((_, idx) => (
                <TextField
                  key={idx}
                  label={`阈值 ${idx + 1}`}
                  type="number"
                  size="small"
                  slotProps={{ input: { inputProps: { min: 0, step: 0.1 } } }}
                  value={
                    (styleConfig.customBreaks &&
                      styleConfig.customBreaks[idx]) ??
                    ""
                  }
                  onChange={(e) => {
                    const v = parseFloat(e.target.value);
                    setStyleConfig((prev) => {
                      const prevBreaks = prev.customBreaks
                        ? [...prev.customBreaks]
                        : [];
                      // 保证长度
                      while (prevBreaks.length < styleConfig.segments)
                        prevBreaks.push(0);
                      prevBreaks[idx] = isNaN(v) ? 0 : Math.max(0, v);
                      return { ...prev, customBreaks: prevBreaks };
                    });
                  }}
                  onBlur={() => {
                    // on blur 保证升序
                    setStyleConfig((prev) => {
                      const prevBreaks = (prev.customBreaks || []).slice(
                        0,
                        styleConfig.segments + 1
                      );
                      prevBreaks.sort((a, b) => a - b);
                      return { ...prev, customBreaks: prevBreaks };
                    });
                  }}
                />
              ))}
            </Box>
          </Box>
        )}
        {/* 颜色方案 */}
        <FormControl variant="standard" fullWidth margin="dense">
          <InputLabel>
            <ColorLensIcon className="mr-1" />
            颜色方案
          </InputLabel>
          <Select
            value={styleConfig.colorType}
            onChange={(e) => {
              const newColorType = e.target.value;
              setStyleConfig((prev) => {
                let newCustomColors = prev.customColors;
                if (
                  newColorType === "custom" &&
                  (!prev.customColors || prev.customColors.length === 0)
                ) {
                  const baseColors = RAINBOW_PALETTES[0].colors;
                  newCustomColors = Array.from(
                    { length: prev.segments },
                    (_, i) => baseColors[i % baseColors.length]
                  );
                }
                return {
                  ...prev,
                  colorType: newColorType,
                  customColors: newCustomColors,
                };
              });
            }}
          >
            <MenuItem value="single">单一色</MenuItem>
            <MenuItem value="gradient">渐进色</MenuItem>
            <MenuItem value="rainbow">离散彩虹</MenuItem>
            <MenuItem value="custom">自定义</MenuItem>
          </Select>
          {getColorSetting()}
        </FormControl>

        {/* 大小设置 */}
        {getSizeSetting()}

        {/* 透明度设置 */}
        <Box className="mt-3">
          <Typography gutterBottom>
            透明度: {(styleConfig.opacity * 100).toFixed(0)}%
          </Typography>
          <Slider
            value={styleConfig.opacity}
            onChange={(_, value) =>
              setStyleConfig((prev) => ({
                ...prev,
                opacity: value as number,
              }))
            }
            min={0.1}
            max={1}
            step={0.05}
            size="small"
          />
        </Box>

        {/* 是否显示属性文字 */}
        <FormControlLabel
          control={
            <Checkbox
              checked={styleConfig.showLabels}
              onChange={(e) =>
                setStyleConfig((prev) => ({
                  ...prev,
                  showLabels: e.target.checked,
                }))
              }
            />
          }
          label="显示属性（缩放 >=15 级时显示）"
        />
        <div className="my-3"></div>
        {/* 操作按钮 */}
        <Box className="flex gap-2">
          <Button
            variant="contained"
            color="primary"
            onClick={() => {
              setStyleState();
            }}
            disabled={!selectedRenderLayer || !styleConfig.property}
            startIcon={<ApplyIcon />}
            fullWidth
          >
            应用
          </Button>
          <Button
            variant="outlined"
            onClick={() => {
              resetStyle();
            }}
            disabled={!selectedRenderLayer}
            startIcon={<ResetIcon />}
            fullWidth
          >
            重置
          </Button>
        </Box>
      </div>
    </>
  );
};

export default StyleEditorPanel;
