<template>
  <div class="map-container">
    <div class="map-wrapper">
      <!-- 地图容器 -->
      <div
        id="map-container"
        class="map-area"
        v-loading="mapLoading"
        element-loading-text="正在加载地图..."
      ></div>

      <!-- 附近地点列表 -->
      <div class="poi-list">
        <div class="poi-header">
          <h4>附近地点</h4>
        </div>

        <div class="poi-content" v-loading="poiLoading">
          <div
            v-for="(poi, index) in nearbyPOIs"
            :key="index"
            class="poi-item"
            @click="selectPOI(poi)"
          >
            <div class="poi-info">
              <div class="poi-name">{{ poi.name }}</div>
              <div class="poi-address">{{ poi.address }}</div>
              <div class="poi-distance">距离: {{ poi.distance }}米</div>
            </div>
            <el-icon class="poi-icon"><Location /></el-icon>
          </div>

          <div v-if="nearbyPOIs.length === 0 && !poiLoading" class="no-data">暂无附近地点</div>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, nextTick } from 'vue'
import { ElMessage } from 'element-plus'
import { Location } from '@element-plus/icons-vue'
import AMapLoader from '@amap/amap-jsapi-loader'

// 组件名称用于调试
defineOptions({
  name: 'MapComponent',
})

// Props 定义
interface Props {
  province?: string
  city?: string
  district?: string
  address?: string
  longitude?: number | null
  latitude?: number | null
}

const props = withDefaults(defineProps<Props>(), {
  province: '',
  city: '',
  district: '',
  address: '',
  longitude: null,
  latitude: null,
})

// Emits 定义
const emit = defineEmits<{
  'update-location': [data: {
    address: string
    longitude: number
    latitude: number
    province?: string
    city?: string
    district?: string
  }]
}>()

// 响应式数据
const mapLoading = ref(true)
const poiLoading = ref(false)
const map = ref<any>(null)
const marker = ref<any>(null)
const geocoder = ref<any>(null)
const placeSearch = ref<any>(null)
const nearbyPOIs = ref<any[]>([])
const mapInitialized = ref(false)

// POI 类型定义
interface POIItem {
  name: string
  address: string
  distance: number
  location: [number, number]
}

// 高德地图API Key (从环境变量获取)
const AMAP_KEY = import.meta.env.VITE_AMAP_API_KEY || 'your-amap-api-key'

// 初始化地图
const initMap = async () => {
  try {
    if (mapInitialized.value) return

    mapLoading.value = true

    // 加载高德地图
    const AMap = await AMapLoader.load({
      key: AMAP_KEY,
      version: '2.0',
      plugins: ['AMap.Geocoder', 'AMap.PlaceSearch', 'AMap.Marker'],
    })

    // 创建地图实例
    map.value = new AMap.Map('map-container', {
      zoom: 15,
      center: [116.397428, 39.90923], // 默认北京
      mapStyle: 'amap://styles/normal',
      resizeEnable: true,
    })

    // 初始化地理编码
    geocoder.value = new AMap.Geocoder({
      city: '全国',
    })

    // 初始化POI搜索
    placeSearch.value = new AMap.PlaceSearch({
      city: '全国',
      pageSize: 10,
      pageIndex: 1,
    })

    // 添加地图点击事件
    map.value.on('click', handleMapClick)

    mapInitialized.value = true
    mapLoading.value = false

    // 初始化完成后，根据传入的数据定位
    await initialLocate()
  } catch (error) {
    mapLoading.value = false
    ElMessage.error('地图加载失败，请刷新重试')
  }
}

// 初始定位
const initialLocate = async () => {
  // 优先使用经纬度定位
  if (props.longitude && props.latitude) {
    await locateByCoordinates(props.longitude, props.latitude)
  } 
  // 其次使用地址定位
  else if (props.address) {
    await geocodeAddress(props.address)
  }
}

// 根据经纬度定位
const locateByCoordinates = async (lng: number, lat: number) => {
  if (!map.value || !geocoder.value) return

  try {
    const lnglat = [lng, lat]
    
    // 更新地图位置
    updateMapLocation(lnglat)
    
    // 反向地理编码获取地址信息
    geocoder.value.getAddress(lnglat, (status: string, result: any) => {
      if (status === 'complete' && result.regeocode) {
        const regeocode = result.regeocode
        const addressComponent = regeocode.addressComponent || {}
        
        emit('update-location', {
          address: regeocode.formattedAddress,
          longitude: lng,
          latitude: lat,
          province: addressComponent.province,
          city: addressComponent.city,
          district: addressComponent.district,
        })
      }
    })
    
    // 搜索附近POI
    searchNearbyPOI()
  } catch (error) {
    console.error('经纬度定位失败:', error)
    ElMessage.error('定位失败')
  }
}

