// ============================================================
// 护理员轨迹 Composable — 手动标记起点/终点 + 路线 + 动画
//
// 交互模型：
//   1. [📍标记起点] → 点击地图 → 放 📍 marker
//   2. [🏁标记终点] → 点击地图 → 放 🏁 marker
//   3. [👩‍⚕️添加护理员] → 放在起点位置（可拖拽）
//   4. [🚗规划路线] → AMap.Driving → 蓝色折线
//   5. [▶出发] → 护理员沿路线动画移动
// ============================================================

import { ref, shallowRef, computed } from 'vue'
import type { Ref } from 'vue'
import { loadAMap } from './useAmap'

// ─── 标记 HTML ─────────────────────────────────────

const CAREGIVER_HTML = '<div class="geofence-caregiver-marker">👩‍⚕️</div>'
const ORIGIN_HTML    = '<div class="geofence-origin-marker">📍</div>'
const DEST_HTML      = '<div class="geofence-dest-marker">🏁</div>'

// ─── 类型 ──────────────────────────────────────────

export interface RouteInfo {
  distance: number
  duration: number
  path: [number, number][]
}

// ─── 工具 ──────────────────────────────────────────

function downsamplePath(path: [number, number][], target: number): [number, number][] {
  if (path.length <= target) return [...path]
  const result: [number, number][] = []
  const step = (path.length - 1) / (target - 1)
  for (let i = 0; i < target; i++) {
    result.push(path[Math.min(Math.round(i * step), path.length - 1)])
  }
  return result
}

/** 安全获取事件经纬度 */
function eventLngLat(e: any): [number, number] | null {
  const lng: number = e.lnglat?.lng ?? e.lnglat?.getLng?.()
  const lat: number = e.lnglat?.lat ?? e.lnglat?.getLat?.()
  if (isNaN(lng) || isNaN(lat)) return null
  return [lng, lat]
}

// ─── Composable ────────────────────────────────────

