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

interface Props {
  longitude?: number;
  latitude?: number;
  zoom?: number;
  height?: string;
  enableClickMark?: boolean;
  securityJsCode?: string;
  showSearch?: boolean; // 是否显示地址搜索框
  initialMarker?: boolean; // 是否在初始化时添加标记点
}

const props = withDefaults(defineProps<Props>(), {
  zoom: 15,
  height: "400px",
  enableClickMark: false,
  securityJsCode: "",
  showSearch: false,
  initialMarker: true // 默认添加初始标记点
});

const emit = defineEmits<{
  "update:longitude": [value: number];
  "update:latitude": [value: number];
  markerMoved: [lng: number, lat: number];
}>();

const mapContainer = ref<HTMLDivElement>();
const searchInput = ref("");
const mapLoading = ref(true);
const mapError = ref("");
const loadingProgress = ref(0);
const loadingStep = ref(0);
const showFallback = ref(false);

let map: any = null;
let marker: any = null;
let geocoder: any = null;
let placeSearch: any = null; // 使用 PlaceSearch 替代 Geocoder

const hasValidCoords = () => {
  return (
    props.longitude !== undefined &&
    props.latitude !== undefined &&
    props.longitude !== null &&
    props.latitude !== null &&
    props.longitude !== 0 &&
    props.latitude !== 0
  );
};

const updatePosition = (lng: number, lat: number) => {
  emit("update:longitude", lng);
  emit("update:latitude", lat);
  emit("markerMoved", lng, lat);
};

const addMarker = (lng: number, lat: number) => {
  if (!map || !AMap) return;

  if (marker) {
    map.remove(marker);
  }

  marker = new AMap.Marker({
    position: [lng, lat],
    title: "门店位置",
    draggable: props.enableClickMark,
    cursor: "move",
    animation: "AMAP_ANIMATION_DROP"
  });

  if (props.enableClickMark) {
    marker.on("dragend", (e: any) => {
      const lngLat = e.lnglat;
      updatePosition(lngLat.lng, lngLat.lat);
      addMarker(lngLat.lng, lngLat.lat);
    });
  }

  map.add(marker);
  map.setCenter([lng, lat]);
};

// 添加自定义标记（支持悬停事件和自定义颜色）
const addCustomMarker = (
  lng: number, 
  lat: number, 
  title: string, 
  events?: { 
    onClick?: () => void;
    onMouseEnter?: () => void;
    onMouseLeave?: () => void;
  }, 
  iconColor: string = 'red'
) => {
  if (!map || !AMap) {
    console.error('[addCustomMarker] map or AMap not initialized');
    return null;
  }

  // 使用 HTML 内容创建红色标记点（更可靠）
  let markerContent = '';
  if (iconColor === 'red') {
    markerContent = `<div style="
      position: relative;
      width: 25px;
      height: 34px;
    ">
      <svg width="25" height="34" viewBox="0 0 25 34" xmlns="http://www.w3.org/2000/svg">
        <path d="M12.5 0C5.6 0 0 5.6 0 12.5c0 9.4 12.5 21.5 12.5 21.5S25 21.9 25 12.5C25 5.6 19.4 0 12.5 0z" fill="#e74c3c"/>
        <circle cx="12.5" cy="12" r="5" fill="white"/>
      </svg>
    </div>`;
  }

  // 创建标记点
  const customMarker = new AMap.Marker({
    position: [lng, lat],
    title: title,
    cursor: "pointer",
    animation: "AMAP_ANIMATION_DROP",
    content: markerContent || undefined
  });

  console.log('[addCustomMarker] 标记点创建成功:', { lng, lat, title, iconColor });

  // 添加事件监听
  if (events) {
    if (events.onClick) {
      customMarker.on("click", events.onClick);
    }
    if (events.onMouseEnter) {
      customMarker.on("mouseover", events.onMouseEnter);
    }
    if (events.onMouseLeave) {
      customMarker.on("mouseout", events.onMouseLeave);
    }
  }

  // 添加到地图
  map.add(customMarker);
  
  return customMarker;
};

// 获取经纬度对应的像素坐标
const lngLatToPixel = (lng: number, lat: number): { x: number; y: number } | null => {
  if (!map) {
    console.error('[lngLatToPixel] 地图未初始化');
    return null;
  }
  
  try {
    const pixel = map.lngLatToContainer([lng, lat]);
    return { x: pixel.x, y: pixel.y };
  } catch (error) {
    console.error('[lngLatToPixel] 转换失败:', error);
    return null;
  }
};

