<template>
  <el-dialog
    v-model="dialogVisible"
    title="位置选择"
    width="800px"
    :before-close="handleClose"
    :close-on-click-modal="false"
    :close-on-press-escape="false"
    :show-close="false"
  >
    <div class="map-container" id="container">
      <div
        v-if="!props.modelValue.lat || !props.modelValue.lng"
        class="map-placeholder"
      ></div>
    </div>
    <div class="address-search">
      <el-select
        v-model="province"
        :placeholder="t('provincePlaceholder')"
        @change="handleProvinceChange"
      >
        <el-option
          v-for="item in provinceList"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <el-select
        v-model="city"
        :placeholder="t('cityPlaceholder')"
        @change="handleCityChange"
        :disabled="!province"
      >
        <el-option
          v-for="item in cityList"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <el-select
        v-model="district"
        :placeholder="t('districtPlaceholder')"
        @change="handleDistrictChange"
        :disabled="!province || !city"
      >
        <el-option
          v-for="item in districtList"
          :key="item.id"
          :label="item.name"
          :value="item.id"
        />
      </el-select>
      <el-input v-model="detailAddress" placeholder="输入地区" />
      <el-button
        type="primary"
        @click="handleAddressSearch"
        :disabled="!province || !city || !district"
        >{{ t('search') }}</el-button
      >
    </div>
    <template #footer>
      <span class="dialog-footer">
        <el-button @click="dialogVisible = false">{{ t('cancel') }}</el-button>
        <el-button type="primary" @click="handleConfirm">
          {{ t('confirm') }}
        </el-button>
      </span>
    </template>
  </el-dialog>
</template>

<script lang="ts" setup>
import { ref, onMounted, watch, computed, nextTick, onBeforeUnmount } from 'vue'
import { ElMessage } from 'element-plus'
import { getAreaListByPid } from '@/app/api/sys'
import { createMarker, addressToLatLng } from '@/utils/qqmap'
import { t } from '@/lang'

// ====================== Props定义 ======================
const props = defineProps({
  modelValue: {
    type: Object,
    default: () => ({
      lat: null,
      lng: null,
      address: '',
    }),
  },
  placeholder: {
    type: String,
    default: t('mapPickerPlaceholder'),
  },
  visible: {
    type: Boolean,
    default: false,
  },
})

const emit = defineEmits(['update:visible', 'update:modelValue', 'confirm'])

// ====================== 状态管理 ======================
const dialogVisible = computed({
  get() {
    return props.visible
  },
  set(value) {
    emit('update:visible', value)
  },
})

// 地图相关
let map: any = null
let marker: any = null
const mapKey = ref('YOUR_API_KEY') // 替换为你的API Key
let mapScript: HTMLScriptElement | null = null
let resizeTimer: number | null = null

// 区域选择
const province = ref('')
const city = ref('')
const district = ref('')
const detailAddress = ref('')
const provinceList = ref<any[]>([])
const cityList = ref<any[]>([])
const districtList = ref<any[]>([])

// ====================== 生命周期 ======================
onMounted(() => {
  // 预加载地图SDK（可选优化）
  const preloadScript = document.createElement('script')
  preloadScript.src = `https://map.qq.com/api/gljs?key= ${mapKey.value}`
  document.head.appendChild(preloadScript)
})

// ====================== 监听器 ======================
watch(
  dialogVisible,
  async (newVal) => {
    if (newVal) {
      try {
        // 清理旧实例
        cleanupMap()

        // 等待DOM更新
        await nextTick()

        // 确保容器存在
        const container = document.getElementById('container')
        if (!container) throw new Error('地图容器未找到')

        // 加载地图SDK
        await loadMapSDK()

        // 初始化地图
        initMap()

        // 获取省份数据
        const res = await getAreaListByPid(0)
        provinceList.value = res.data

        // 如果存在初始地址，进行解析
        if (props.modelValue.address) {
          await parseAndSetAddress(props.modelValue.address)
        }

        // 绑定resize监听器
        bindResizeListener()
      } catch (error) {
        handleError(error)
      }
    } else {
      cleanupMap()
    }
  },
  { immediate: true }
)

