<template>
  <div style="height: 100%; width: 100%; display: flex; flex-direction: row">
    <!-- 左边是列表 -->
    <div style="width: 300px; height: 100%">
      <el-card style="height: 100%">
        <template #header>
          <div class="card-header">
            <el-icon :size="15" class="mr-2" style="vertical-align: middle">
              <component :is="Menu" />
            </el-icon>
            <span>项目列表</span>
          </div>
        </template>
        <el-menu
          :key="menuKey"
          :default-active="activePath"
          :default-openeds="defaultOpeneds"
          class="custom-menu"
          mode="vertical"
          @select="handleMenuSelect"
        >
          <el-sub-menu
            v-for="(parent, parentIndex) in menuItems"
            :key="parentIndex"
            :index="parent.index"
            :class="{ 'parent-active': isParentActive(parent.index) }"
          >
            <template #title>
              <!-- 父菜单图标 -->
              <el-icon :size="18" class="mr-2">
                <component :is="parent.icon" />
              </el-icon>
              <span>{{ parent.title }}</span>
            </template>
            <el-menu-item
              v-for="(child, childIndex) in parent.children"
              :key="childIndex"
              :index="child.index"
            >
              <!-- 子菜单图标 -->
              <el-icon :size="18" class="mr-2">
                <component :is="child.icon" />
              </el-icon>
              <span>{{ child.title }}</span>
            </el-menu-item>
          </el-sub-menu>
        </el-menu>
      </el-card>
    </div>

    <!-- 右边是地图引擎 -->
    <div style="width: 100%; height: 100%; display: grid">
      <div id="mapview" ref="mapview" v-loading="mapSet.loading" />

      <div class="float-stat">
        <div class="float-stat-item">
          <div class="float-stat-item-key" style="padding-top: 4px">
            查询时间
          </div>
          <el-date-picker
            v-model="queryState.queryTime"
            type="datetimerange"
            :shortcuts="queryTimeShortCuts"
            range-separator="至"
            start-placeholder="开始日期时间"
            end-placeholder="结束日期时间"
            :popper-options="{
              placement: 'bottom-start'
            }"
          />

          <el-button
            style="margin-left: 10px"
            type="primary"
            :icon="useRenderIcon(Search)"
            @click="getHisPath"
            >查询数据</el-button
          >
        </div>

        <div style="display: flex; flex-direction: row">
          <div class="float-stat-item" style="margin-top: 10px">
            <div class="float-stat-item-key" style="padding-top: 4px">
              播放时间
            </div>
            <div
              class="float-stat-item-value"
              style="padding-top: 4px; color: blue"
            >
              {{ parseTime(playTime) }}
            </div>
          </div>

          <div class="float-stat-item">
            <div
              class="float-stat-item-key"
              style="
                margin-top: 10px;
                padding-top: 4px;
                text-align: right;
                padding-right: 20px;
              "
            >
              速度
            </div>
            <el-select
              v-model="playSpeed"
              class="float-stat-item-value"
              style="margin-top: 10px; width: 80px"
            >
              <el-option
                v-for="item in playSpeedOptions"
                :key="item.value"
                :label="item.label"
                :value="item.value"
              />
            </el-select>
          </div>

          <div class="float-stat-item" style="margin-top: 10px">
            <el-button
              style="margin-left: 10px"
              :icon="useRenderIcon(Search)"
              @click="play"
              :type="isPlaying ? 'danger' : 'success'"
              >{{ isPlaying ? "暂停" : "播放" }}</el-button
            >

            <el-button
              style="margin-left: 10px"
              type="primary"
              :icon="useRenderIcon(Search)"
              @click="getHisPath"
              >一键绘制</el-button
            >
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import {
  h,
  ref,
  onMounted,
  computed,
  onUnmounted,
  reactive,
  getCurrentInstance,
  onBeforeMount
} from "vue";
// 导入 Element Plus 内置图标
import { Bottom, Folder, Menu } from "@element-plus/icons-vue";
import { deviceDetection } from "@pureadmin/utils";
import AMapLoader from "@amap/amap-jsapi-loader";
import { mapJson } from "@/api/mock";
import PicCar from "@/assets/car.png";
import PicCarDisable from "@/assets/car-disable.png";
import { ElNotification, ElMessageBox } from "element-plus";
import { clear } from "console";
import { duration } from "dayjs";
import RtWatchPart from "./rtWatchPart.vue";
import Location from "@/model/location";
import Search from "~icons/ep/search";
import IconDownLoad from "~icons/ep/download";
import { useRenderIcon } from "@/components/ReIcon/src/hooks";
import { fetchHisPath } from "@/api/path";
import { parseTime } from "@/utils/time";

