<template>
  <el-dialog
    title="选择发生地点"
    :visible.sync="dialogVisible"
    width="80%"
    :before-close="handleClose"
    append-to-body
    modal-append-to-body
  >
    <!-- 搜索框 -->
    <div class="location-picker-search" style="margin-bottom: 16px;">
      <el-input
        v-model="searchKeyword"
        placeholder="搜索地点、地址或POI名称"
        clearable
        @keyup.enter.native="handleSearch"
      >
        <el-button 
          slot="append" 
          icon="el-icon-search" 
          @click="handleSearch"
        >
          搜索
        </el-button>
      </el-input>
      
      <!-- 搜索结果列表 -->
      <div v-if="searchResults.length > 0" class="location-search-results">
        <div 
          v-for="(item, index) in searchResults" 
          :key="index"
          class="search-result-item"
          @click="selectSearchResult(item)"
        >
          <div class="result-name">{{ item.name }}</div>
          <div class="result-address">{{ item.address }}</div>
        </div>
      </div>
    </div>

    <div class="location-picker-container">
      <div class="location-picker-map">
        <Amap 
          ref="locationPickerMap"
          container-id="location-picker-map-container"
          height="500px"
          :center="mapCenter"
          :zoom="15"
          :markers="mapMarkers"
        />
      </div>
      <div class="location-picker-info" v-if="selectedLocation">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="地址">
            {{ selectedLocation.address || '正在解析...' }}
          </el-descriptions-item>
          <el-descriptions-item label="经度">
            {{ selectedLocation.lng.toFixed(6) }}
          </el-descriptions-item>
          <el-descriptions-item label="纬度">
            {{ selectedLocation.lat.toFixed(6) }}
          </el-descriptions-item>
        </el-descriptions>
      </div>
      <div class="location-picker-info" v-else>
        <el-alert
          title="请在地图上点击选择位置或搜索地点"
          type="info"
          :closable="false"
          show-icon
        >
        </el-alert>
      </div>
    </div>
    <div slot="footer" class="dialog-footer">
      <el-button @click="handleClose">取消</el-button>
      <el-button type="primary" @click="handleConfirm" :disabled="!selectedLocation">
        确认选择
      </el-button>
    </div>
  </el-dialog>
</template>

<script>
import Amap from '@/components/Amap'