export function useRouteTrack(mapInstance: Ref<AMap.Map | null>) {
  // ===== 状态 =====

  const caregiverMarker = shallowRef<AMap.Marker | null>(null)
  const originMarker    = shallowRef<AMap.Marker | null>(null)
  const destMarker      = shallowRef<AMap.Marker | null>(null)
  const routePolyline   = shallowRef<AMap.Polyline | null>(null)

  const routePath    = ref<[number, number][]>([])
  const animPath     = ref<[number, number][]>([])
  const routeInfo    = ref<RouteInfo | null>(null)
  const isPlanning   = ref(false)
  const isAnimating  = ref(false)
  const animProgress = ref(0)
  const animStep     = ref(0)

  /** 起点坐标 */
  const originPoint = ref<[number, number] | null>(null)
  /** 终点坐标 */
  const destPoint   = ref<[number, number] | null>(null)

  /** 当前模式：'origin' | 'dest' | null */
  const settingMode = ref<'origin' | 'dest' | null>(null)

  let animTimer: ReturnType<typeof setInterval> | null = null
  let _clickHandler: ((e: any) => void) | null = null

  // ── 派生 ──

  const hasCaregiver = () => caregiverMarker.value !== null
  const hasRoute     = () => routePolyline.value !== null
  const hasOrigin    = () => originPoint.value !== null
  const hasDest      = () => destPoint.value !== null
  const canPlanRoute = computed(() =>
    hasOrigin() && hasDest() && !isPlanning.value
  )

  // ===== 点击地图通用处理 =====

  async function enterSetMode(mode: 'origin' | 'dest'): Promise<void> {
    const map = mapInstance.value
    if (!map) return
    exitSetMode()

    settingMode.value = mode
    map.setDefaultCursor('crosshair')

    const AMap = await loadAMap()

    function onClick(e: any): void {
      const pt = eventLngLat(e)
      if (!pt) return

      if (mode === 'origin') {
        applyOrigin(pt, AMap, map!)
      } else {
        applyDestination(pt)
      }
      exitSetMode()
    }

    _clickHandler = onClick
    ;(map as any)._rtClick = onClick
    map.on('click', onClick)
  }

  function exitSetMode(): void {
    const map = mapInstance.value
    if (!map) return
    settingMode.value = null
    map.setDefaultCursor('default')
    if (_clickHandler && (map as any)._rtClick) {
      map.off('click', _clickHandler)
      delete (map as any)._rtClick
      _clickHandler = null
    }
  }

  // ===== 起点标记 =====

  function applyOrigin(
    point: [number, number],
    AMap: typeof import('@amap/amap-jsapi-loader'),
    map: AMap.Map
  ): void {
    originPoint.value = point

    if (originMarker.value) {
      originMarker.value.setPosition(point)
    } else {
      const m = new AMap.Marker({
        position: point,
        content: ORIGIN_HTML,
        offset: new AMap.Pixel(-10, -10),
        zIndex: 205,
      })
      map.add(m)
      originMarker.value = m
    }

    console.log(`[护理员] 📍 起点: [${point[0].toFixed(4)}, ${point[1].toFixed(4)}]`)
  }

  function removeOrigin(): void {
    const map = mapInstance.value
    if (!map) return
    if (originMarker.value) { map.remove(originMarker.value); originMarker.value = null }
    originPoint.value = null
    // 清除起点也清除路线
    clearRoute()
  }

  // ===== 终点标记 =====

  function applyDestination(point: [number, number]): void {
    const map = mapInstance.value
    if (!map) return
    destPoint.value = point

    if (destMarker.value) {
      destMarker.value.setPosition(point)
    } else {
      const m = new AMap.Marker({
        position: point,
        content: DEST_HTML,
        offset: new AMap.Pixel(-12, -32),
        zIndex: 215,
      })
      map.add(m)
      destMarker.value = m
    }
    console.log(`[护理员] 🏁 终点: [${point[0].toFixed(4)}, ${point[1].toFixed(4)}]`)
  }

  function removeDest(): void {
    const map = mapInstance.value
    if (!map) return
    if (destMarker.value) { map.remove(destMarker.value); destMarker.value = null }
    destPoint.value = null
    clearRoute()
  }

  // ===== 护理员标记 =====

  /** 添加护理员：放在起点位置，没有起点则放地图中心 */
  async function addCaregiver(): Promise<void> {
    const map = mapInstance.value
    if (!map) return

    const pos = originPoint.value
      ? [...originPoint.value]
      : (() => { const c = map.getCenter(); return [c.lng, c.lat] as [number, number] })()

    removeCaregiver()

    const AMap = await loadAMap()

    const marker = new AMap.Marker({
      position: pos,
      content: CAREGIVER_HTML,
      offset: new AMap.Pixel(-17, -17),
      draggable: true,
      zIndex: 210,
    })
    map.add(marker)
    caregiverMarker.value = marker

    // 如果没起点，护理员的位置同时作为起点
    if (!originPoint.value) {
      applyOrigin(pos, AMap, map)
    }

    if (!originPoint.value && !destPoint.value) {
      map.setZoomAndCenter(5, pos)
    }

    console.log(`[护理员] 👩‍⚕️ 护理员已添加: [${pos[0].toFixed(4)}, ${pos[1].toFixed(4)}]`)
  }

  function removeCaregiver(): void {
    const map = mapInstance.value
    if (!map) return
    stopAnimation()
    if (caregiverMarker.value) { map.remove(caregiverMarker.value); caregiverMarker.value = null }
  }

  // ===== 全部清除 =====

  function clearAll(): void {
    exitSetMode()
    stopAnimation()
    clearRoute()
    removeCaregiver()
    removeOrigin()
    removeDest()
  }

  // ===== 路线规划 =====

  async function planRoute(): Promise<void> {
    const map = mapInstance.value
    if (!map || !originPoint.value || !destPoint.value) return

    clearRoute()
    isPlanning.value = true

    try {
      const AMap = await loadAMap()

      // 检查 Driving 是否可用
      if (!AMap.Driving) {
        throw new Error('AMap.Driving 插件未加载，请检查 config/amap.ts 中的 AMAP_PLUGINS 是否包含 "AMap.Driving"')
      }

      const [orgLng, orgLat] = originPoint.value
      const [destLng, destLat] = destPoint.value

      console.log(`[护理员] 🚗 规划路线: [${orgLng.toFixed(4)}, ${orgLat.toFixed(4)}] → [${destLng.toFixed(4)}, ${destLat.toFixed(4)}]`)

      await new Promise<void>((resolve, reject) => {
        // 必须传入 map 实例，否则 Driving 无法正确初始化
        const driving = new AMap.Driving({
          map: map as any,
          policy: 0,          // 0 = 速度优先
          showTraffic: false,
        })

        // 参数使用 AMap.LngLat 实例（更可靠）
        const originLngLat = new AMap.LngLat(orgLng, orgLat)
        const destLngLat   = new AMap.LngLat(destLng, destLat)

        driving.search(originLngLat, destLngLat, (status: string, result: any) => {
          console.log(`[护理员] Driving 回调: status="${status}", routes=${result?.routes?.length ?? 0}`)

          if (status === 'complete' && result.routes?.length > 0) {
            const route = result.routes[0]
            const fullPath: [number, number][] = []
            for (const step of route.steps) {
              for (const pt of step.path) fullPath.push([pt.lng, pt.lat])
            }
            if (fullPath.length < 2) { reject(new Error('路线点数不足')); return }

            routePath.value = fullPath
            animPath.value = downsamplePath(fullPath, 250)
            routeInfo.value = { distance: route.distance, duration: route.time, path: fullPath }

            const polyline = new AMap.Polyline({
              path: fullPath,
              strokeColor: '#4A90D9', strokeWeight: 4, strokeOpacity: 0.75,
              lineJoin: 'round', lineCap: 'round', zIndex: 85,
            })
            map!.add(polyline)
            routePolyline.value = polyline
            map!.setFitView([polyline], false, [60, 60, 60, 60])

            console.log(`[护理员] 🚗 路线完成 — ${(route.distance/1000).toFixed(1)}km，${animPath.value.length}动画点`)
            resolve()
          } else if (status === 'error') {
            const msg = result?.info || result?.message || '未知错误'
            console.error(`[护理员] ❌ Driving 返回错误: ${msg}`, result)
            reject(new Error(`路线规划失败: ${msg}`))
          } else if (status === 'no_data') {
            reject(new Error('起终点之间无可用路线，请尝试缩短距离或调整位置'))
          } else {
            console.error(`[护理员] ❌ 未知状态: ${status}`, result)
            reject(new Error(`路线规划失败 (${status})，请重试`))
          }
        })
      })
    } catch (err: any) {
      alert(`路线规划失败: ${err.message}`)
      clearRoute()
    } finally {
      isPlanning.value = false
    }
  }

  function clearRoute(): void {
    const map = mapInstance.value
    if (!map) return
    stopAnimation()
    if (routePolyline.value) { map.remove(routePolyline.value); routePolyline.value = null }
    routePath.value = []
    animPath.value = []
    routeInfo.value = null
    animProgress.value = 0
    animStep.value = 0
  }

  // ===== 动画 =====

  async function startAnimation(): Promise<void> {
    // 如果护理员不存在，自动在起点创建
    if (!caregiverMarker.value) {
      if (!originPoint.value) {
        alert('请先标记起点和终点，再规划路线')
        return
      }
      await addCaregiver()
    }

    if (animPath.value.length < 2) {
      alert('路线数据为空，请先规划路线')
      return
    }

    if (isAnimating.value) return

    isAnimating.value = true
    animStep.value = 0
    animProgress.value = 0
    const total = animPath.value.length - 1

    animTimer = setInterval(() => {
      if (animStep.value >= total) {
        stopAnimation()
        animProgress.value = 1
        return
      }
      animStep.value++
      animProgress.value = animStep.value / total
      caregiverMarker.value?.setPosition(animPath.value[animStep.value])
    }, 40)

    console.log(`[护理员] ▶ 出发，${total}步 ~${(total*40/1000).toFixed(1)}秒`)
  }

  function stopAnimation(): void {
    if (animTimer) { clearInterval(animTimer); animTimer = null }
    isAnimating.value = false
  }

  function resetToOrigin(): void {
    stopAnimation()
    if (caregiverMarker.value && originPoint.value) {
      caregiverMarker.value.setPosition(originPoint.value)
    }
    animProgress.value = 0
    animStep.value = 0
  }

  // ===== 清理 =====

  function destroyRouteTrack(): void {
    clearAll()
  }

  return {
    caregiverMarker, routePolyline, routePath, routeInfo,
    isPlanning, isAnimating, animProgress,
    originPoint, destPoint, settingMode,
    hasCaregiver, hasRoute, hasOrigin, hasDest, canPlanRoute,

    enterSetMode, exitSetMode,
    addCaregiver, removeCaregiver,
    removeOrigin, removeDest,
    planRoute, clearRoute,
    startAnimation, stopAnimation, resetToOrigin,
    clearAll,
    destroyRouteTrack,
  }
}
