<template>
  <el-dialog
   draggable
    v-model="dialogVisible"
    :title="title"
    :width="dialogWidth"
    
    :close-on-click-modal="false"
    @closed="handleDialogClosed"
    class="map-picker-dialog"
  >
    <!-- 地图容器 -->
    <div ref="mapContainer" class="map-container"></div>

    <!-- 工具栏 -->
    <div class="toolbar">
      <el-space :size="10">
        <el-input
          v-model="searchAddress"
          placeholder="输入地址搜索"
          clearable
          @keyup.enter="handleAddressSearch"
          style="width: 300px"
        >
          <template #prepend>
            <el-icon><Search /></el-icon>
          </template>
        </el-input>

        <el-button-group>
          <el-button type="primary" @click="handleAddressSearch"> 搜索地址 </el-button>
        </el-button-group>
      </el-space>
    </div>

    <!-- 结果展示区域 -->
    <div class="result-panel">
      <el-descriptions
        :title="selectedPoint ? '拾取结果' : '操作提示'"
        :column="1"
        border
        size="small"
      >
        <el-descriptions-item label="坐标" v-if="selectedPoint">
          {{ selectedPoint.lng }}, {{ selectedPoint.lat }}
          
        </el-descriptions-item>

        <el-descriptions-item label="地址" v-if="selectedPoint">
          {{ selectedPoint.address }}
        </el-descriptions-item>

        <el-descriptions-item label="操作提示" v-if="!selectedPoint">
          <span class="tip-text"> 点击地图选择位置，或输入地址进行搜索 </span>
        </el-descriptions-item>
      </el-descriptions>
    </div>

    <template #footer>
      <span class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm" :disabled="!selectedPoint">
          确认选择
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script setup>
import { ref, watch, nextTick, computed } from 'vue'
import { Search, CopyDocument, Plus, Minus, Location, FullScreen } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'

const props = defineProps({
  modelValue: {
    type: Boolean,
    default: false
  },
  // 对话框标题
  title: {
    type: String,
    default: '地图坐标拾取器'
  },
  // 初始中心点
  initCenter: {
    type: Object,
    default: () => ({ lng: 116.404, lat: 39.915 })
  },
  // 初始缩放级别
  initZoom: {
    type: Number,
    default: 12
  },
  // 对话框宽度
  width: {
    type: String,
    default: '900px'
  }
})

// 自定义事件
const emit = defineEmits(['update:modelValue', 'select'])

// 响应式数据
const dialogVisible = ref(props.modelValue)
const mapContainer = ref(null)
const searchAddress = ref('')
const inputLng = ref('')
const inputLat = ref('')
const selectedPoint = ref(null)
const hasGeolocation = ref('geolocation' in navigator)
const isFullscreen = ref(false)

let map = null
let geocoder = null
let currentMarker = null
let infoWindow = null

const dialogWidth = computed(() => {
  return isFullscreen.value ? '100%' : props.width
})

// 监听 modelValue 变化
watch(
  () => props.modelValue,
  (val) => {
    dialogVisible.value = val
    if (val) {
      // 对话框打开时初始化地图
      nextTick(() => {
        initMap()
      })
    }
  }
)

// 监听对话框可见性变化
watch(dialogVisible, (val) => {
  emit('update:modelValue', val)
  if (!val) {
    cleanupMap()
  }
})

// 初始化地图
const initMap = () => {
  // 如果容器不存在或已初始化，则返回
  if (!mapContainer.value || map) return

  // 动态加载百度地图API
  if (!window.BMap) {
    loadBaiduMapAPI()
    return
  }

  nextTick(() => {
    try {
      // 创建地图实例
      map = new BMap.Map(mapContainer.value)
      map.centerAndZoom(new BMap.Point(props.initCenter.lng, props.initCenter.lat), props.initZoom)

      // 启用控件和交互
      map.enableScrollWheelZoom(true)
      map.addControl(new BMap.NavigationControl())
      map.addControl(new BMap.ScaleControl())

      // 初始化地理编码器
      geocoder = new BMap.Geocoder()

      // 绑定地图点击事件
      map.addEventListener('click', handleMapClick)

      console.log('百度地图初始化完成')
    } catch (error) {
      console.error('地图初始化失败:', error)
      ElMessage.error('地图初始化失败，请检查API Key和网络连接')
    }
  })
}