const queryTimeShortCuts = [
  {
    text: "今天",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      const end = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() + 1
      );
      return [start, end];
    }
  },
  {
    text: "昨天",
    value: () => {
      const now = new Date();
      const start = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - 1
      );
      const end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      return [start, end];
    }
  },
  {
    text: "本周",
    value: () => {
      const now = new Date();
      const start = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - now.getDay()
      );
      const end = new Date(
        now.getFullYear(),
        now.getMonth(),
        now.getDate() - now.getDay() + 6
      );
      return [start, end];
    }
  },
  {
    text: "本月",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), 1);
      const end = new Date(now.getFullYear(), now.getMonth() + 1, 0);
      return [start, end];
    }
  }
];

const playSpeedOptions = ref([
  { label: "1X", value: 1 },
  { label: "2X", value: 2 },
  { label: "4X", value: 4 },
  { label: "10X", value: 10 },
  { label: "15X", value: 15 },
  { label: "20X", value: 20 },
  { label: "30X", value: 30 },
  { label: "50X", value: 50 },
  { label: "100X", value: 100 },
  { label: "120X", value: 120 },
  { label: "150X", value: 150 },
  { label: "180X", value: 180 },
  { label: "200X", value: 200 }
]);

const playSpeed = ref(1);
let paths = [];
const isPlaying = ref(false);
const playTime = ref(new Date().getTime());
let loop = 0;
const vecAnchor = [];
const markerAnchors = [];

const queryState = ref({
  queryTime: [
    // new Date(
    //   new Date().getFullYear(),
    //   new Date().getMonth(),
    //   new Date().getDate()
    // ),
    new Date(2025, 8, 24, 9, 20, 0),
    new Date(
      new Date().getFullYear(),
      new Date().getMonth(),
      new Date().getDate() + 1
    )
  ],
  queryProjectName: "",
  queryLocationName: "",
  queryName: "",
  queryPhone: ""
});

const vGlobal = window.vueGlobal;

export interface MapConfigureInter {
  on: Fn;
  destroy?: Fn;
  clearEvents?: Fn;
  addControl?: Fn;
  setCenter?: Fn;
  setZoom?: Fn;
  plugin?: Fn;
}

defineOptions({
  name: "Amap"
});

let MarkerCluster;
let map: MapConfigureInter;
let AMap = null;

const instance = getCurrentInstance();

const mapSet = reactive({
  loading: deviceDetection() ? false : true
});

// 菜单数据
const menuItems = [
  {
    index: "1",
    title: "父菜单1",
    icon: Menu,
    children: [{ index: "1-1", title: "子菜单1-1", icon: Folder }]
  }
];
const menuKey = ref(0);
let dictMenus = {};
let firstMenuId = null;

// 当前选中的路径
const activePath = ref("");

// 计算所有父菜单的索引，用于默认展开所有子菜单
const defaultOpeneds = computed(() => {
  // 提取所有父菜单的 index 组成数组
  return menuItems.map(item => item.index);
});

let scheduleId = null;

const selLocation = ref(new Location());

const createMenus = () => {
  menuItems.splice(0);
  dictMenus = {};
  for (const p of vGlobal.vecProject) {
    const pIdx = "" + p.id;
    menuItems.push({
      index: pIdx,
      title: p.name,
      icon: Menu,
      children: []
    });
    dictMenus[pIdx] = p;
    for (const m of p.locations) {
      const mIdx = pIdx + "-" + m.id;
      menuItems[menuItems.length - 1].children.push({
        index: mIdx,
        title: m.name,
        icon: Folder
      });
      dictMenus[mIdx] = m;
      if (!firstMenuId) {
        firstMenuId = mIdx;
      }
    }
  }
  menuKey.value++;
};

