<template>
	<el-dialog
		class="map-dialog"
		:style="{ width: '80%' }"
		:modelValue="modelValue"
		:show-close="true"
		@update:model-value="emit('update:modelValue', $event)"
		@open="open"
		@close="close"
	>
		<template #header="{ titleId, titleClass }">
			<div class="header">
				<h4 :id="titleId" :class="titleClass">坐标拾取</h4>
				<div class="search-container">
					<div class="search-item">
						<label class="search"><span>请输入地址：</span><el-input id="map-input" v-model="address" /></label>
						<!-- <el-button class="btn-search" type="primary">搜索</el-button> -->
					</div>
					<div class="search-item">
						<label class="address"><span>地址：</span><el-input disabled :model-value="coordinateInfo.address" /></label>
						<label class="lon"><span>经度：</span><el-input disabled :model-value="coordinateInfo.lng" /></label>
						<label class="lat"><span>纬度：</span><el-input disabled :model-value="coordinateInfo.lat" /></label>
						<el-button class="btn-submit" type="primary" @click="submit">提交</el-button>
					</div>
				</div>
			</div>
		</template>

		<div id="map-container" class="map"></div>
	</el-dialog>
</template>

<script lang="ts" setup>
import { ElMessage } from "element-plus";
import { ref, shallowRef, reactive } from "vue";
import initAMap from "./AMap";

defineProps<{ modelValue: boolean }>();
const emit = defineEmits<{
	(e: "update:modelValue", data: boolean): void;
	(e: "getAddress", data: typeof coordinateInfo): void;
}>();

const address = ref("");
const coordinateInfo = reactive({ address: "", lng: "", lat: "" });
const map = shallowRef<AMap.Map>();
const search = shallowRef<any>();
const autocomplete = shallowRef<any>();

const open = async () => {
	const AMap = await initAMap();

	// 地图加载与点击
	map.value = new AMap.Map("map-container", { zoom: 8, resizeEnable: true });
	map.value?.on("click", e => {
		map.value?.clearMap();
		map.value?.add(new AMap.Marker({ position: e.lnglat }));
		map.value?.setCenter(e.lnglat);
		coordinateInfo.lng = e.lnglat.getLng();
		coordinateInfo.lat = e.lnglat.getLat();
		const geocoder = new AMap.Geocoder();
		geocoder.getAddress(e.lnglat, (status: string, result: any) => {
			if (status === "complete" && result.info === "OK") {
				const regeocode = result.regeocode;
				coordinateInfo.address = regeocode.formattedAddress;
			}
		});
	});

	// 联想输入与 POI 搜索
	autocomplete.value = new AMap.AutoComplete({ extensions: "all", input: "map-input" });
	search.value = new AMap.PlaceSearch({ map: map.value, extensions: "base" });
	autocomplete.value?.on("select", (e: any) => {
		map.value?.clearMap();
		if (e.poi.location) {
			coordinateInfo.lng = e.poi.location.lng;
			coordinateInfo.lat = e.poi.location.lat;
			map.value?.add(new AMap.Marker({ position: e.poi.location }));
		} else {
			const geocoder = new AMap.Geocoder({ city: e.adcode });
			geocoder.getLocation(e.poi.name, (status: string, result: any) => {
				if (status === "complete" && result.info === "OK") {
					const data = result.geocodes;
					if (data.length > 1) ElMessage.success("检索到多个结果，已为您定位到第一个地址");
					coordinateInfo.lng = data[0].location.lng;
					coordinateInfo.lat = data[0].location.lat;
					map.value?.add(new AMap.Marker({ position: data[0].location }));
				}
			});
		}
		coordinateInfo.address = e.poi.district;
		search.value.setCity(e.poi.adcode);
		search.value.search(e.poi.name);
	});
};

const submit = () => {
	if (coordinateInfo.address && coordinateInfo.lng && coordinateInfo.lat) {
		emit("getAddress", coordinateInfo);
	}
};

const close = () => {
	map.value?.destroy();
	address.value = "";
	coordinateInfo.address = "";
	coordinateInfo.lng = "";
	coordinateInfo.lat = "";
};
</script>

<style lang="scss" scoped>
@import "./AMap.scss";
</style>
