<template>
  <div id="path-map"></div>
</template>

<script>
import originIcon from '../../imgs/origin.png'
import destinationIcon from '../../imgs/destination.png'
import vehicleIcon from '../../imgs/vehicle.png'
import config from './config'

const AMap = window.AMap
// 生成高德标准写法经纬度
function loc (lng, lat) {
  return new AMap.LngLat(lng, lat)
}
const center = loc(113.84513250000002, 32.885113878375115) // 中心点

export default {
  props: ['pathList'],
  watch: {
    pathList: {
      immediate: true,
      handler (val) {
        val.length && (
          // 有了dom才能渲染
          this.$nextTick(() => {
            this.initMap()
          })
        )
      }
    }
  },
  created () {
  },
  mounted () {
    this.initMap()
  },

  data () {
    return {
      map: {}, // 地图对象
      infoWindow: {}, // 弹窗对象
    }
  },
  methods: {
    // 初始化地图
    initMap () {
      // 地图配置项
      const mapOptions = {
        center,
        resizeEnable: true,
        zoom: 5,
        zooms: [3, 12], // 缩放范围, 最大19
        mapStyle: 'amap://styles/fresh'
      }
      this.map = new AMap.Map('path-map', mapOptions)
      // 设置控件
      AMap.plugin([
        'AMap.ToolBar', // 工具条
        'AMap.Scale', // 比例尺
      ], () => {
        const toolOptions = {
          direction: false, // 方向盘
        }
        const tool = new AMap.ToolBar(toolOptions)
        this.map.addControl(tool)
        this.map.addControl(new AMap.Scale())
      })
      this.pathList.map((item, index) => {
        item.mapInfo = {} // 用于保存根据业务产生的地图信息
        this.setMarkers(item, index)
        this.setHistoryLines(item, index)
        this.setPlanLines(item, index)
      })
    },
    // 设置标记点
    setMarkers (obj, pathIndex) {
      // 设置当前点
      obj.mapInfo.currentLoc = loc(obj.locations[obj.locations.length - 1].lon, obj.locations[obj.locations.length - 1].lat)
      const icon = vehicleIcon // 当前点图标
      const marker = new AMap.Marker({
        icon,
        position: obj.mapInfo.currentLoc
      })
      this.map.add(marker)
      obj.mapInfo.currentMarker = marker
      // 设置提示窗
      let content = `<div class="info"><p class="info__logistics-no">运单号 : ${obj.waybillNo}</p>`
      obj.vehicles.map((item, index) => {
        const vehicle = item.vehicleNo ? `车辆 ${index + 1} : ${item.vehicleNo}` : ''
        const addr = item.currentAddress ? ` 已到达 ${item.currentAddress}` : ''
        content += (vehicle && addr) && `<p class="info__vehicle-info">${vehicle}${addr}</p>`
      })
      content += `</div>`
      obj.mapInfo.infoWindow = new AMap.InfoWindow({
        isCustom: true,
        autoMove: true,
        closeWhenClickMap: true, // 点地图时关闭弹窗
        content,
        offset: new AMap.Pixel(0, -30) // 偏移量
      })
      // 点击标记弹窗
      marker.on('click', e => {
        if (obj.mapInfo.reloadPlanPath) {
          this.searchRoutes(obj, pathIndex, obj.mapInfo.reloadType)
          obj.mapInfo.reloadPlanPath = false
        } else {
          this.infoWindow = obj.mapInfo.infoWindow
          this.infoWindow.open(this.map, marker.getPosition())
        }
      })
    },
    // 设置历史路线
    setHistoryLines (obj, pathIndex) {
      const historyPath = obj.locations.map(item => loc(item.lon, item.lat))
      // 设置起点
      this.setMarkersByAddr(obj, 'origin', () => {
        // ##注释年会特殊代码
        const polyline = new AMap.Polyline({
          path: [obj.mapInfo.originLoc, ...historyPath],
          strokeColor: config.color.main,
          strokeWeight: config.weight.main,
          lineJoin: 'round',
        })
        this.map.add(polyline)
        polyline.on('click', e => {
          console.log(`点击 ${pathIndex} 号历史路径`)
          if (obj.mapInfo.reloadPlanPath) {
            obj.mapInfo.reloadPlanPath = false
            this.searchRoutes(obj, pathIndex)
          }
        })
        // ##年会特殊代码
        // this.searchRoutes(obj, pathIndex, 'origin')
      })
    },
    // 设置规划路线
    setPlanLines (obj, pathIndex) {
      // 因为设置了终点才有终点经纬度
      this.setMarkersByAddr(obj, 'destination', () => {
        // 查询路线
        this.searchRoutes(obj, pathIndex)
      })
    },
    // 查询规划路线
    searchRoutes (obj, pathIndex, type) {
      const driving = new AMap.Driving()
      let start, end
      switch (type) {
        case 'origin':
          start = obj.mapInfo.originLoc
          end = obj.mapInfo.currentLoc
          break
        default:
          start = obj.mapInfo.currentLoc
          end = obj.mapInfo.destinationLoc
          break
      }
      driving.search(start, end, (status, result) => {
        if (status === 'complete') {
          console.log('路线规划 result =', result)
          if (result.routes && result.routes.length) {
            // 绘制第一条路线，也可以按需求绘制其它几条路线
            drawRoute(result.routes[0], type)
          }
        } else {
          this.$toast(`${pathIndex + 1} 号运单 (单号: ${obj.waybillNo}) 规划路径获取失败, 请点击运单当前车辆重试`)
          obj.mapInfo.reloadPlanPath = true
          obj.mapInfo.reloadType = type
          console.log(status, result)
        }
      })
      // 自定义绘制路线
      const drawRoute = (route, type) => {
        const path = parseRouteToPath(route)
        const routeLine = new AMap.Polyline({
          path: path,
          // isOutline: true,
          // outlineColor: '#ffeeee',
          // borderWeight: 2,
          strokeWeight: config.weight.main,
          strokeColor: config.color.main,
          strokeOpacity: type === 'origin' ? 1 : config.color.opacity,
          lineJoin: 'round'
        })

        routeLine.setMap(this.map)
      }
      // 解析DrivingRoute对象，构造成AMap.Polyline的path参数需要的格式
      // DrivingResult对象结构参考文档 https://lbs.amap.com/api/javascript-api/reference/route-search#m_DriveRoute
      function parseRouteToPath (route) {
        const path = []

        for (let i = 0, l = route.steps.length; i < l; i++) {
          const step = route.steps[i]

          for (let j = 0, n = step.path.length; j < n; j++) {
            path.push(step.path[j])
          }
        }

        return path
      }
    },
    // 根据地址文字查询经纬度并设置 marker
    setMarkersByAddr (obj, type, cb) {
      const geocoder = new AMap.Geocoder() // 地址解析对象
      geocoder.getLocation(obj[type], (status, result) => {
        // 解析成功
        if (status === 'complete' && result.geocodes.length) {
          const position = result.geocodes[0].location
          obj.mapInfo[`${type}Loc`] = position
          const marker = new AMap.Marker({
            icon: type === 'origin' ? originIcon : destinationIcon, // 起始点图标
            position,
          })
          obj.mapInfo[`${type}Marker`] = marker
          this.map.add(marker)
          if (typeof cb === 'function') {
            cb()
          }
        } else {
          this.$toast('地址解析失败, 请刷新重试')
        }
      })
    },
  },
}
</script>

<style lang="scss">
  #path-map {
    width: 100%;
    height: 100%; // 可能有变动的需要
  }
  .info {
    /*background: #fff;*/
    /*border-radius: 10px;*/
    /*box-shadow: 0 0 0.8rem #ccc;*/
    padding: 1rem;
    font-size: 0.8rem;
    background: #000000d9;
    color: #fff;
    border-radius: 5px;
    box-shadow: 0 3px 14px #f388014a;
    &:hover {
      box-shadow: 0 3px 14px #f388014a;
    }
  }
  .amap-info-content {
    background: #000000d9;
    color: #fff;
    border-radius: 5px;
    box-shadow: 0 3px 14px #f388014a;
    &:hover {
      box-shadow: 0 3px 14px #f388014a;
    }
  }
</style>