// 动态加载百度地图API
const loadBaiduMapAPI = () => {
  return new Promise((resolve, reject) => {
    if (window.BMap) {
      initMap()
      resolve()
      return
    }

    const script = document.createElement('script')
    script.type = 'text/javascript'
    script.src = `https://api.map.baidu.com/api?v=3.0&ak=c0crhdxQ5H7WcqbcazGr7mnHrLa4GmO0&type=webgl&callback=initBaiduMapCallback`

    // 设置超时
    const timeoutId = setTimeout(() => {
      reject(new Error('百度地图API加载超时'))
    }, 10000)

    // 全局回调函数
    window.initBaiduMapCallback = () => {
      clearTimeout(timeoutId)
      nextTick(() => {
        initMap()
      })
      resolve()
    }

    script.onerror = () => {
      clearTimeout(timeoutId)
      reject(new Error('百度地图API加载失败'))
    }

    document.head.appendChild(script)
  })
}

// 地图点击事件处理
const handleMapClick = (e) => {
  const point = e.point

  // 反向地理编码获取地址信息
  geocoder.getLocation(point, (result) => {
    if (result) {
      const pointData = {
        lng: point.lng.toFixed(6),
        lat: point.lat.toFixed(6),
        address: result.address,
        formattedAddress: formatAddress(result),
        pois: result.surroundingPois || [],
        rawPoint: point // 保存原始点对象供后续使用
      }

      selectedPoint.value = pointData

      // 添加标记
      addMarker(point, result.address)

      // 触发选择事件
      emit('select', pointData)
    }
  })
}

// 地址搜索
const handleAddressSearch = async () => {
  if (!searchAddress.value.trim()) {
    ElMessage.warning('请输入搜索地址')
    return
  }

  if (!geocoder) {
    ElMessage.warning('地图服务正在初始化，请稍后再试')
    return
  }

  try {
    // 使用 LocalSearch 进行地址搜索
    const local = new BMap.LocalSearch(map, {
      onSearchComplete: function (results) {
        if (local.getStatus() == BMAP_STATUS_SUCCESS) {
          // 获取第一个搜索结果
          if (results.getNumPois() > 0) {
            const poi = results.getPoi(0)
            const point = poi.point

            map.centerAndZoom(point, 16)

            // 获取详细地址信息
            geocoder.getLocation(point, (result) => {
              const pointData = {
                lng: point.lng.toFixed(6),
                lat: point.lat.toFixed(6),
                address: result?.address || poi.title,
                formattedAddress: result ? formatAddress(result) : '',
                pois: result?.surroundingPois || [],
                rawPoint: point
              }

              selectedPoint.value = pointData
              addMarker(point, result?.address || poi.title)

              emit('select', pointData)
            })
          } else {
            ElMessage.warning('未找到该地址对应的坐标')
          }
        } else {
          ElMessage.warning('未找到该地址对应的坐标')
        }
      }
    })

    local.search(searchAddress.value)
  } catch (error) {
    console.error('地址搜索失败:', error)
    ElMessage.error('地址搜索失败，请重试')
  }
}

// 添加标记点
const addMarker = (point, title) => {
  // 清除旧标记
  if (currentMarker) {
    map.removeOverlay(currentMarker)
    if (infoWindow) {
      map.closeInfoWindow(infoWindow)
    }
  }

  // 创建新标记
  currentMarker = new BMap.Marker(point)
  map.addOverlay(currentMarker)

  // 创建信息窗口
  infoWindow = new BMap.InfoWindow(title, {
    width: 250,
    height: 60
  })

  // 标记点击事件
  currentMarker.addEventListener('click', () => {
    currentMarker.openInfoWindow(infoWindow)
  })

  currentMarker.openInfoWindow(infoWindow)
}