const reloadMap = () => {
  if (map) {
    map.destroy();
    map = null;
  }
  showFallback.value = false;
  initMap();
};

const showFallbackMap = () => {
  showFallback.value = true;
  mapLoading.value = false;
  mapError.value = '';
};

const hideFallbackMap = () => {
  showFallback.value = false;
};

// 使用 PlaceSearch 进行地址搜索
const searchAddress = async (address: string) => {
  console.log('[地址搜索] 开始执行:', address);
  console.log('[地址搜索] placeSearch:', !!placeSearch);
  console.log('[地址搜索] AMap:', !!AMap);
  
  if (!placeSearch || !AMap) {
    console.error('[地址搜索] PlaceSearch 未初始化');
    alert('地图组件正在初始化，请稍后再试');
    return;
  }

  try {
    console.log('[地址搜索] 调用 search 方法...');
    
    const result = await new Promise((resolve, reject) => {
      let completed = false;
      
      const timeoutId = setTimeout(() => {
        if (!completed) {
          console.error('[地址搜索] 超时（10 秒）');
          reject(new Error('地址搜索超时，请检查网络或重试'));
        }
      }, 10000);
      
      placeSearch.search(address, (status: string, result: any) => {
        completed = true;
        clearTimeout(timeoutId);
        
        console.log('[地址搜索] 回调执行:', { status, hasResult: !!result, poiCount: result?.poiList?.count, errorInfo: result?.info });
        
        if (status === 'complete' && result.poiList && result.poiList.count > 0) {
          console.log('[地址搜索] 成功，解析结果');
          resolve(result.poiList.pois[0]); // 返回第一个结果
        } else {
          const errorMsg = result?.info || result?.infocode || '未找到该地址';
          console.error('[地址搜索] 详细错误:', { status, info: result?.info, infocode: result?.infocode });
          reject(new Error(errorMsg));
        }
      });
    });

    const poi = result as any;
    const location = poi.location; // POI 对象包含 location 属性
    
    console.log('[地址搜索] 搜索结果:', location);
    
    // 更新地图中心点和标记
    updatePosition(location.lng, location.lat);
    addMarker(location.lng, location.lat);
    
    // 设置缩放级别
    map.setZoomAndCenter(15, [location.lng, location.lat]);
  } catch (error: any) {
    console.error('[地址搜索] 失败:', error);
    alert(error.message || '地址搜索失败，请尝试其他地址');
  }
};

// 处理搜索
const handleSearch = () => {
  console.log('[搜索] 开始搜索:', searchInput.value);
  console.log('[搜索] placeSearch 状态:', !!placeSearch);
  console.log('[搜索] AMap 状态:', !!AMap);
  
  if (!searchInput.value.trim()) {
    alert('请输入地址');
    return;
  }
  
  // 确保 PlaceSearch 已初始化
  if (!placeSearch || !AMap) {
    console.error('[搜索] PlaceSearch 未初始化');
    alert('地图组件正在初始化，请稍后再试');
    return;
  }
  
  console.log('[搜索] 准备调用 searchAddress:', searchInput.value);
  searchAddress(searchInput.value);
};

// 按回车搜索
const handleKeyPress = (e: KeyboardEvent) => {
  if (e.key === 'Enter') {
    handleSearch();
  }
};

// 获取当前位置
const getCurrentLocation = () => {
  if (navigator.geolocation) {
    navigator.geolocation.getCurrentPosition(
      (position) => {
        const lng = position.coords.longitude;
        const lat = position.coords.latitude;
        console.log('获取到当前位置:', lng, lat);
        updatePosition(lng, lat);
        addMarker(lng, lat);
        map.setCenter([lng, lat]);
        map.setZoom(15);
      },
      (error) => {
        console.warn('获取当前位置失败:', error);
        // 使用默认位置（北京）
        const defaultLng = 116.397428;
        const defaultLat = 39.90923;
        updatePosition(defaultLng, defaultLat);
        addMarker(defaultLng, defaultLat);
      }
    );
  } else {
    console.warn('浏览器不支持地理位置');
    // 使用默认位置
    const defaultLng = 116.397428;
    const defaultLat = 39.90923;
    updatePosition(defaultLng, defaultLat);
    addMarker(defaultLng, defaultLat);
  }
};

