"use client";
import { config } from "@/config/config";
import React, {
  createContext,
  useContext,
  useState,
  useEffect,
  useRef,
} from "react";
import { Map as OlMap, VectorTile } from "ol";
import View from "ol/View.js";
import "ol/ol.css";
import MapTools from "./MapTools";

import { Layer } from "ol/layer"; // 保留导入，但用于继承
import VectorTileSource from "ol/source/VectorTile";
import WebGLVectorTileLayer from "ol/layer/WebGLVectorTile";
import MVT from "ol/format/MVT";
import { FlatStyleLike } from "ol/style/flat";
import { toLonLat } from "ol/proj";
import { along, bearing, lineString, length, toMercator } from "@turf/turf";
import { Deck } from "@deck.gl/core";
import { TextLayer } from "@deck.gl/layers";
import { TripsLayer } from "@deck.gl/geo-layers";
import { CollisionFilterExtension } from "@deck.gl/extensions";
import VectorSource from "ol/source/Vector";
import GeoJson from "ol/format/GeoJSON";
import VectorLayer from "ol/layer/Vector";
import { Icon, Style } from "ol/style.js";
import { FeatureLike } from "ol/Feature";
import { Point } from "ol/geom";

interface MapComponentProps {
  children?: React.ReactNode;
}
interface DataContextType {
  currentTime?: number; // 当前时间
  setCurrentTime?: React.Dispatch<React.SetStateAction<number>>;
  selectedDate?: Date; // 选择的日期
  schemeName?: string; // 当前方案名称
  setSchemeName?: React.Dispatch<React.SetStateAction<string>>;
  setSelectedDate?: React.Dispatch<React.SetStateAction<Date>>;
  currentJunctionCalData?: any[]; // 当前计算结果
  setCurrentJunctionCalData?: React.Dispatch<React.SetStateAction<any[]>>;
  currentPipeCalData?: any[]; // 当前计算结果
  setCurrentPipeCalData?: React.Dispatch<React.SetStateAction<any[]>>;
  showJunctionText?: boolean; // 是否显示节点文本
  showPipeText?: boolean; // 是否显示管道文本
  setShowJunctionText?: React.Dispatch<React.SetStateAction<boolean>>;
  setShowPipeText?: React.Dispatch<React.SetStateAction<boolean>>;
  junctionText: string;
  pipeText: string;
  setJunctionText?: React.Dispatch<React.SetStateAction<string>>;
  setPipeText?: React.Dispatch<React.SetStateAction<string>>;
  scadaData?: any[]; // SCADA 数据
}

// 创建自定义Layer类来包装deck.gl
class DeckLayer extends Layer {
  private deck: Deck;

  constructor(deckInstance: Deck) {
    super({});
    this.deck = deckInstance;
  }

  render(frameState: any): HTMLElement {
    const { size, viewState } = frameState;
    const [width, height] = size;
    const [longitude, latitude] = toLonLat(viewState.center);
    const zoom = viewState.zoom - 1; // 调整 zoom 以匹配
    const bearing = (-viewState.rotation * 180) / Math.PI;
    const deckViewState = { bearing, longitude, latitude, zoom };
    this.deck.setProps({ width, height, viewState: deckViewState });
    this.deck.redraw();
    // 返回deck.gl的canvas元素
    return document.getElementById("deck-canvas") as HTMLElement;
  }
}
// 跨组件传递
const MapContext = createContext<OlMap | undefined>(undefined);
const DataContext = createContext<DataContextType | undefined>(undefined);

const extent = config.mapExtent;
const mapUrl = config.mapUrl;

// 添加防抖函数
function debounce<F extends (...args: any[]) => any>(func: F, waitFor: number) {
  let timeout: ReturnType<typeof setTimeout> | null = null;

  return (...args: Parameters<F>): void => {
    if (timeout !== null) {
      clearTimeout(timeout);
    }
    timeout = setTimeout(() => func(...args), waitFor);
  };
}

export const useMap = () => {
  return useContext(MapContext);
};
export const useData = () => {
  return useContext(DataContext);
};