const formatAddress = (result) => {
  if (!result || !result.addressComponents) return ''

  const addr = result.addressComponents
  const components = []

  if (addr.province) components.push(addr.province)
  if (addr.city && addr.city !== addr.province) components.push(addr.city)
  if (addr.district) components.push(addr.district)
  if (addr.street) components.push(addr.street)
  if (addr.streetNumber) components.push(addr.streetNumber)

  return components.join('')
}

const copyCoordinates = async () => {
  if (!selectedPoint.value) return

  const text = `${selectedPoint.value.lng}, ${selectedPoint.value.lat}`

  try {
    await navigator.clipboard.writeText(text)
    ElMessage.success('坐标已复制到剪贴板')
  } catch (err) {
    // 降级方案
    const textArea = document.createElement('textarea')
    textArea.value = text
    document.body.appendChild(textArea)
    textArea.select()
    document.execCommand('copy')
    document.body.removeChild(textArea)
    ElMessage.success('坐标已复制')
  }
}

// 地图控制方法
const zoomIn = () => {
  if (map) map.zoomIn()
}

const zoomOut = () => {
  if (map) map.zoomOut()
}

const handleDialogClosed = () => {
  cleanupMap()
}

const cleanupMap = () => {
  if (currentMarker) {
    map?.removeOverlay(currentMarker)
    currentMarker = null
  }
  if (infoWindow) {
    map?.closeInfoWindow(infoWindow)
    infoWindow = null
  }
  selectedPoint.value = null
  searchAddress.value = ''
  inputLng.value = ''
  inputLat.value = ''
}

const handleConfirm = () => {
  if (!selectedPoint.value) {
    ElMessage.warning('请先选择坐标点')
    return
  }

  emit('confirm', selectedPoint.value)
  dialogVisible.value = false
}

const handleCancel = () => {
  emit('cancel')
  dialogVisible.value = false
}

defineExpose({
  openDialog: () => {
    dialogVisible.value = true
  },
  closeDialog: () => {
    dialogVisible.value = false
  },
  getSelectedPoint: () => selectedPoint.value,
  clearSelection: () => {
    cleanupMap()
  }
})
</script>

<style scoped>
.map-picker-dialog {
  :deep(.el-dialog__body) {
    padding: 0;
    display: flex;
    flex-direction: column;
    height: 70vh;
  }
}

.map-container {
  flex: 1;
  min-height: 65vh;
  background: #f5f5f5;
}

.toolbar {
  padding: 15px;
  background: white;
  border-bottom: 1px solid #ebeef5;
}

.result-panel {
  padding: 15px;
  background: white;
  border-top: 1px solid #ebeef5;
  max-height: 200px;
  overflow-y: auto;
}

.copy-btn {
  margin-left: 10px;
  padding: 2px 4px;
}

.tip-text {
  color: #909399;
  font-style: italic;
}

.poi-section {
  margin-top: 10px;
}

.poi-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.poi-item {
  padding: 6px 8px;
  border-bottom: 1px solid #f0f0f0;
  cursor: pointer;
  display: flex;
  justify-content: space-between;
  align-items: center;
  transition: background-color 0.2s;
}

.poi-item:hover {
  background-color: #f5f7fa;
}

.poi-title {
  font-size: 13px;
  color: #303133;
}

.poi-distance {
  font-size: 12px;
  color: #909399;
}

.map-controls {
  position: absolute;
  top: 85px;
  right: 20px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  z-index: 1000;
}

.map-controls .el-button-group {
  display: flex;
  flex-direction: column;
}

.dialog-footer {
  display: flex;
  justify-content: flex-end;
  align-items: center;
}
</style>