const initMap = async () => {
  console.log('[地图初始化] 开始检查...');
  
  // 等待 DOM 更新
  await nextTick();
  
  if (!mapContainer.value) {
    console.error('[地图初始化] 地图容器不存在');
    mapError.value = '地图容器未准备好';
    mapLoading.value = false;
    return;
  }
  
  console.log('[地图初始化] 容器元素:', mapContainer.value);
  console.log('[地图初始化] 容器高度:', mapContainer.value.style.height);
  console.log('[地图初始化] 容器 offsetHeight:', mapContainer.value.offsetHeight);
  
  if (!AMap) {
    console.error('[地图初始化] AMap 对象未初始化');
    mapError.value = '地图 SDK 未加载';
    mapLoading.value = false;
    return;
  }

  console.log('[地图初始化] AMap 对象存在:', !!AMap);
  console.log('[地图初始化] AMap.Map 构造函数:', typeof AMap.Map);

  mapLoading.value = true;
  mapError.value = "";

  try {
    const initialCenter = hasValidCoords()
      ? [props.longitude, props.latitude]
      : [116.397428, 39.90923];

    console.log('[地图初始化] 开始创建地图实例...');
    console.log('[地图初始化] 中心点:', initialCenter);
    console.log('[地图初始化] 缩放级别:', props.zoom);
    
    // 配置地图选项
    const mapOptions: any = {
      zoom: props.zoom,
      center: initialCenter,
      resizeEnable: true,
      viewMode: "2D",
      keyboardEnable: true,
      scrollWheel: true,
      doubleClickZoom: true,
      zoomEnable: true,
      // 控制地图显示元素，减少标注重叠
      features: ['bg', 'road', 'building', 'point'],
      // 设置标注显示策略：避免重叠
      showIndoorMap: false,
      // 使用标准样式，标注更清晰
      mapStyle: 'amap://styles/normal'
    };
    
    // 如果 AMap 已加载，添加图层配置
    if ((window as any).AMap) {
      // 只使用默认底图，移除路网层避免重叠
      mapOptions.layers = [
        new (window as any).AMap.TileLayer({
          // 控制标注密度
          zIndex: 1
        })
      ];
    }
    
    map = new AMap.Map(mapContainer.value, mapOptions);

    console.log('[地图初始化] 地图实例创建成功:', !!map);
    console.log('[地图初始化] 地图对象:', map);

    // 先初始化地理编码插件（在地图实例创建之后）
    console.log('[地图初始化] 开始加载地理编码插件...');
    
    // 使用 Promise 包装插件加载
    await new Promise((resolve, reject) => {
      AMap.plugin(['AMap.PlaceSearch'], () => {
        console.log('[插件加载] 插件加载回调执行');
        placeSearch = new AMap.PlaceSearch({
          pageSize: 5,
          pageIndex: 1,
          extensions: 'all' // 返回详细信息
        });
        
        console.log('[地图初始化] PlaceSearch 初始化完成');
        console.log('[地图初始化] placeSearch 对象:', !!placeSearch);
        console.log('[地图初始化] placeSearch.search:', typeof placeSearch.search);
        resolve(true);
      }, (error: any) => {
        console.error('[插件加载] 失败:', error);
        reject(error);
      });
    });

    if (hasValidCoords() && props.initialMarker) {
      console.log('[地图初始化] 添加初始标记点');
      addMarker(props.longitude!, props.latitude!);
    } else if (hasValidCoords()) {
      console.log('[地图初始化] 只设置中心点，不添加标记点');
      map.setCenter([props.longitude!, props.latitude!]);
    } else if (props.showSearch) {
      // 如果是新数据且显示搜索框，获取当前位置
      console.log('[地图初始化] 无坐标数据，获取当前位置');
      getCurrentLocation();
    }

    if (props.enableClickMark) {
      console.log('[地图初始化] 启用点击事件');
      map.on("click", (e: any) => {
        const lng = e.lnglat.getLng();
        const lat = e.lnglat.getLat();
        updatePosition(lng, lat);
        addMarker(lng, lat);
      });
    }

    console.log('[地图初始化] 完成');
    mapLoading.value = false;
  } catch (error: any) {
    console.error("[地图初始化] 失败:", error);
    mapError.value = error.message || "地图加载失败，请检查网络连接";
    mapLoading.value = false;
  }
};