const MapComponent: React.FC<MapComponentProps> = ({ children }) => {
  const mapRef = useRef<HTMLDivElement | null>(null);
  const deckRef = useRef<Deck | null>(null);

  const [map, setMap] = useState<OlMap>();
  // currentCalData 用于存储当前计算结果
  const [currentTime, setCurrentTime] = useState<number>(-1); // 默认选择当前时间
  // const [selectedDate, setSelectedDate] = useState<Date>(new Date("2025-9-17"));
  const [selectedDate, setSelectedDate] = useState<Date>(new Date()); // 默认今天
  const [schemeName, setSchemeName] = useState<string>(""); // 当前方案名称

  const [currentJunctionCalData, setCurrentJunctionCalData] = useState<any[]>(
    []
  );
  const [currentPipeCalData, setCurrentPipeCalData] = useState<any[]>([]);
  // junctionData 和 pipeData 分别缓存瓦片解析后节点和管道的数据，用于 deck.gl 定位、标签渲染
  const [junctionData, setJunctionDataState] = useState<any[]>([]);
  const [pipeData, setPipeDataState] = useState<any[]>([]);
  const junctionDataIds = useRef(new Set<string>());
  const pipeDataIds = useRef(new Set<string>());
  const tileJunctionDataBuffer = useRef<any[]>([]);
  const tilePipeDataBuffer = useRef<any[]>([]);

  const [showJunctionText, setShowJunctionText] = useState(false); // 控制节点文本显示
  const [showPipeText, setShowPipeText] = useState(false); // 控制管道文本显示
  const [showJunctionTextLayer, setShowJunctionTextLayer] = useState(true); // 控制节点文本图层显示
  const [showPipeTextLayer, setShowPipeTextLayer] = useState(true); // 控制管道文本图层显示
  const [junctionText, setJunctionText] = useState("pressure");
  const [pipeText, setPipeText] = useState("flow");
  const flowAnimation = useRef(false); // 添加动画控制标志
  const [currentZoom, setCurrentZoom] = useState(12); // 当前缩放级别

  // 防抖更新函数
  const debouncedUpdateData = useRef(
    debounce(() => {
      if (tileJunctionDataBuffer.current.length > 0) {
        setJunctionData(tileJunctionDataBuffer.current);
        tileJunctionDataBuffer.current = [];
      }
      if (tilePipeDataBuffer.current.length > 0) {
        setPipeData(tilePipeDataBuffer.current);
        tilePipeDataBuffer.current = [];
      }
    }, 100)
  );

  const setJunctionData = (newData: any[]) => {
    const uniqueNewData = newData.filter((item) => {
      if (!item || !item.id) return false;
      if (!junctionDataIds.current.has(item.id)) {
        junctionDataIds.current.add(item.id);
        return true;
      }
      return false;
    });
    if (uniqueNewData.length > 0) {
      setJunctionDataState((prev) => [...prev, ...uniqueNewData]);
    }
  };
  const setPipeData = (newData: any[]) => {
    const uniqueNewData = newData.filter((item) => {
      if (!item || !item.id) return false;
      if (!pipeDataIds.current.has(item.id)) {
        pipeDataIds.current.add(item.id);
        return true;
      }
      return false;
    });
    if (uniqueNewData.length > 0) {
      setPipeDataState((prev) => [...prev, ...uniqueNewData]);
    }
  };
  // 配置地图数据源、图层和样式
  const defaultFlatStyle: FlatStyleLike = config.mapDefaultStyle;
  // 定义 SCADA 图层的样式函数，根据 type 字段选择不同图标
  const scadaStyle = (feature: any) => {
    const type = feature.get("type");
    const scadaPressureIcon = "/icons/scada_pressure.svg";
    const scadaFlowIcon = "/icons/scada_flow.svg";
    // 如果 type 不匹配，可以设置默认图标或不显示
    return new Style({
      image: new Icon({
        src: type === "pipe_flow" ? scadaFlowIcon : scadaPressureIcon,
        scale: 0.1, // 根据需要调整图标大小
        anchor: [0.5, 0.5], // 图标锚点居中
      }),
    });
  };
  // 定义 reservoirs 图层的样式函数，使用固定图标
  const reservoirsStyle = () => {
    const reserviorIcon = "/icons/reservior.svg";
    return new Style({
      image: new Icon({
        src: reserviorIcon,
        scale: 0.1, // 根据需要调整图标大小
        anchor: [0.5, 0.5], // 图标锚点居中
      }),
    });
  };
  // 定义 valves 图层的样式函数，使用固定图标
  const valvesStyle = function (feature: FeatureLike) {
    const styles = [];
    const valveIcon = "/icons/valve.svg";

    const geometry = feature.getGeometry();
    const lineCoords =
      geometry?.getType() === "LineString"
        ? (geometry as any).getCoordinates()
        : null;
    if (geometry) {
      const lineCoordsWGS84 = lineCoords.map((coord: []) => {
        const [lon, lat] = toLonLat(coord);
        return [lon, lat];
      });
      // 计算中点
      const lineStringFeature = lineString(lineCoordsWGS84);
      const lineLength = length(lineStringFeature);
      const midPoint = along(lineStringFeature, lineLength / 2).geometry
        .coordinates;
      // 在中点添加 icon 样式
      const midPointMercator = toMercator(midPoint);
      styles.push(
        new Style({
          geometry: new Point(midPointMercator),
          image: new Icon({
            src: valveIcon,
            scale: 0.12,
            anchor: [0.5, 0.5],
          }),
        })
      );
    }
    return styles;
  };
  // 矢量瓦片数据源和图层
  const junctionSource = new VectorTileSource({
    url: `${mapUrl}/gwc/service/tms/1.0.0/TJWater:geo_junctions_mat@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL
    format: new MVT(),
    projection: "EPSG:3857",
  });
  const pipeSource = new VectorTileSource({
    url: `${mapUrl}/gwc/service/tms/1.0.0/TJWater:geo_pipes_mat@WebMercatorQuad@pbf/{z}/{x}/{-y}.pbf`, // 替换为你的 MVT 瓦片服务 URL
    format: new MVT(),
    projection: "EPSG:3857",
  });
  const scadaSource = new VectorSource({
    url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_scada&outputFormat=application/json`,
    format: new GeoJson(),
  });
  const reservoirsSource = new VectorSource({
    url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_reservoirs&outputFormat=application/json`,
    format: new GeoJson(),
  });
  const valvesSource = new VectorSource({
    url: `${mapUrl}/TJWater/ows?service=WFS&version=1.0.0&request=GetFeature&typeName=TJWater:geo_valves&outputFormat=application/json`,
    format: new GeoJson(),
  });
  // WebGL 渲染优化显示
  const junctionLayer = new WebGLVectorTileLayer({
    source: junctionSource as any, // 使用 WebGL 渲染
    style: defaultFlatStyle,
    extent: extent, // 设置图层范围
    maxZoom: 24,
    minZoom: 12,
    properties: {
      name: "节点", // 设置图层名称
      value: "junctions",
      type: "point",
      properties: [
        // { name: "需求量", value: "demand" },
        // { name: "海拔高度", value: "elevation" },
        { name: "实际需求量", value: "actualdemand" },
        { name: "水头", value: "head" },
        { name: "压力", value: "pressure" },
        { name: "水质", value: "quality" },
      ],
    },
  });
  const pipeLayer = new WebGLVectorTileLayer({
    source: pipeSource as any, // 使用 WebGL 渲染
    style: defaultFlatStyle,
    extent: extent, // 设置图层范围
    maxZoom: 24,
    minZoom: 12,
    properties: {
      name: "管道", // 设置图层名称
      value: "pipes",
      type: "linestring",
      properties: [
        // { name: "直径", value: "diameter" },
        // { name: "粗糙度", value: "roughness" },
        // { name: "局部损失", value: "minor_loss" },
        { name: "流量", value: "flow" },
        { name: "摩阻系数", value: "friction" },
        { name: "水头损失", value: "headloss" },
        { name: "水质", value: "quality" },
        { name: "反应速率", value: "reaction" },
        { name: "设置值", value: "setting" },
        { name: "状态", value: "status" },
        { name: "流速", value: "velocity" },
      ],
    },
  });
  const scadaLayer = new VectorLayer({
    source: scadaSource,
    style: scadaStyle,
    // extent: extent, // 设置图层范围
    maxZoom: 24,
    minZoom: 12,
    properties: {
      name: "SCADA", // 设置图层名称
      value: "scada",
      type: "point",
      properties: [],
    },
  });
  const reservoirsLayer = new VectorLayer({
    source: reservoirsSource,
    style: reservoirsStyle,
    extent: extent, // 设置图层范围
    maxZoom: 24,
    minZoom: 12,
    properties: {
      name: "水库", // 设置图层名称
      value: "reservoirs",
      type: "point",
      properties: [],
    },
  });
  const valvesLayer = new VectorLayer({
    source: valvesSource,
    style: valvesStyle,
    extent: extent, // 设置图层范围
    maxZoom: 24,
    minZoom: 12,
    properties: {
      name: "阀门", // 设置图层名称
      value: "valves",
      type: "linestring",
      properties: [],
    },
  });
  useEffect(() => {
    if (!mapRef.current) return;
    // 缓存 junction、pipe 数据，提供给 deck.gl 显示标签使用
    junctionSource.on("tileloadend", (event) => {
      try {
        if (event.tile instanceof VectorTile) {
          const renderFeatures = event.tile.getFeatures();
          const data = new Map();

          renderFeatures.forEach((renderFeature) => {
            const props = renderFeature.getProperties();
            const featureId = props.id;
            if (featureId && !junctionDataIds.current.has(featureId)) {
              const geometry = renderFeature.getGeometry();
              if (geometry) {
                const coordinates = geometry.getFlatCoordinates();
                const coordWGS84 = toLonLat(coordinates);
                data.set(featureId, {
                  id: featureId,
                  position: coordWGS84,
                  elevation: props.elevation || 0,
                  demand: props.demand || 0,
                });
              }
            }
          });

          const uniqueData = Array.from(data.values());
          if (uniqueData.length > 0) {
            tileJunctionDataBuffer.current.push(...uniqueData);
            debouncedUpdateData.current();
          }
        }
      } catch (error) {
        console.error("Junction tile load error:", error);
      }
    });
    pipeSource.on("tileloadend", (event) => {
      try {
        if (event.tile instanceof VectorTile) {
          const renderFeatures = event.tile.getFeatures();
          const data = new Map();

          renderFeatures.forEach((renderFeature) => {
            try {
              const props = renderFeature.getProperties();
              const featureId = props.id;
              if (featureId && !pipeDataIds.current.has(featureId)) {
                const geometry = renderFeature.getGeometry();
                if (geometry) {
                  const flatCoordinates = geometry.getFlatCoordinates();
                  const stride = geometry.getStride(); // 获取步长，通常为 2
                  // 重建为 LineString GeoJSON 格式的 coordinates: [[x1, y1], [x2, y2], ...]
                  const lineCoords = [];
                  for (let i = 0; i < flatCoordinates.length; i += stride) {
                    lineCoords.push([
                      flatCoordinates[i],
                      flatCoordinates[i + 1],
                    ]);
                  }
                  const lineCoordsWGS84 = lineCoords.map((coord) => {
                    const [lon, lat] = toLonLat(coord);
                    return [lon, lat];
                  });
                  // 添加验证：确保至少有 2 个坐标点
                  if (lineCoordsWGS84.length < 2) return; // 跳过此特征
                  // 计算中点
                  const lineStringFeature = lineString(lineCoordsWGS84);
                  const lineLength = length(lineStringFeature);
                  const midPoint = along(lineStringFeature, lineLength / 2)
                    .geometry.coordinates;
                  // 计算角度
                  const prevPoint = along(lineStringFeature, lineLength * 0.49)
                    .geometry.coordinates;
                  const nextPoint = along(lineStringFeature, lineLength * 0.51)
                    .geometry.coordinates;
                  let lineAngle = bearing(prevPoint, nextPoint);
                  lineAngle = -lineAngle + 90;
                  if (lineAngle < -90 || lineAngle > 90) {
                    lineAngle += 180;
                  }

                  // 计算时间戳（可选）
                  const numSegments = lineCoordsWGS84.length - 1;
                  const timestamps = [0];
                  if (numSegments > 0) {
                    for (let i = 1; i <= numSegments; i++) {
                      timestamps.push((i / numSegments) * 10);
                    }
                  }

                  data.set(featureId, {
                    id: featureId,
                    diameter: props.diameter || 0,
                    path: lineCoordsWGS84, // 使用重建后的坐标
                    position: midPoint,
                    angle: lineAngle,
                    timestamps,
                  });
                }
              }
            } catch (geomError) {
              console.error("Geometry calculation error:", geomError);
            }
          });

          const uniqueData = Array.from(data.values());
          if (uniqueData.length > 0) {
            tilePipeDataBuffer.current.push(...uniqueData);
            debouncedUpdateData.current();
          }
        }
      } catch (error) {
        console.error("Pipe tile load error:", error);
      }
    });
    // 监听 junctionLayer 的 visible 变化
    const handleJunctionVisibilityChange = () => {
      const isVisible = junctionLayer.getVisible();
      setShowJunctionTextLayer(isVisible);
    };
    // 监听 pipeLayer 的 visible 变化
    const handlePipeVisibilityChange = () => {
      const isVisible = pipeLayer.getVisible();
      setShowPipeTextLayer(isVisible);
    };
    // 添加事件监听器
    junctionLayer.on("change:visible", handleJunctionVisibilityChange);
    pipeLayer.on("change:visible", handlePipeVisibilityChange);

    const map = new OlMap({
      target: mapRef.current,
      view: new View({
        maxZoom: 24,
        projection: "EPSG:3857",
      }),
      // 图层依面、线、点、标注次序添加
      layers: [
        pipeLayer,
        junctionLayer,
        valvesLayer,
        scadaLayer,
        reservoirsLayer,
      ],
      controls: [],
    });
    setMap(map);
    map.getView().fit(extent, {
      padding: [50, 50, 50, 50], // 添加一些内边距
      duration: 1000, // 动画持续时间
    });
    // 监听缩放变化
    map.getView().on("change", () => {
      setTimeout(() => {
        const zoom = map.getView().getZoom() || 0;
        setCurrentZoom(zoom);
      }, 0);
    });
    // 初始化 deck.gl
    const deck = new Deck({
      initialViewState: {
        longitude: 0,
        latitude: 0,
        zoom: 1,
      },
      canvas: "deck-canvas",
      controller: false, // 由 OpenLayers 控制视图
      layers: [],
    });
    deckRef.current = deck;
    const deckLayer = new DeckLayer(deck);
    // deckLayer.setZIndex(1000); // 确保在最上层
    map.addLayer(deckLayer);

    // 清理函数
    return () => {
      junctionLayer.un("change:visible", handleJunctionVisibilityChange);
      pipeLayer.un("change:visible", handlePipeVisibilityChange);
      map.setTarget(undefined);
      map.dispose();
      deck.finalize();
    };
  }, []);

  // 当数据变化时，更新 deck.gl 图层
  useEffect(() => {
    const deck = deckRef.current;
    if (!deck) return; // 如果 deck 实例还未创建，则退出
    const newLayers = [
      new TextLayer({
        id: "junctionTextLayer",
        zIndex: 10,
        data: showJunctionText ? junctionData : [],
        getPosition: (d: any) => d.position,
        fontFamily: "Monaco, monospace",
        getText: (d: any) =>
          d[junctionText] ? (d[junctionText] as number).toFixed(3) : "",
        getSize: 18,
        fontWeight: "bold",
        getColor: [0, 0, 0],
        getAngle: 0,
        getTextAnchor: "middle",
        getAlignmentBaseline: "center",
        getPixelOffset: [0, -10],
        visible:
          showJunctionTextLayer && currentZoom >= 15 && currentZoom <= 24,
        extensions: [new CollisionFilterExtension()],
        collisionTestProps: {
          sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距
        },
        // 可读性设置
        characterSet: "auto",
        fontSettings: {
          sdf: true,
          fontSize: 64,
          buffer: 6,
        },
        // outlineWidth: 10,
        // outlineColor: [242, 244, 246, 255],
      }),
      new TextLayer({
        id: "pipeTextLayer",
        zIndex: 10,
        data: showPipeText ? pipeData : [],
        getPosition: (d: any) => d.position,
        fontFamily: "Monaco, monospace",
        getText: (d: any) =>
          d[pipeText] ? (d[pipeText] as number).toFixed(3) : "",
        getSize: 18,
        fontWeight: "bold",
        getColor: [0, 0, 0],
        getAngle: (d: any) => d.angle || 0,
        getPixelOffset: [0, -8],
        getTextAnchor: "middle",
        getAlignmentBaseline: "bottom",
        visible: showPipeTextLayer && currentZoom >= 15 && currentZoom <= 24,
        extensions: [new CollisionFilterExtension()],
        collisionTestProps: {
          sizeScale: 3, // 增加碰撞检测的尺寸以提供更大间距
        },
        // 可读性设置
        characterSet: "auto",
        fontSettings: {
          sdf: true,
          fontSize: 64,
          buffer: 6,
        },
        // outlineWidth: 10,
        // outlineColor: [242, 244, 246, 255],
      }),
    ];
    deck.setProps({ layers: newLayers });

    // 动画循环
    const animate = () => {
      if (!deck || !flowAnimation.current) return; // 添加检查，防止空数据或停止旧循环
      // 动画总时长（秒）
      if (pipeData.length === 0) {
        requestAnimationFrame(animate);
        return;
      }
      const animationDuration = 10;
      // 缓冲时间（秒）
      const bufferTime = 2;
      // 完整循环周期
      const loopLength = animationDuration + bufferTime;
      // 确保时间范围与你的时间戳数据匹配
      const currentTime = (Date.now() / 1000) % loopLength; // (0,12) 之间循环
      // console.log("Current Time:", currentTime);
      const waterflowLayer = new TripsLayer({
        id: "waterflowLayer",
        data: pipeData,
        getPath: (d) => d.path,
        getTimestamps: (d) => {
          return d.timestamps; // 这些应该是与 currentTime 匹配的数值
        },
        getColor: [0, 220, 255],
        opacity: 0.8,
        visible:
          flowAnimation.current && currentZoom >= 12 && currentZoom <= 24,
        widthMinPixels: 5,
        jointRounded: true, // 拐角变圆
        // capRounded: true, // 端点变圆
        trailLength: 2, // 水流尾迹淡出时间
        currentTime: currentTime,
      });

      // 获取当前除 waterflowLayer 之外的所有图层
      const otherLayers = deck.props.layers.filter(
        (layer: any) => layer && layer.id !== "waterflowLayer"
      );

      deck.setProps({
        layers: [...otherLayers, waterflowLayer],
      });

      // 继续请求动画帧，每帧执行一次函数
      requestAnimationFrame(animate);
    };
    animate();
  }, [
    flowAnimation,
    junctionData,
    pipeData,
    currentZoom,
    showJunctionText,
    showPipeText,
    showJunctionTextLayer,
    showPipeTextLayer,
    junctionText,
    pipeText,
  ]);
  // 控制流动动画开关
  useEffect(() => {
    if (pipeText === "flow" && currentPipeCalData.length > 0) {
      flowAnimation.current = true;
    } else {
      flowAnimation.current = false;
    }
  }, [currentPipeCalData, pipeText]);
  // 计算值更新时，更新 junctionData 和 pipeData
  useEffect(() => {
    const junctionProperties = junctionText;
    const pipeProperties = pipeText;

    // 将 nodeRecords 转换为 Map 以提高查找效率
    const nodeMap: Map<string, any> = new Map(
      currentJunctionCalData.map((r: any) => [r.ID, r])
    );
    // 将 linkRecords 转换为 Map 以提高查找效率
    const linkMap: Map<string, any> = new Map(
      currentPipeCalData.map((r: any) => [r.ID, r])
    );

    // 更新junctionData
    setJunctionDataState((prev: any[]) =>
      prev.map((j) => {
        const record = nodeMap.get(j.id);
        if (record) {
          return {
            ...j,
            [junctionProperties]: record.value,
          };
        }
        return j;
      })
    );

    // 更新pipeData
    setPipeDataState((prev: any[]) =>
      prev.map((p) => {
        const record = linkMap.get(p.id);
        if (record) {
          return {
            ...p,
            flowFlag: pipeProperties === "flow" && record.value < 0 ? -1 : 1,
            path:
              pipeProperties === "flow" && record.value < 0 && p.flowFlag > 0
                ? [...p.path].reverse()
                : p.path,
            [pipeProperties]: record.value,
          };
        }
        return p;
      })
    );
  }, [currentJunctionCalData, currentPipeCalData]);
  return (
    <>
      <DataContext.Provider
        value={{
          currentTime,
          setCurrentTime,
          selectedDate,
          setSelectedDate,
          schemeName,
          setSchemeName,
          currentJunctionCalData,
          setCurrentJunctionCalData,
          currentPipeCalData,
          setCurrentPipeCalData,
          setShowJunctionText,
          setShowPipeText,
          setJunctionText,
          setPipeText,
          showJunctionText,
          showPipeText,
          junctionText,
          pipeText,
        }}
      >
        <MapContext.Provider value={map}>
          <div className="relative w-full h-full">
            <div ref={mapRef} className="w-full h-full"></div>
            <MapTools />
            {children}
          </div>
          <canvas id="deck-canvas" />
        </MapContext.Provider>
      </DataContext.Provider>
    </>
  );
};

export default MapComponent;
