<template>
  <div class="car-path-history" v-if="showBtn">
    <div class="car-path-history-content" v-show="showCarPathHistory">
      <div class="car-path-time">当前时间：{{ currentTime }}</div>
      <div class="car-path-control">
        <div>历史轨迹</div>
        <div class="select-date-time" @click="selectDateTime">选择时段</div>
        <div class="control-slider">
          <div class="slider">
            <div class="slider-origin">
              <div class="play-btn">
                <Icon style="font-size: 24px" @click="playCar" v-if="isPause" type="caret-right" theme="filled" />
                <Icon style="font-size: 24px" @click="pauseCar" v-else type="pause" />
              </div>
              <Slider
                @change="onChangePlayTimeLine"
                :value="playTime"
                :min="0"
                :max="positions.length - 1 < 0 ? 0 : positions.length - 1"
                :tip-formatter="playTimeFormatter"
                :step="1"
                @afterChange="afterChange"
              />
            </div>
            <div class="slider-time">
              <div>{{ startTime }}</div>
              <div>{{ endTime }}</div>
            </div>
          </div>
          <div class="select-btn">
            <Select v-model="defaultSpeed" @change="onChangeSpeedHandler">
              <SelectOption v-for="(item, index) in speedData" :key="index" :value="item.value" >
                {{ item.title }}
              </SelectOption>
            </Select>
          </div>
        </div>
      </div>
    </div>
    <div class="gj-img">
      <div class="btn" @click="showCarPathHistory = !showCarPathHistory"></div>
    </div>
    <Modal v-model="visibleModal" destroyOnClose title="选择时间段" @ok="handleOk">
      <FormModel :model="selectDateTimeForm" :rules="rules" ref="formModel">
        <FormModelItem label="开始时间" required prop="startTime">
          <DatePicker
            v-model="selectDateTimeForm.startTime"
            show-time
            type="date"
            placeholder="请选择开始时间"
            style="width: 100%"
          />
        </FormModelItem>
        <FormModelItem label="结束时间" required prop="endTime">
          <DatePicker
            v-model="selectDateTimeForm.endTime"
            show-time
            type="date"
            placeholder="请选择结束时间"
            style="width: 100%"
          />
        </FormModelItem>
      </FormModel>
    </Modal>
  </div>
</template>

<script>
import { getCarLocation } from '@/api/iot.js'
import { Button, Slider, Select, Icon, Modal, FormModel, DatePicker } from 'ant-design-vue'

const SelectOption = Select.Option
const FormModelItem = FormModel.Item
/**
 * 计算角度
 * @param {*} startPoint 开始点位
 * @param {*} endPoint 下一个点位
 */
function calcAngle(startPoint, endPoint) {
  if (!(startPoint && endPoint)) {
    return 0
  }

  let dRotateAngle = Math.atan2(Math.abs(startPoint[0] - endPoint[0]), Math.abs(startPoint[1] - endPoint[1]))
  if (endPoint[0] >= startPoint[0]) {
    if (endPoint[1] >= startPoint[1]) {
    } else {
      dRotateAngle = Math.PI - dRotateAngle
    }
  } else {
    if (endPoint[1] >= startPoint[1]) {
      dRotateAngle = 2 * Math.PI - dRotateAngle
    } else {
      dRotateAngle = Math.PI + dRotateAngle
    }
  }
  dRotateAngle = (dRotateAngle * 180) / Math.PI
  return dRotateAngle
}