// 处理菜单选中事件
const handleMenuSelect = index => {
  activePath.value = index;
  console.log("handleMenuSelect", index, dictMenus[index]);
  const location = dictMenus[index];
  if (location) {
    selLocation.value = location;
    map.setCenter([location.center.x, location.center.y]);
    map.setZoom(13);
  }
};

// 判断父菜单是否需要激活样式
const isParentActive = parentIndex => {
  // 检查当前选中项是否属于该父菜单
  return activePath.value.startsWith(parentIndex + "-");
};

const genMarkerLabel = anc => {
  const label = {
    direction: "bottom",
    //设置文本标注偏移量
    offset: new AMap.Pixel(-4, 0),
    //设置文本标注内容
    content: anc.isCharging
      ? `<div style="color: red; font-weight: bold; font-size: 14px;  " > A[#${anc.id}](充电中)</div>`
      : `<div style="font-size: 14px;  "> A[#${anc.id}](${anc.percentBattery}%)</div>`
  };

  return label;
};

const getHisPath = () => {
  const proj = selLocation.value.parent;
  let projId = 0;
  if (proj) {
    projId = proj.id;
  }
  const queryParams = {
    beginTime: queryState.value.queryTime[0].getTime(),
    endTime: queryState.value.queryTime[1].getTime(),
    sortMode: 1,
    projId: projId
  };

  fetchHisPath(queryParams).then(res => {
    if (res.success) {
      paths = [];
      playTime.value = 0;
      for (const m of markerAnchors) {
        m.remove();
      }
      markerAnchors.splice(0);

      for (const t of res.items) {
        const tm = Number(t["tm"]);
        if (playTime.value == 0 || playTime.value > tm) {
          playTime.value = tm;
        }
        paths.push(t);
      }

      if (paths.length) {
        ElNotification.success({
          message: "查询成功"
        });
      } else {
        ElNotification.info({
          message: "查询时间段内无数据"
        });
      }

      playTime.value = queryState.value.queryTime[0].getTime();
      isPlaying.value = false;
      loop = 0;
    }
  });
};

const play = () => {
  isPlaying.value = !isPlaying.value;
};

const genBatStr = battery => {
  let perBat = Math.floor(((battery - 3700) / (4100 - 3700)) * 100);
  if (perBat < 0) {
    perBat = 0;
  } else if (perBat > 100) {
    perBat = 100;
  }
  return perBat;
};

const genMarker = (id, x, y, isCharging) => {
  const marker = new AMap.Marker({
    extData: {
      id: id,
      isOnline: 1
    },
    position: [x, y],
    icon: PicCar,
    offset: new AMap.Pixel(-18, -10),
    label: {
      direction: "bottom",
      //设置文本标注偏移量
      offset: new AMap.Pixel(-4, 0),
      //设置文本标注内容
      content: isCharging
        ? `<div> A[#${id}](充电中)</div>`
        : `<div> A[#${id}]</div>`
    }
    // visible: v.isOnline
  });

  marker.on("click", ({ lnglat }) => {
    // map.setZoom(13); //设置地图层级
    // map.setCenter(lnglat);
    const extData = marker.getExtData();
    const id = extData["id"];
    const x = extData["x"];
    const y = extData["y"];
    const battery = extData["battery"];
    const isCharging = battery > 4400;

    //信息窗体的内容
    var content = [
      `<div style="font-size: 14px; "><b style="font-size: 16px; ">A[#${id}]</b>`,
      `<b>经度:</b> ${x} <b>纬度:</b> ${y}`,
      `<b>电池${isCharging ? "状态" : "电量"}:</b> ${isCharging ? "充电中" : genBatStr(battery) + "%"}`,
      "</div>"
    ];

    //创建 infoWindow 实例
    var infoWindow = new AMap.InfoWindow({
      content: content.join("<br>"), //传入字符串拼接的 DOM 元素
      anchor: "top-left"
    });

    //打开信息窗体
    infoWindow.open(map, marker.getPosition()); //map 为当前地图的实例，map.getCenter() 用于获取地图中心点坐标。
  });
  marker.setMap(map);
  markerAnchors.push(marker);

  return marker;
};