// 地理编码 - 将地址转换为坐标（暴露给父组件调用）
const geocodeAddress = async (address: string) => {
  if (!geocoder.value || !address) return

  try {
    geocoder.value.getLocation(address, (status: string, result: any) => {
      if (status === 'complete' && result.geocodes && result.geocodes.length > 0) {
        const geocode = result.geocodes[0]
        const location = geocode.location
        const addressComponent = geocode.addressComponent || {}
        
        updateMapLocation(location)
        searchNearbyPOI()
        
        // 发送更新事件
        emit('update-location', {
          address: geocode.formattedAddress || address,
          longitude: location.lng,
          latitude: location.lat,
          province: addressComponent.province,
          city: addressComponent.city,
          district: addressComponent.district,
        })
      } else {
        ElMessage.warning('地址解析失败，请检查地址信息')
      }
    })
  } catch (error) {
    console.error('地理编码失败:', error)
    ElMessage.error('地址解析出错')
  }
}

// 处理地图点击事件
const handleMapClick = (e: any) => {
  const lng = e.lnglat.getLng()
  const lat = e.lnglat.getLat()
  
  // 定位到点击位置
  locateByCoordinates(lng, lat)
}

// 更新地图位置
const updateMapLocation = (location: any) => {
  if (!map.value) return

  // 设置地图中心点
  map.value.setCenter(location)
  map.value.setZoom(16)

  // 清除之前的标记
  if (marker.value) {
    map.value.remove(marker.value)
  }

  // 创建新标记
  const AMap = (window as any).AMap
  marker.value = new AMap.Marker({
    position: location,
    title: '当前位置',
    icon: new AMap.Icon({
      size: new AMap.Size(30, 40),
      image: 'https://webapi.amap.com/theme/v1.3/markers/n/mark_r.png',
    }),
  })

  map.value.add(marker.value)
}

// 搜索附近POI
const searchNearbyPOI = async () => {
  if (!placeSearch.value || !marker.value) return

  try {
    poiLoading.value = true
    nearbyPOIs.value = []

    const location = marker.value.getPosition()

    placeSearch.value.searchNearBy(
      '',
      location,
      1000, // 搜索半径1000米
      (status: string, result: any) => {
        poiLoading.value = false

        if (status === 'complete' && result.poiList && result.poiList.pois) {
          nearbyPOIs.value = result.poiList.pois.map((poi: any) => ({
            name: poi.name,
            address: poi.address || poi.pname + poi.cityname + poi.adname,
            distance: Math.round(poi.distance || 0),
            location: [poi.location.lng, poi.location.lat],
          }))
        }
      },
    )
  } catch (error) {
    console.error('POI搜索失败:', error)
    poiLoading.value = false
  }
}

// 选择POI地点
const selectPOI = (poi: POIItem) => {
  // 定位到选中的POI
  locateByCoordinates(poi.location[0], poi.location[1])
  
  ElMessage.success(`已选择: ${poi.name}`)
}

// 监听属性变化
watch(
  [() => props.longitude, () => props.latitude],
  ([newLng, newLat]) => {
    if (mapInitialized.value && newLng && newLat) {
      locateByCoordinates(newLng, newLat)
    }
  },
)

watch(
  () => props.address,
  (newAddress) => {
    if (mapInitialized.value && newAddress && !props.longitude && !props.latitude) {
      geocodeAddress(newAddress)
    }
  },
)

// 暴露方法给父组件
defineExpose({
  geocodeAddress,
  locateByCoordinates,
})

// 组件挂载
onMounted(() => {
  initMap()
})
</script>

<style scoped>
/* 样式保持不变 */
.map-container {
  width: 100%;
  margin-top: 20px;
}

.map-wrapper {
  display: flex;
  gap: 0;
  border: 1px solid var(--el-border-color);
  border-radius: 12px;
  overflow: hidden;
  background: #fff;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
  transition: box-shadow 0.3s ease;
  height: 400px; /* 固定高度 */
}