// ====================== 方法实现 ======================
const handleClose = (done: () => void) => {
  done()
}

const handleConfirm = () => {
  if (!props.modelValue.lat || !props.modelValue.lng) {
    ElMessage.warning(t('mapPickerWarning'))
    return
  }

  // 拼接完整地址
  const provinceName = province.value
    ? provinceList.value.find((p) => p.id === province.value)?.name || ''
    : ''
  const cityName = city.value
    ? cityList.value.find((c) => c.id === city.value)?.name || ''
    : ''
  const districtName = district.value
    ? districtList.value.find((d) => d.id === district.value)?.name || ''
    : ''

  const fullAddress = `${provinceName}${cityName}${districtName}${detailAddress.value}`

  emit('confirm', {
    lat: props.modelValue.lat,
    lng: props.modelValue.lng,
    address: fullAddress,
  })

  dialogVisible.value = false
}

// 地址解析逻辑
const parseAndSetAddress = async (address: string) => {
  // 解析地址
  const { provinceName, cityName, districtName, detail } = parseAddress(address)
  detailAddress.value = detail

  // 1. 处理省份选择
  if (provinceName) {
    const provinceItem = provinceList.value.find((p) =>
      p.name.includes(provinceName)
    )
    if (provinceItem) {
      province.value = provinceItem.id

      // 2. 处理城市选择
      const cityRes = await getAreaListByPid(province.value)
      cityList.value = cityRes.data

      if (cityName) {
        const cityItem = cityList.value.find((c) => c.name.includes(cityName))
        if (cityItem) {
          city.value = cityItem.id

          // 3. 处理区县选择
          const districtRes = await getAreaListByPid(city.value)
          districtList.value = districtRes.data

          if (districtName) {
            const districtItem = districtList.value.find((d) =>
              d.name.includes(districtName)
            )
            if (districtItem) {
              district.value = districtItem.id
            }
          }
        }
      }
    }
  }

  // 触发地址搜索
  handleAddressSearch()
}

// 地址拆分函数
const parseAddress = (address: string) => {
  let provinceName = ''
  let cityName = ''
  let districtName = ''
  let detail = address

  // 提取省/直辖市/自治区
  const provinceMatch = address.match(/^([^省市自治区]+[省市区]|[^市]+市)/)
  if (provinceMatch) {
    provinceName = provinceMatch[0]
    detail = address.slice(provinceName.length)
  }

  // 提取市
  const cityMatch = detail.match(/^([^市区]+市)/)
  if (cityMatch) {
    cityName = cityMatch[0]
    detail = detail.slice(cityName.length)
  }

  // 提取区/县
  const districtMatch = detail.match(/^([^区县]+[区县])/)
  if (districtMatch) {
    districtName = districtMatch[0]
    detail = detail.slice(districtName.length)
  }

  return {
    provinceName,
    cityName,
    districtName,
    detail: detail.trim() || '',
  }
}

// ====================== 地图相关方法 ======================
const cleanupMap = () => {
  if (mapScript) {
    document.body.removeChild(mapScript)
    mapScript = null
  }

  if (map) {
    map.destroy()
    map = null
  }

  marker = null

  if (resizeTimer) {
    clearTimeout(resizeTimer)
    resizeTimer = null
  }

  window.removeEventListener('resize', handleResize)
}

const loadMapSDK = (): Promise<void> => {
  return new Promise((resolve, reject) => {
    mapKey.value = 'AKTBZ-OGICT-E5NXQ-LGEGK-H5AJ5-M2BOX'

    mapScript = document.createElement('script')
    mapScript.type = 'text/javascript'
    mapScript.src = `https://map.qq.com/api/gljs?libraries=tools ,service&v=1.exp&key=${mapKey.value}`

    mapScript.onload = () => {
      if ((window as any).TMap) {
        resolve()
      } else {
        reject(new Error('TMap未定义'))
      }
    }

    mapScript.onerror = (error) => {
      reject(error)
    }

    document.body.appendChild(mapScript)
  })
}