const schedule = () => {
  if (!isPlaying.value) {
    return;
  }

  let path = null;
  if (loop < paths.length) {
    path = paths[loop];
  }

  // 计算播放时间
  playTime.value += playSpeed.value * 1000;
  console.log("playTime", parseTime(playTime.value), loop, playTime.value);
  console.log("path", path ? Number(path["tm"]) : "000-000");

  // 在播放时间内
  while (playTime.value >= Number(path["tm"]) && loop < paths.length) {
    path = paths[loop];

    const ancAddr = Number(path["addr"]);
    let marker = null;
    let extData = null;
    for (const m of markerAnchors) {
      // 查找 anchor
      extData = m.getExtData();
      const id = Number(extData["id"]);
      if (id == ancAddr) {
        marker = m;
        break;
      }
    }

    if (marker) {
      // console.log("marker find", marker);
      // 找到 anchor
      marker.setPosition([Number(path["x"]), Number(path["y"])]);
    } else {
      // 未找到 anchor
      // console.log("marker find", marker);
      marker = genMarker(ancAddr, Number(path["x"]), Number(path["y"]), 0);
      extData = marker.getExtData();
    }
    let isOnline = Number(path["status"]) || 0;
    extData["isOnline"] = isOnline;
    extData["battery"] = Number(path["battery"]);
    extData["x"] = Number(path["x"]);
    extData["y"] = Number(path["y"]);
    const isCharging = extData["battery"] > 4400;
    marker.setExtData(extData);

    const label = {
      direction: "bottom",
      //设置文本标注偏移量
      offset: new AMap.Pixel(-4, 0),
      //设置文本标注内容
      content: isCharging
        ? `<div style="color: red; font-weight: bold; font-size: 14px;  " > A[#${extData["id"]}](充电中)</div>`
        : `<div style="font-size: 14px; font-weight: bold; "> A[#${extData["id"]}](${genBatStr(extData["battery"])}%)</div>`
    };
    marker.setLabel(label);

    if (isOnline) {
      marker.setIcon(PicCar);
    } else {
      marker.setIcon(PicCarDisable);
    }

    loop++;

    console.log("playTime", parseTime(playTime.value), loop, playTime.value);
    console.log("path", path ? Number(path["tm"]) : "000-000");
  } // end while 在播放时间内

  // 播放时间结束
  if (loop >= paths.length) {
    isPlaying.value = false;
    ElNotification.success({
      message: "查询时间内已有数据回放结束"
    });
  }
};

onBeforeMount(() => {
  if (!instance) return;
  const { MapConfigure } = instance.appContext.config.globalProperties.$config;
  const { options } = MapConfigure;

  AMapLoader.load({
    key: MapConfigure.amapKey,
    version: "2.0",
    plugins: ["AMap.MarkerCluster", "AMap.MoveAnimation"]
  })
    .then(aMap => {
      AMap = aMap;
      // 创建地图实例
      map = new AMap.Map(instance.refs.mapview, options);

      //地图中添加地图操作ToolBar插件
      map.plugin(["AMap.ToolBar", "AMap.MapType", "AMap.ControlBar"], () => {
        map.addControl(new AMap.ToolBar());
        //地图类型切换
        map.addControl(
          new AMap.MapType({
            defaultType: 0,
            position: {
              right: "10px",
              top: "10px"
            }
          })
        );
        map.addControl(
          new AMap.ControlBar({
            position: {
              right: "10px",
              top: "120px"
            }
          })
        );
      });

      // MarkerCluster = new AMap.MarkerCluster(map, [], {
      //   // 聚合网格像素大小
      //   gridSize: 80,
      //   maxZoom: 14,
      //   renderMarker(ctx) {
      //     const { marker, data } = ctx;
      //     if (Array.isArray(data) && data[0]) {
      //       const { driver, plateNumber, orientation } = data[0];
      //       const content = `<img style="transform: scale(1) rotate(${
      //         360 - Number(orientation)
      //       }deg);" src='${car}' />`;
      //       marker.setContent(content);
      //       marker.setLabel({
      //         direction: "bottom",
      //         //设置文本标注偏移量
      //         offset: new AMap.Pixel(-4, 0),
      //         //设置文本标注内容
      //         content: `<div> ${plateNumber}(${driver})</div>`
      //       });
      //       marker.setOffset(new AMap.Pixel(-18, -10));
      //       marker.on("click", ({ lnglat }) => {
      //         map.setZoom(13); //设置地图层级
      //         map.setCenter(lnglat);
      //       });
      //     }
      //   }
      // });

      complete();
    })
    .catch(() => {
      mapSet.loading = false;
      throw "地图加载失败，请重新加载";
    });
});

