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

interface Props {
  longitude?: number;
  latitude?: number;
  zoom?: number;
  height?: string;
  enableClickMark?: boolean;
  securityJsCode?: string;
}

const props = withDefaults(defineProps<Props>(), {
  longitude: 116.397428,
  latitude: 39.90923,
  zoom: 15,
  height: "400px",
  enableClickMark: false,
  securityJsCode: "f58a434f5aa44a00c811862862e7760b"
});

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

const mapContainer = ref<HTMLDivElement>();
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 AMap: any = null;

const hasValidCoords = () => {
  return (
    props.longitude &&
    props.latitude &&
    props.longitude >= -180 &&
    props.longitude <= 180 &&
    props.latitude >= -90 &&
    props.latitude <= 90
  );
};

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 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;
};

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);
    
    map = new AMap.Map(mapContainer.value, {
      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'
    });

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

    if (hasValidCoords()) {
      console.log('[地图初始化] 添加标记点');
      addMarker(props.longitude!, props.latitude!);
    }

    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=f58a434f5aa44a00c811862862e7760b')
    .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);
      
      if (props.securityJsCode) {
        (window as any)._AMapSecurityConfig = {
          securityJsCode: props.securityJsCode
        };
        console.log("已设置安全密钥");
      }

      // 更新进度
      loadingStep.value = 3;
      loadingProgress.value = 80;

      AMapLoader.load({
        key: "f58a434f5aa44a00c811862862e7760b",
        version: "2.0",
        plugins: ["AMap.Scale", "AMap.ToolBar"]
      })
        .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]) => {
    if (newLng && newLat && map) {
      addMarker(newLng as number, newLat as number);
      map.setCenter([newLng, newLat]);
    }
  }
);

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

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

defineExpose({
  reloadMap,
  addMarker
});
</script>

<template>
  <div class="amap-wrapper">
    <!-- 地图容器始终渲染 -->
    <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;
}

.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;
}

.coord-empty {
  color: #909399;
  font-size: 13px;
}
</style>