const initMap = () => {
  const container = document.getElementById('container')
  if (!(window as any).TMap || !container) {
    throw new Error('地图SDK未加载或容器不存在')
  }

  const TMap = (window as any).TMap
  let center

  // 优先使用传入的坐标
  if (props.modelValue.lat && props.modelValue.lng) {
    center = new TMap.LatLng(props.modelValue.lat, props.modelValue.lng)
  } else {
    // 默认使用北京坐标
    center = new TMap.LatLng(39.90403, 116.407526)
  }

  // 创建地图实例
  map = new TMap.Map('container', {
    center,
    zoom: 12,
  })

  // 创建标记
  marker = createMarker(map)

  // 初始化时设置标记位置
  if (props.modelValue.lat && props.modelValue.lng) {
    marker.updateGeometries({
      id: 'center',
      position: new TMap.LatLng(props.modelValue.lat, props.modelValue.lng),
    })
  }

  // 地图点击事件
  map.on('click', (evt: any) => {
    map.setCenter(evt.latLng)
    marker.updateGeometries({
      id: 'center',
      position: evt.latLng,
    })
    emit('update:modelValue', {
      lat: evt.latLng.lat,
      lng: evt.latLng.lng,
      address: detailAddress.value,
    })
  })
}

const bindResizeListener = () => {
  window.addEventListener('resize', handleResize)
}

const handleResize = () => {
  if (resizeTimer) clearTimeout(resizeTimer)
  resizeTimer = setTimeout(() => {
    map?.setSize()
  }, 300)
}

// ====================== 区域选择处理 ======================
const handleProvinceChange = async (val: string) => {
  try {
    const res = await getAreaListByPid(val)
    cityList.value = res.data
    city.value = ''
    district.value = ''
  } catch (error) {
    handleError(error)
  }
}

const handleCityChange = async (val: string) => {
  try {
    const res = await getAreaListByPid(val)
    districtList.value = res.data
    district.value = ''
  } catch (error) {
    handleError(error)
  }
}

const handleDistrictChange = (val: string) => {
  // TODO: 处理区县选择
}

// 地址搜索
const handleAddressSearch = async () => {
  try {
    const address = [
      province.value
        ? provinceList.value.find((p) => p.id === province.value)?.name
        : '',
      city.value ? cityList.value.find((c) => c.id === city.value)?.name : '',
      district.value
        ? districtList.value.find((d) => d.id === district.value)?.name
        : '',
      detailAddress.value,
    ].join('')

    const { message, result } = await addressToLatLng({
      mapKey: mapKey.value,
      address,
    })

    if (message == 'Success' || message == 'query ok') {
      const latLng = new (window as any).TMap.LatLng(
        result.location.lat,
        result.location.lng
      )
      map.setCenter(latLng)
      marker.updateGeometries({
        id: 'center',
        position: latLng,
      })
      emit('update:modelValue', {
        lat: result.location.lat,
        lng: result.location.lng,
        address: detailAddress.value,
      })
    }
  } catch (error) {
    handleError(error)
  }
}

// ====================== 错误处理 ======================
const handleError = (error: any) => {
  console.error('地图组件错误:', error)
  ElMessage.error(t('mapLoadFailed'))
  dialogVisible.value = false
}

// 回显处理
watch(
  () => props.modelValue,
  (newVal) => {
    if (newVal?.lat && newVal?.lng && map) {
      try {
        const latLng = new (window as any).TMap.LatLng(newVal.lat, newVal.lng)
        map.setCenter(latLng)
        marker?.updateGeometries({
          id: 'center',
          position: latLng,
        })
      } catch (error) {
        console.warn('地图更新失败:', error)
      }
    }
  },
  {
    deep: true,
    immediate: true,
  }
)

onBeforeUnmount(() => {
  cleanupMap()
})
</script>

<style scoped>
.map-picker {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.map-container {
  width: 100%;
  height: 400px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  position: relative;
}

.map-placeholder {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  color: #909399;
  font-size: 14px;
}

.address-search {
  display: flex;
  gap: 8px;
  margin-top: 20px;
}
</style>