.map-wrapper:hover {
  box-shadow: 0 6px 20px rgba(0, 0, 0, 0.12);
}

.map-area {
  flex: 1;
  height: 100%;
  min-width: 480px;
  position: relative;
}

#map-container {
  height: 100%;
  border-radius: 12px 0 0 12px;
}

.poi-list {
  width: 320px;
  border-left: 1px solid var(--el-border-color-lighter);
  display: flex;
  flex-direction: column;
  background: var(--el-bg-color);
}

.poi-header {
  padding: 20px 20px 16px;
  border-bottom: 1px solid var(--el-border-color-lighter);
  background: linear-gradient(135deg, var(--el-color-primary-light-9), var(--el-bg-color));
}

.poi-header h4 {
  margin: 0;
  font-size: 16px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  display: flex;
  align-items: center;
}

.poi-header h4::before {
  content: '📍';
  margin-right: 8px;
  font-size: 14px;
}

.poi-content {
  flex: 1;
  overflow-y: auto;
  max-height: 384px;
  padding: 8px 0;
}

/* 自定义滚动条 */
.poi-content::-webkit-scrollbar {
  width: 6px;
}

.poi-content::-webkit-scrollbar-track {
  background: var(--el-fill-color-lighter);
}

.poi-content::-webkit-scrollbar-thumb {
  background: var(--el-color-primary-light-5);
  border-radius: 3px;
}

.poi-content::-webkit-scrollbar-thumb:hover {
  background: var(--el-color-primary);
}

.poi-item {
  padding: 16px 20px;
  margin: 0 8px 4px;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
  display: flex;
  align-items: center;
  justify-content: space-between;
  position: relative;
}

.poi-item:hover {
  background: var(--el-color-primary-light-9);
  transform: translateY(-1px);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.poi-item:active {
  transform: translateY(0);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.1);
}

.poi-info {
  flex: 1;
  min-width: 0;
}

.poi-name {
  font-size: 15px;
  font-weight: 600;
  color: var(--el-text-color-primary);
  margin-bottom: 6px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.4;
}

.poi-address {
  font-size: 13px;
  color: var(--el-text-color-regular);
  margin-bottom: 4px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  line-height: 1.3;
}

.poi-distance {
  font-size: 12px;
  color: var(--el-color-primary);
  font-weight: 500;
  background: var(--el-color-primary-light-9);
  padding: 2px 8px;
  border-radius: 12px;
  display: inline-block;
}

.poi-icon {
  color: var(--el-color-primary);
  font-size: 18px;
  margin-left: 12px;
  transition: transform 0.2s ease;
}

.poi-item:hover .poi-icon {
  transform: scale(1.1);
}

.no-data {
  padding: 60px 20px;
  text-align: center;
  color: var(--el-text-color-placeholder);
  font-size: 14px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 12px;
}

.no-data::before {
  content: '🔍';
  font-size: 32px;
  opacity: 0.6;
}

/* 响应式设计 */
@media (max-width: 1024px) {
  .map-area {
    min-width: 400px;
  }

  .poi-list {
    width: 280px;
  }
}

@media (max-width: 768px) {
  .map-container {
    margin-top: 16px;
  }

  .map-wrapper {
    flex-direction: column;
    border-radius: 8px;
    height: auto;
  }

  .map-area {
    min-width: auto;
    height: 300px;
  }

  #map-container {
    border-radius: 8px 8px 0 0;
  }

  .poi-list {
    width: 100%;
    border-left: none;
    border-top: 1px solid var(--el-border-color-lighter);
  }

  .poi-header {
    padding: 16px;
    background: var(--el-bg-color-page);
  }

  .poi-header h4 {
    font-size: 15px;
  }

  .poi-content {
    max-height: 240px;
    padding: 4px 0;
  }

  .poi-item {
    padding: 12px 16px;
    margin: 0 4px 2px;
  }

  .poi-name {
    font-size: 14px;
  }

  .poi-address {
    font-size: 12px;
  }
}

/* 深色模式适配 */
@media (prefers-color-scheme: dark) {
  .map-wrapper {
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  }

  .map-wrapper:hover {
    box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
  }

  .poi-header {
    background: linear-gradient(135deg, var(--el-color-primary-light-7), var(--el-bg-color));
  }
}
</style>