const loadAMap = () => {
  console.log("开始加载高德地图...");
  
  // 重置状态
  loadingProgress.value = 0;
  loadingStep.value = 0;
  
  // 设置超时机制
  const timeoutId = setTimeout(() => {
    console.warn('地图加载超时');
    mapError.value = '地图加载超时，请刷新页面重试';
    mapLoading.value = false;
  }, 15000); // 15 秒超时
  
  // 更新进度
  loadingStep.value = 1;
  loadingProgress.value = 20;
  
  // 先检查网络连接
  fetch('https://webapi.amap.com/maps?v=2.0&key=b1e59efdfdc10271d78db9a556540361')
    .then(response => {
      clearTimeout(timeoutId); // 清除超时
      console.log('高德 API 网络连接测试:', response.status);
        
      // 更新进度
      loadingStep.value = 2;
      loadingProgress.value = 50;
        
      if (!response.ok) {
        throw new Error(`网络响应错误：${response.status}`);
      }
      return response.text();
    })
    .then(data => {
      console.log('高德 API 响应数据长度:', data.length);
  
      // 设置安全密钥
      (window as any)._AMapSecurityConfig = {
        securityJsCode: 'bcfcaa8d8ef22452d4cf6d3892646262'
      };
      console.log('已设置安全密钥');

      // 更新进度
      loadingStep.value = 3;
      loadingProgress.value = 80;
  
      AMapLoader.load({
        key: "b1e59efdfdc10271d78db9a556540361",
        version: "2.0",
        plugins: ["AMap.Scale", "AMap.ToolBar", "AMap.PlaceSearch"]
      })
        .then((AMapInstance) => {
          clearTimeout(timeoutId); // 清除超时
          console.log("高德地图API加载成功");
          AMap = AMapInstance;
          (window as any).AMap = AMapInstance;
          
          // 完成进度
          loadingProgress.value = 100;
          
          initMap();
        })
        .catch((error) => {
          clearTimeout(timeoutId); // 清除超时
          console.error("加载高德地图失败:", error);
          mapError.value = `地图加载失败：${error.message || '未知错误'}. 请检查网络连接或 API 密钥是否正确`;
          mapLoading.value = false;
        });
    })
    .catch(error => {
      clearTimeout(timeoutId); // 清除超时
      console.error('网络连接测试失败:', error);
      mapError.value = `网络连接测试失败：${error.message}. 请检查网络连接`;
      mapLoading.value = false;
    });
};

watch(
  () => [props.longitude, props.latitude],
  ([newLng, newLat]) => {
    // 只有在 initialMarker 为 true 时才自动添加标记点
    if (newLng && newLat && map && props.initialMarker) {
      addMarker(newLng as number, newLat as number);
      map.setCenter([newLng, newLat]);
    } else if (newLng && newLat && map) {
      // 只更新中心点，不添加标记
      map.setCenter([newLng, newLat]);
    }
  }
);

onMounted(() => {
  console.log('地图组件挂载，容器存在:', !!mapContainer.value);
  loadAMap();
});

onBeforeUnmount(() => {
  if (map) {
    map.destroy();
    map = null;
  }
});

defineExpose({
  reloadMap,
  addMarker,
  addCustomMarker, // 暴露添加自定义标记的方法
  searchAddress, // 暴露搜索方法
  lngLatToPixel // 暴露坐标转换方法
});
</script>

