<template>
  <div>
    <el-row class="search-bar" :gutter="10">
      <el-col :span="18">
        <el-input
          v-model="searchKeyword"
          size="small"
          placeholder="请输入地名或点击地图选点"
          @keypress.enter="searchPoint"
        ></el-input>
      </el-col>
      <el-col :span="1.5">
        <el-button type="primary" size="small" icon="search">搜索</el-button>
      </el-col>
    </el-row>

    <div id="map-container"></div>
    <!-- 添加或修改站点对话框 -->
    <el-dialog
      :title="title"
      v-model="open"
      width="500px"
      append-to-body
      :close-on-click-modal="false"
      :close-on-press-escape="false"
      :show-close="false"
    >
      <el-form ref="siteRef" :model="form" :rules="rules" label-width="80px">
        <el-form-item label="站点名称" prop="siteName">
          <el-input v-model="form.siteName" placeholder="请输入站点名称" />
        </el-form-item>
        <el-form-item label="分组" prop="groupId">
          <!-- <el-input v-model="form.groupId" placeholder="请输入分组ID" /> -->
          <el-select v-model="form.groupId" placeholder="请选择站点分组">
            <el-option
              v-for="item in siteGroupList"
              :key="item.groupId"
              :label="item.groupName"
              :value="item.groupId"
            />
          </el-select>
        </el-form-item>
        <city-select v-model="form" :label-width="80"></city-select>
        <!-- <el-form-item label="省" prop="province">
          <el-input v-model="form.province" placeholder="请输入省" />
        </el-form-item>
        <el-form-item label="市" prop="city">
          <el-input v-model="form.city" placeholder="请输入市" />
        </el-form-item>
        <el-form-item label="区" prop="area">
          <el-input v-model="form.area" placeholder="请输入区" />
        </el-form-item> -->
        <el-form-item label="详细地址" prop="address">
          <el-input v-model="form.address" placeholder="请输入详细地址" />
        </el-form-item>
        <el-form-item label="经纬度" prop="coordinate">
          <el-input
            class="map-select"
            readonly
            v-model="form.coordinate"
            placeholder="请点击右侧按钮在地图上选点"
          >
            <template #append>
              <!-- <el-icon @click="open = false"><Pointer />
                </el-icon
            > -->
              <el-button @click="open = false" icon="pointer"></el-button>
            </template>
          </el-input>
        </el-form-item>
        <el-form-item label="备注" prop="remark">
          <el-input v-model="form.remark" placeholder="请输入备注" />
        </el-form-item>
        <!-- <el-form-item label="站点" prop="tenantId">
          <el-input v-model="form.tenantId" placeholder="请输入站点ID" />
        </el-form-item> -->
      </el-form>
      <template #footer>
        <div class="dialog-footer">
          <el-button type="primary" @click="submitForm">确 定</el-button>
          <el-button @click="back">取 消</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup>
import tab from "@/plugins/tab";
import { useRoute } from "vue-router";
import { loadAMap } from "@/utils/map";
import { listSiteGroup } from "@/api/site/group";
import CitySelect from "@/components/CitySelect";
import markBsPng from "@/assets/images/mark_bs.png";
import { addSite, getSite, updateSite } from "@/api/site/site";
const route = useRoute();
const { proxy } = getCurrentInstance();
const geocoder = shallowRef(null); // 经纬度转地址插件
const placeSearch = shallowRef(null);
const searchResultMarkers = shallowRef([]); // 搜索结果表笔列表
const resultInfoWindow = shallowRef(null);
const siteMarker = shallowRef(null);
const searchKeyword = ref("");
const AMap = shallowRef(null);
const map = shallowRef(null);
const siteGroupList = ref([]);
const open = ref(false);
const title = ref("");
const data = reactive({
  form: {},
  rules: {},
});

const { form, rules } = toRefs(data);

// 根据经纬度获取地址
const regeoCode = (lnglat /** [lng, lat] */) => {
  return new Promise((resolve, reject) => {
    geocoder.value.getAddress(lnglat, (status, result) => {
      if (status === "complete" && result.regeocode) {
        const address = result.regeocode.formattedAddress;
        resolve(address);
      } else {
        reject("根据经纬度查询地址失败");
      }
    });
  });
};

const handleMapClick = async (ev) => {
  open.value = true;
  form.value.coordinate = `${ev.lnglat.lng},${ev.lnglat.lat}`;
  form.value.address = await regeoCode([ev.lnglat.lng, ev.lnglat.lat]);
};