export default {
  name: 'CarPathHistory',
  components: {
    Button,
    Slider,
    Select,
    SelectOption,
    Icon,
    Modal,
    FormModel,
    FormModelItem,
    DatePicker,
  },
  props: {
    idInfo: Object,
  },
  computed: {
    speed() {
      return Number(this.idInfo.meta.speedLimit || 100)
    }
  },
  data() {
    return {
      showBtn: false,
      currentTime: '00:00:00',
      speedData: [
        {
          title: '50x',
          value: 50,
        },
        {
          title: '10x',
          value: 10,
        },
        {
          title: '5x',
          value: 5,
        },
        {
          title: '2x',
          value: 2,
        },
        {
          title: '1x',
          value: 1,
        },
      ],
      defaultSpeed: 1,
      visibleModal: false,
      selectDateTimeForm: {
        startTime: '',
        endTime: '',
      },
      showCarPathHistory: false,
      rules: {
        startTime: [{ required: true, message: '请选择开始时间', trigger: 'blur' }],
        endTime: [{ required: true, message: '请选择结束时间', trigger: 'blur' }],
      },
      positions: [],
      originPositions: [],
      startTime: '00:00:00',
      endTime: '00:00:00',
      carMarker: null,
      playTime: 0,
      positionIndex: 0,
      isPause: true,
      isFirstPlay: true,
      path: [],
      passedPathLength: 0,
      passedPath: [],
    }
  },
  inject: ['carMap'],
  watch: {
    playTime: function (value) {
      const time = new Date(this.originPositions[0].timeUtc8).getTime()
      const currentDate = new Date(time + value * 5 * 1000)
      this.currentTime = `${currentDate.getFullYear()}-${
        currentDate.getMonth() + 1
      }-${currentDate.getDate()} ${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}`
    },
    idInfo: {
      handler(val) {
        this.showBtn = val && val.key.indexOf('car') >= 0
      },
      deep: true,
    },
  },
  methods: {
    clearAll() {
      this.clearCarCache()
      this.selectDateTimeForm = {
        startTime: '',
        endTime: '',
      }
      this.currentTime = '00:00:00'
      this.startTime = '00:00:00'
      this.endTime = '00:00:00'
      this.carMarker && this.carMarker.setMap(null)
      this.basicInfo && this.basicInfo.setMap(null)
      this.passedPolyline && this.passedPolyline.setMap(null)
      this.showCarPathHistory = false
      this.clearPath()
    },
    onChangeSpeedHandler() {
      this.isFirstPlay = true
      this.positionIndex = this.playTime
      this.passedPathLength = this.playTime
      this.passedPath = this.positions.slice(0, this.playTime)
      if (!this.isPause) {
        this.playCar()
      }
    },
    // 选择时间段
    selectDateTime() {
      this.visibleModal = true
    },
    onChangePlayTimeLine(value) {
      this.playTime = value
      if (!this.carMarker) return
      this.carMarker.pauseMove()
      this.positionIndex = value
      this.carMarker.setPosition(this.positions[value])
      this.carMarker.setAngle(calcAngle(this.positions[value], this.positions[value + 1]))
    },
    afterChange(value) {
      this.isFirstPlay = true
      this.passedPathLength = value
      this.passedPath = this.positions.slice(0, value)
      if (!this.isPause) {
        this.playCar()
      }
    },
    playTimeFormatter(value) {
      if (!this.positions || this.positions.length === 0) return '00:00:00'
      const time = new Date(this.originPositions[0].timeUtc8).getTime()
      const currentDate = new Date(time + value * 5 * 1000)
      return `${currentDate.getFullYear()}-${
        currentDate.getMonth() + 1
      }-${currentDate.getDate()} ${currentDate.getHours()}:${currentDate.getMinutes()}:${currentDate.getSeconds()}`
    },
    handleOk() {
      this.$refs.formModel.validate((valid) => {
        if (valid) {
          // 做处理操作
          console.log('开始时间', this.selectDateTimeForm.startTime.format('YYYY-MM-DD HH:mm:ss'))
          console.log('结束时间', this.selectDateTimeForm.endTime.format('YYYY-MM-DD HH:mm:ss'))
          this.handleCarPathHistory('2023-07-18 18:40:00', '2023-07-18 19:00:00').then(() => {
            this.visibleModal = false
          })
        } else {
          return false
        }
      })
    },
    // 绘制路线
    drawCarPathLine(AMap, map) {
      if (!this.originPositions || this.originPositions.length === 0) return
      // 超速路段
      const overspeedSegment = []
      // 正常路段
      const normalVelocitySegment = []
      // 当前超速记录索引
      let overspeedIndex = 0
      // 当前正常速度记录索引
      let normalIndex = 0
      // 分析超速路段以及正常行驶路段
      this.originPositions.forEach((item, idx) => {
        item.index = idx
        if (Number(item.speed) > this.speed) {
          if (overspeedSegment.length === 0) {
            overspeedSegment.push([item])
          } else {
            const arr = overspeedSegment[overspeedIndex]
            if (
              Math.abs(new Date(arr[arr.length - 1].timeUtc8).getTime() - new Date(item.timeUtc8)) > 5000 &&
              this.originPositions[idx - 1].speed <= this.speed
            ) {
              overspeedSegment.push([item])
              overspeedIndex++
            } else {
              arr.push(item)
            }
          }
        } else {
          if (normalVelocitySegment.length === 0) {
            normalVelocitySegment.push([item])
          } else {
            const arr = normalVelocitySegment[normalIndex]
            if (
              Math.abs(new Date(arr[arr.length - 1].timeUtc8).getTime() - new Date(item.timeUtc8)) > 5000 &&
              this.originPositions[idx - 1].speed > this.speed
            ) {
              if (this.originPositions[arr[arr.length - 1].index + 1].speed > this.speed) {
                arr.push(this.originPositions[arr[arr.length - 1].index + 1])
              }
              normalIndex++
              if (idx - 1 >= 0 && this.originPositions[idx - 1].speed > this.speed) {
                normalVelocitySegment.push([ this.originPositions[idx - 1], item])
              } else {
                normalVelocitySegment.push([this.originPositions[idx - 1], item])
              }
            } else {
              arr.push(item)
            }
          }
        }
      })
      overspeedSegment.forEach((position) => {
        if (position && position.length > 0) {
          this.path.push(
            new AMap.Polyline({
              map: map,
              path: position.map((item) => [Number(item.longitude), Number(item.latitude)]),
              showDir: true,
              strokeColor: '#de0000', //线颜色
              strokeOpacity: 1, //线透明度
              strokeWeight: 5, //线宽
              // strokeStyle: "solid"  //线样式
            })
          )
        }
      })
      normalVelocitySegment.forEach((position) => {
        if (position && position.length > 0) {
          this.path.push(
            new AMap.Polyline({
              map: map,
              path: position.map((item) => [Number(item.longitude), Number(item.latitude)]),
              showDir: true,
              strokeColor: '#33b100', //线颜色
              strokeOpacity: 1, //线透明度
              strokeWeight: 5, //线宽
              // strokeStyle: "solid"  //线样式
            })
          )
        }
      })
    },
    playCar() {
      if (!this.carMarker) return
      if (this.isFirstPlay) {
        this.isFirstPlay = false
        this.carMarker.moveAlong(this.positions.slice(this.positionIndex), {
          // 每一段的时长
          duration: 5000 / this.defaultSpeed, //可根据实际采集时间间隔设置
          // JSAPI2.0 是否延道路自动设置角度在 moveAlong 里设置
          autoRotation: true,
        })
      } else {
        this.carMarker.resumeMove()
      }
      this.isPause = false
    },
    pauseCar() {
      if (!this.carMarker) return
      this.carMarker.pauseMove()
      this.isPause = true
    },
    // 加载轨迹回放小车
    loadCar(AMap, map) {
      if (this.carMarker) {
        this.isPause = true
        this.carMarker.pauseMove()
        this.carMarker.setMap(null)
        this.passedPolyline && this.passedPolyline.setMap(null)
      }
      this.carMarker = new AMap.Marker({
        map: map,
        position: this.positions[0],
        icon: 'https://a.amap.com/jsapi_demos/static/demo-center-v2/car.png',
        offset: new AMap.Pixel(-13, -26),
        autoRotation: true,
      })
      this.passedPolyline = new AMap.Polyline({
        map: map,
        strokeColor: '#000', //线颜色
        strokeOpacity: 0.3, //线透明度
        strokeWeight: 6, //线宽
      })
      map.setZoom(18)
      map.setCenter(this.carMarker.getPosition(), true)
      this.basicInfo = new AMap.InfoWindow({
        isCustom: true, // 使用自定义窗体
        content: '',
        offset: new AMap.Pixel(6, -25),
      })
      this.basicInfo.open(map, this.positions[0])
      this.carMarker.on('moving',  (e) => {
          this.passedPolyline.setPath([...this.passedPath,...e.passedPath])
          // map.setCenter(e.target.getPosition(),true)
          // 后面的参数指的是经纬度，在此显示窗口
          var lastLocation = e.passedPath[e.passedPath.length - 1]
          this.basicInfo.setPosition(lastLocation)
          this.setVehicleSpeedInWidowns(lastLocation, AMap)
          const locationIndex = e.passedPath.length - 1 + this.passedPathLength
          if (locationIndex === this.positions.length - 1) {
            this.pauseCar()
            this.clearCarCache()
            this.passedPolyline.setMap(null)
            this.passedPolyline.setPath(null)
            this.basicInfo.setContent('')
            this.carMarker.setPosition(this.positions[0])
            this.passedPolyline.setMap(map)
          } else {
            this.playTime = e.passedPath.length - 1 + this.passedPathLength
          }
      })
    },
    clearCarCache() {
      this.playTime = 0
      this.positionIndex = 0
      this.passedPathLength = 0
      this.passedPath = []
      this.isFirstPlay = true
    },
    setVehicleSpeedInWidowns(lnglat, AMap) {
      for (var i = 0; i < this.positions.length; i++) {
        const content = `
          <div style="padding:10px;background: #fff;">
            <div style="padding-bottom: 5px;font-size: 18px;">${this.idInfo.meta.plateNumber}</div>
            <div style="padding: 0 5px;line-height: 25px;font-size: 14px;">
              <div ><span style="color:var(--antd-wave-shadow-color);font-size: 18px;font-weight: 500;">${this.originPositions[i].speed} KM</span>/h <span>
                <span style="font-size:14px;">超速路段 <span style="background:#de0000;width: 15px; height: 10px;display:inline-block;"></span></span>
                <span style="font-size:14px;">正常路段 <span style="background:#33b100;width: 15px; height: 10px;display:inline-block;"></span></span>
                </span></div>
            </div>
          </div>
        `
        if (lnglat.distance(new AMap.LngLat(this.originPositions[i].longitude, this.originPositions[i].latitude)) < 4) {
          this.basicInfo.setContent(content)
          return
        }
      }
    },
    clearPath() {
      this.path.forEach((item) => item.setMap(null))
      this.path = []
    },
    handleCarPathHistory(startTime, endTime) {
      this.clearPath()
      return getCarLocation({
        startTime,
        endTime,
        vehicleId: 195,
      }).then((res) => {
        const positions = res.data
        if (positions && positions.length > 2) {
          this.clearCarCache()
          this.originPositions = positions
          this.positions = positions.map((item) => [Number(item.longitude), Number(item.latitude)])
          this.startTime = positions[0].timeUtc8.split(' ')[1]
          this.currentTime = positions[0].timeUtc8
          this.endTime = positions[positions.length - 1].timeUtc8.split(' ')[1]
          //        获取地图类以及实例
          const AMap = this.carMap.AMap
          const mapInstace = this.carMap.map
          //        绘制路线
          this.drawCarPathLine(AMap, mapInstace)
          //        加载小车
          this.loadCar(AMap, mapInstace)
        }
      })
    },
  },
}
</script>