export default {
  name: 'LocationPickerDialog',
  components: {
    Amap
  },
  props: {
    visible: {
      type: Boolean,
      default: false
    },
    initialLocation: {
      type: Object,
      default: null
    }
  },
  data() {
    return {
      dialogVisible: false,
      mapCenter: [120.1551, 30.2741], // 默认中心点（杭州）
      mapMarkers: [],
      selectedLocation: null, // { lng, lat, address }
      geocoder: null, // AMap.Geocoder 实例
      placeSearch: null, // AMap.PlaceSearch 实例
      searchKeyword: '',
      searchResults: []
    }
  },
  watch: {
    visible(newVal) {
      this.dialogVisible = newVal
      if (newVal) {
        this.openDialog()
      }
    },
    dialogVisible(newVal) {
      if (!newVal) {
        this.$emit('update:visible', false)
      }
    }
  },
  methods: {
    openDialog() {
      // 如果已有位置，使用现有位置作为中心点
      if (this.initialLocation && this.initialLocation.longitude && this.initialLocation.latitude) {
        this.mapCenter = [this.initialLocation.longitude, this.initialLocation.latitude]
        this.mapMarkers = [{
          lat: this.initialLocation.latitude,
          lng: this.initialLocation.longitude,
          title: '当前位置'
        }]
      } else {
        this.mapCenter = [120.1551, 30.2741]
        this.mapMarkers = []
      }
      
      this.selectedLocation = null
      this.searchResults = []
      this.searchKeyword = ''
      
      // 等待对话框完全打开后再初始化
      this.$nextTick(() => {
        this.initMap()
        this.initGeocoder()
        this.initPlaceSearch()
      })
    },
    
    initMap() {
      // 等待地图组件加载完成
      let retryCount = 0
      const maxRetries = 30
      const checkInterval = setInterval(() => {
        retryCount++
        const mapComponent = this.$refs.locationPickerMap
        if (mapComponent && mapComponent.map) {
          clearInterval(checkInterval)
          const map = mapComponent.map
          
          // 确保地图尺寸正确
          setTimeout(() => {
            map.getSize() // 触发地图尺寸计算
            map.resize() // 强制地图重新计算尺寸
          }, 100)
          
          // 添加地图点击事件
          map.on('click', (e) => {
            this.handleMapClick(e)
          })
          
          console.log('位置选择器地图点击事件已绑定')
        } else if (retryCount >= maxRetries) {
          clearInterval(checkInterval)
          console.warn('位置选择器地图加载超时')
        }
      }, 100)
    },
    
    handleMapClick(event) {
      if (!event || !event.lnglat) return
      
      const lng = event.lnglat.lng
      const lat = event.lnglat.lat
      
      // 更新选中位置
      this.selectedLocation = {
        lng: lng,
        lat: lat,
        address: '正在解析地址...'
      }
      
      // 更新地图标记
      this.mapMarkers = [{
        lat: lat,
        lng: lng,
        title: '选择的位置'
      }]
      
      // 更新地图中心
      this.mapCenter = [lng, lat]
      
      // 反向地理编码获取地址
      this.reverseGeocode(lng, lat)
    },
    
    initGeocoder() {
      if (!window.AMap) {
        console.warn('AMap 未加载，无法初始化地理编码器')
        return
      }
      
      if (this.geocoder) {
        return
      }
      
      if (window.AMap.Geocoder && typeof window.AMap.Geocoder === 'function') {
        try {
          this.geocoder = new window.AMap.Geocoder({
            city: '全国'
          })
          console.log('地理编码器初始化成功（直接创建）')
          return
        } catch (error) {
          console.error('地理编码器创建失败:', error)
        }
      }
      
      window.AMap.plugin('AMap.Geocoder', () => {
        try {
          if (window.AMap.Geocoder && typeof window.AMap.Geocoder === 'function') {
            this.geocoder = new window.AMap.Geocoder({
              city: '全国'
            })
            console.log('地理编码器初始化成功（插件加载后）')
          }
        } catch (error) {
          console.error('地理编码器初始化失败:', error)
        }
      })
    },
    
    reverseGeocode(lng, lat) {
      if (!this.geocoder) {
        this.initGeocoder()
        
        let retryCount = 0
        const maxRetries = 20
        const checkInterval = setInterval(() => {
          retryCount++
          if (this.geocoder) {
            clearInterval(checkInterval)
            this.performReverseGeocode(lng, lat)
          } else if (retryCount >= maxRetries) {
            clearInterval(checkInterval)
            if (this.selectedLocation) {
              this.selectedLocation.address = '地址解析失败（插件加载超时）'
            }
          }
        }, 100)
        return
      }
      
      this.performReverseGeocode(lng, lat)
    },
    
    performReverseGeocode(lng, lat) {
      if (!this.geocoder) {
        if (this.selectedLocation) {
          this.selectedLocation.address = '地址解析失败（地理编码器未初始化）'
        }
        return
      }
      
      try {
        this.geocoder.getAddress([lng, lat], (status, result) => {
          if (status === 'complete' && result && result.info === 'OK') {
            const formattedAddress = result.regeocode?.formattedAddress
            const addressComponent = result.regeocode?.addressComponent
            
            const address = formattedAddress || 
              (addressComponent?.province || '') + 
              (addressComponent?.city || '') + 
              (addressComponent?.district || '') + 
              (addressComponent?.street || '') + 
              (addressComponent?.streetNumber || '')
            
            if (this.selectedLocation) {
              this.selectedLocation.address = address || '地址解析失败'
            }
          } else if (result && result.status === 1) {
            const address = result.regeocode?.formattedAddress || 
              (result.regeocode?.addressComponent?.province || '') +
              (result.regeocode?.addressComponent?.city || '') +
              (result.regeocode?.addressComponent?.district || '')
            
            if (this.selectedLocation) {
              this.selectedLocation.address = address || '地址解析失败'
            }
          } else {
            if (this.selectedLocation) {
              this.selectedLocation.address = '地址解析失败'
            }
          }
        })
      } catch (error) {
        console.error('地理编码异常:', error)
        if (this.geocoder.getAddress && typeof this.geocoder.getAddress === 'function') {
          try {
            const promise = this.geocoder.getAddress([lng, lat])
            if (promise && typeof promise.then === 'function') {
              promise.then((result) => {
                if (result && result.status === 1) {
                  const address = result.regeocode?.formattedAddress || 
                    (result.regeocode?.addressComponent?.province || '') +
                    (result.regeocode?.addressComponent?.city || '') +
                    (result.regeocode?.addressComponent?.district || '')
                  
                  if (this.selectedLocation) {
                    this.selectedLocation.address = address || '地址解析失败'
                  }
                } else {
                  if (this.selectedLocation) {
                    this.selectedLocation.address = `地址解析失败 (status: ${result?.status})`
                  }
                }
              }).catch((error) => {
                console.error('Promise地理编码错误:', error)
                if (this.selectedLocation) {
                  this.selectedLocation.address = '地址解析失败（网络错误）'
                }
              })
            }
          } catch (e) {
            console.error('Promise方式也失败:', e)
            if (this.selectedLocation) {
              this.selectedLocation.address = '地址解析失败（API错误）'
            }
          }
        } else {
          if (this.selectedLocation) {
            this.selectedLocation.address = '地址解析失败（方法不存在）'
          }
        }
      }
    },
    
    initPlaceSearch() {
      if (!window.AMap) {
        return
      }
      
      if (this.placeSearch) {
        return
      }
      
      window.AMap.plugin('AMap.PlaceSearch', () => {
        try {
          this.placeSearch = new window.AMap.PlaceSearch({
            city: '全国',
            pageSize: 10,
            pageIndex: 1
          })
          console.log('地点搜索初始化成功')
        } catch (error) {
          console.error('地点搜索初始化失败:', error)
        }
      })
    },
    
    handleSearch() {
      if (!this.searchKeyword || this.searchKeyword.trim() === '') {
        this.$message.warning('请输入搜索关键词')
        return
      }
      
      if (!this.placeSearch) {
        this.initPlaceSearch()
        
        let retryCount = 0
        const maxRetries = 20
        const checkInterval = setInterval(() => {
          retryCount++
          if (this.placeSearch) {
            clearInterval(checkInterval)
            this.performLocationSearch()
          } else if (retryCount >= maxRetries) {
            clearInterval(checkInterval)
            this.$message.error('搜索功能初始化失败，请稍后重试')
          }
        }, 100)
        return
      }
      
      this.performLocationSearch()
    },
    
    performLocationSearch() {
      if (!this.placeSearch) {
        return
      }
      
      this.placeSearch.search(this.searchKeyword, (status, result) => {
        if (status === 'complete' && result.info === 'OK') {
          this.searchResults = result.poiList.pois.map(poi => ({
            name: poi.name,
            address: poi.address,
            location: poi.location,
            lng: poi.location.lng,
            lat: poi.location.lat
          }))
          console.log('搜索成功，找到', this.searchResults.length, '个结果')
        } else {
          this.searchResults = []
          this.$message.warning('未找到相关地点，请尝试其他关键词')
        }
      })
    },
    
    selectSearchResult(item) {
      const lng = item.lng
      const lat = item.lat
      
      this.selectedLocation = {
        lng: lng,
        lat: lat,
        address: item.address || item.name
      }
      
      this.mapMarkers = [{
        lat: lat,
        lng: lng,
        title: item.name
      }]
      this.mapCenter = [lng, lat]
      
      this.searchResults = []
      this.searchKeyword = ''
      
      if (!item.address || item.address === '') {
        this.selectedLocation.address = '正在解析地址...'
        this.reverseGeocode(lng, lat)
      }
    },
    
    handleConfirm() {
      // 如果未通过地图点击或搜索选中位置，则回退到初始位置
      const fallback = this.initialLocation && this.initialLocation.longitude && this.initialLocation.latitude
        ? {
            lng: this.initialLocation.longitude,
            lat: this.initialLocation.latitude,
            address: this.initialLocation.address
          }
        : null

      const result = this.selectedLocation || fallback

      if (!result || result.lng == null || result.lat == null) {
        this.$message.warning('请在地图上选择位置或提供有效的经纬度')
        return
      }

      this.$emit('confirm', {
        lng: result.lng,
        lat: result.lat,
        address: result.address
      })

      this.dialogVisible = false
      this.$message.success('位置已选择')
    },
    
    handleClose(done) {
      // 重置状态
      this.selectedLocation = null
      this.mapMarkers = []
      this.searchResults = []
      this.searchKeyword = ''
      
      // 如果是 before-close 回调，调用 done()
      if (typeof done === 'function') {
        done()
      }
      
      // 无论哪种方式，都发出关闭事件
      this.dialogVisible = false
    }
  }
}
</script>

<style lang="scss" scoped>
.location-picker-search {
  margin-bottom: 16px;
}

.location-search-results {
  margin-top: 12px;
  max-height: 200px;
  overflow-y: auto;
  border: 1px solid #ebeef5;
  border-radius: 4px;
}

.search-result-item {
  padding: 12px;
  cursor: pointer;
  border-bottom: 1px solid #ebeef5;
  transition: background-color 0.3s;
}

.search-result-item:last-child {
  border-bottom: none;
}

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

.result-name {
  font-weight: 600;
  color: #303133;
  margin-bottom: 4px;
}

.result-address {
  font-size: 12px;
  color: #909399;
}

.location-picker-container {
  display: flex;
  gap: 16px;
}

.location-picker-map {
  flex: 1;
  min-width: 0;
}

.location-picker-info {
  width: 300px;
  flex-shrink: 0;
}
</style>