/** 提交按钮 */
function submitForm() {
  proxy.$refs["siteRef"].validate((valid) => {
    if (valid) {
      if (form.value.siteId != null) {
        updateSite(form.value).then((response) => {
          proxy.$modal.msgSuccess("修改成功");
          open.value = false;
          back();
        });
      } else {
        addSite(form.value).then((response) => {
          proxy.$modal.msgSuccess("新增成功");
          open.value = false;
          back();
        });
      }
    }
  });
}

// 根据名称搜索地图标点
const searchPoint = (val /** 搜索建议选项 */, type) => {
  map.value.clearMap();
  form.value.fencePath = [];

  placeSearch.value.search(searchKeyword.value, (status, result) => {
    // TODO: 添加搜索结果标记
    if (status === "complete") {
      searchResultMarkers.value = result.poiList.pois.map((el, index) => {
        const marker = new AMap.value.Marker({
          map: map.value,
          position: new AMap.value.LngLat(el.location.lng, el.location.lat),
          extData: el,
          anchor: "bottom-center",
          content: `
              <div
                style="
                  background-image: url(${markBsPng});
                  width: 19px;
                  height: 31px;
                  background-size: cover;
                  color: #fff;
                  text-align: center;
                  font-size: 12px;
                  padding-top: 3px;
                "
              >
                ${index + 1}
              </div>
              `,
        });
        marker.on("mouseover", (ev) => {
          resultInfoWindow.value.setContent(`
            <div>
            ${ev.target.getExtData().name}</div>
            `);
          resultInfoWindow.value.open(map.value, [
            ev.lnglat.lng,
            ev.lnglat.lat,
          ]);
        });
        marker.on("click", handleResultClick);
        marker.on("mouseout", (ev) => {
          resultInfoWindow.value.close();
        });
        return marker;
      });
      map.value.setFitView(searchResultMarkers.value);
    }
  });
};

// 搜索结果点击
const handleResultClick = async (ev) => {
  const lnglat = ev.target.getExtData()?.location;
  if (!lnglat) return ElMessage.error("获取经纬度失败");
  let address;
  try {
    address = ev.target.getExtData()?.name ?? (await regeoCode(lnglat));
  } catch (error) {
    address = `${lnglat.lng},${lnglat.lat}`;
  }
  open.value = true;
  form.value.coordinate = `${lnglat.lng},${lnglat.lat}`;
  form.value.address = address;
};

function back() {
  reset();
  tab.closeOpenPage({ path: "/basic/site" });
}
// 表单重置
function reset() {
  form.value = {
    siteId: null,
    siteName: null,
    groupId: null,
    province: null,
    city: null,
    area: null,
    address: null,
    coordinate: null,
    remark: null,
    createBy: null,
    createTime: null,
    uuid: null,
    tenantId: null,
  };
  proxy.resetForm("siteRef");
}

onMounted(async () => {});

listSiteGroup().then((resp) => {
  siteGroupList.value = resp.rows;
});

reset();
onMounted(async () => {
  // load form
  if (route.query.siteId && route.query.uuid) {
    const routerObj = Object.assign({}, route, { title: "站点修改" });
    tab.updatePage(routerObj);
    const resp = await getSite(route.query.siteId, route.query.uuid);
    form.value = resp.data;
    open.value = true;
    title.value = "修改站点";
  } else {
    open.value = true;
    title.value = "添加站点";
  }
  // 加载地图
  const _AMap = await loadAMap([
    "AMap.Scale",
    "AMap.Geocoder",
    "AMap.PlaceSearch",
  ]);
  AMap.value = _AMap;
  map.value = new AMap.value.Map("map-container", {
    zoom: 16, // 缩放级别
    center: [117.290345, 31.797813], // 中心点
  });
  resultInfoWindow.value = new AMap.value.InfoWindow({
    anchor: "bottom-center",
    offset: new AMap.value.Pixel(0, -31),
  });
  siteMarker.value = new AMap.value.Marker();
  // 地点搜索插件
  placeSearch.value = new AMap.value.PlaceSearch({
    city: "0551",
  });
  geocoder.value = new AMap.value.Geocoder();
  map.value.on("click", handleMapClick);
  map.value.addControl(new AMap.value.Scale());

  // TODO:
  if (form.value.coordinate) {
    siteMarker.value.setPosition(
      new AMap.value.LngLat(...form.value.coordinate.split(","))
    );
    map.value.add(siteMarker.value);
    map.value.setFitView([siteMarker.value]);
  }
});
</script>

<style lang="scss" scoped>
#map-container {
  width: 100%;
  height: calc(100vh - 84px);
}
.search-bar {
  z-index: 99;
  width: 300px;
  position: absolute;
  left: 20px;
  top: 20px;
}
// :deep(.map-select) {
// }
</style>