<style scoped lang="less">
.car-path-history {
  position: absolute;
  bottom: 20px;
  right: 20px;
  display: flex;
  justify-content: flex-end;
  align-items: center;

  .car-path-history-content {
    background-color: #fff;
    padding: 5px 10px;
    .car-path-time {
      display: flex;
      justify-content: center;
      align-items: center;
      color: red;
    }
  }
  .select-date-time {
    color: var(--antd-wave-shadow-color);
    cursor: pointer;
  }
  .car-path-control {
    // margin-right: 40px;
    pointer-events: all;
    display: flex;
    align-items: center;
    & > div {
      margin-right: 10px;
      &:nth-last-child(1) {
        margin: 0px;
      }
    }
    .control-slider {
      display: flex;
      align-items: center;
      .control-slider__inner {
        display: flex;
        align-items: center;
      }
      .slider {
        display: flex;
        flex-direction: column;

        .slider-origin {
          width: 340px;
          display: flex;
          align-items: center;
          /deep/ .ant-slider {
            flex: auto;
          }
        }

        .slider-time {
          display: flex;
          justify-content: space-between;
          align-items: flex-start;
        }
      }
      .select-btn {
        margin-left: 10px;
      }
    }
  }

  .gj-img {
    height: 88px;
    display: flex;
    align-items: center;
    .btn {
      width: 56px;
      height: 56px;
      background: url('../../../assets/images/gj.png') no-repeat;
      background-size: 100% 100%;
      cursor: pointer;
      pointer-events: all;
      margin-left: 20px;
    }
  }
}
</style>