const handleResize = () => {
  if (map) {
    map.resize(); // 调用高德地图的resize方法重新计算尺寸
  }
};

onMounted(() => {
  const ci = setInterval(() => {
    if (vGlobal.isInited()) {
      clearInterval(ci);
      createMenus();
      handleMenuSelect(firstMenuId);

      window.addEventListener("resize", handleResize);
    }
  }, 100);

  console.log("onMounted");
  scheduleId = setInterval(() => {
    schedule();
  }, 1000);
});

onUnmounted(() => {
  window.removeEventListener("resize", handleResize);
  if (map) {
    // 销毁地图实例
    map.destroy() && map.clearEvents("click");
  }
  clearInterval(scheduleId);
  console.log("onUnmounted");
  scheduleId = null;
});

// 地图创建完成(动画关闭)
const complete = (): void => {
  if (map) {
    map.on("complete", () => {
      mapSet.loading = false;
    });
  }
};
</script>

<style scoped>
.custom-menu {
  width: 100%;
}

:deep(.el-sub-menu .el-menu-item.is-active) {
  color: #0557aa !important;
  background-color: #e6f7ff !important;
}

/* 子菜单选中样式 */
:deep(.el-menu-item.is-active) {
  color: #0557aa !important;
  background-color: #e6f7ff !important;
  font-weight: 600;
}

/* 父菜单激活样式 - 当子菜单选中时 */
:deep(.parent-active .el-sub-menu__title) {
  color: #0557aa !important;
  font-weight: bold;
}

/* 父菜单 hover 样式保持一致 */
:deep(.el-sub-menu__title:hover) {
  color: #0557aa !important;
}

#mapview {
  height: calc(100vh - 48px);
  width: 100%;
  grid-area: 1 / 1 / -1 / -1;
}

/* 新增根元素高度设置 */
:root {
  height: 100%;
}

/* 确保父级容器高度正确传递 */
:deep(html),
:deep(body) {
  height: 100%;
  margin: 0;
  padding: 0;
}

/* 调整网格容器样式 */
:deep(.grid-container) {
  /* 假设地图外层容器添加class="grid-container" */
  display: grid;
  height: 100%;
}

.float-stat {
  padding: 10px 10px 10px 10px;
  width: fit-content;
  height: fit-content;
  background: #ffffff;
  grid-area: 1 / 1 / -1 / -1;
  z-index: 10;
  border-radius: 2px;
  opacity: 0.95;
  box-shadow: rgba(0, 0, 0, 0.6) 0 2px 2px;
  display: flex;
  flex-direction: column;
  margin-top: 10px;
  justify-self: center;
}

.float-stat-item {
  /* width: 100%; */
  width: fit-content;
  display: flex;
  flex-direction: row;
}

.float-stat-item-key {
  font-weight: 900;
  width: 80px;
}

.float-stat-item-value {
  font-weight: 600;
  width: fit-content;
  text-align: right;
}

:deep(.amap-marker-label) {
  border: none !important;
}

:deep(.amap-copyright) {
  display: none !important;
}

:deep(.amap-logo) {
  display: none !important;
}
</style>