<template>
  <div class="amap-wrapper">
    <!-- 地址搜索框 -->
    <div v-if="showSearch" class="search-box">
      <el-input
        v-model="searchInput"
        placeholder="请输入地址进行搜索"
        clearable
        @keypress="handleKeyPress"
      >
        <template #append>
          <el-button @click="handleSearch">
            <el-icon><Search /></el-icon>
            搜索
          </el-button>
        </template>
      </el-input>
    </div>

    <!-- 地图容器始终渲染 -->
    <div ref="mapContainer" class="map-container" :style="{ height }"></div>
    
    <!-- 加载状态覆盖层 -->
    <div v-if="mapLoading" class="loading-overlay">
      <div class="loading-spinner"></div>
      <span>地图加载中...</span>
      <div class="loading-progress">
        <div class="progress-bar" :style="{ width: loadingProgress + '%' }"></div>
      </div>
      <div class="loading-steps">
        <div :class="{ 'step-active': loadingStep >= 1 }">🌐 网络检测</div>
        <div :class="{ 'step-active': loadingStep >= 2 }">🔑 API 验证</div>
        <div :class="{ 'step-active': loadingStep >= 3 }">🗺️ 地图初始化</div>
      </div>
    </div>
    
    <!-- 错误状态覆盖层 -->
    <div v-else-if="mapError" class="error-overlay">
      <div class="error-icon">⚠️</div>
      <span>{{ mapError }}</span>
      <div class="error-actions">
        <el-button size="small" @click="reloadMap">重新加载</el-button>
        <el-button size="small" @click="showFallbackMap">显示备用地图</el-button>
      </div>
    </div>
    
    <div
      v-if="hasValidCoords() && !mapLoading && !mapError"
      class="coord-display"
    >
      <span>📍</span>
      <span>经度：{{ props.longitude?.toFixed(6) }}</span>
      <span>|</span>
      <span>纬度：{{ props.latitude?.toFixed(6) }}</span>
    </div>
    <div v-else-if="!mapLoading && !mapError" class="coord-empty">
      <span>📍</span>
      <span>暂无位置信息，请在地图上点击选择位置或通过地址搜索定位</span>
    </div>
    
    <!-- 备用静态地图 -->
    <div v-if="showFallback" class="fallback-map">
      <div class="fallback-content">
        <h3>备用地图视图</h3>
        <div class="fallback-coords">
          <p><strong>经度:</strong> {{ props.longitude || '未设置' }}</p>
          <p><strong>纬度:</strong> {{ props.latitude || '未设置' }}</p>
        </div>
        <div class="fallback-actions">
          <el-button @click="hideFallbackMap">关闭备用地图</el-button>
          <el-button type="primary" @click="reloadMap">重试加载</el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped>
.amap-wrapper {
  position: relative;
  width: 100%;
  border-radius: 8px;
  overflow: hidden;
}

.search-box {
  margin-bottom: 10px;
  z-index: 1001;
  position: relative;
}

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

.loading-overlay,
.error-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.9);
  z-index: 1000;
}

.loading-state,
.error-state,
.coord-display,
.coord-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
  margin-top: 8px;
}

.error-state {
  flex-direction: column;
  color: #f56c6c;
  padding: 24px;
}

.loading-state {
  color: #409eff;
  text-align: center;
  padding: 20px;
}

.loading-spinner {
  width: 40px;
  height: 40px;
  border: 4px solid #f3f3f3;
  border-top: 4px solid #409eff;
  border-radius: 50%;
  animation: spin 1s linear infinite;
  margin: 0 auto 15px;
}

@keyframes spin {
  0% { transform: rotate(0deg); }
  100% { transform: rotate(360deg); }
}

.loading-progress {
  width: 80%;
  height: 6px;
  background-color: #e4e7ed;
  border-radius: 3px;
  margin: 15px auto;
  overflow: hidden;
}

.progress-bar {
  height: 100%;
  background-color: #409eff;
  transition: width 0.3s ease;
}

.loading-steps {
  display: flex;
  justify-content: space-around;
  margin-top: 15px;
  font-size: 12px;
}

.loading-steps div {
  opacity: 0.5;
  transition: all 0.3s ease;
}

.step-active {
  opacity: 1;
  color: #409eff;
  font-weight: bold;
}

.error-icon {
  font-size: 32px;
  margin-bottom: 10px;
}

.error-actions {
  margin-top: 15px;
}

.error-actions .el-button {
  margin: 0 5px;
}

.fallback-map {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.95);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 1000;
}

.fallback-content {
  background: white;
  padding: 30px;
  border-radius: 8px;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  text-align: center;
  max-width: 400px;
}

.fallback-content h3 {
  margin-top: 0;
  color: #333;
}

.fallback-coords {
  text-align: left;
  margin: 20px 0;
}

.fallback-coords p {
  margin: 10px 0;
  font-size: 14px;
}

.fallback-actions {
  margin-top: 20px;
}

.fallback-actions .el-button {
  margin: 0 5px;
}

.coord-display {
  color: #606266;
  font-size: 13px;
  padding: 8px 12px;
  background: #f5f7fa;
  border-radius: 4px;
  margin-top: 8px;
}

.coord-empty {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  padding: 12px;
  background: #f5f7fa;
  border-radius: 4px;
  margin-top: 8px;
}
</style>
