<template>

<div :class="['cars', scene, direction ? 'out' : 'in']" >
  <div
    v-for="item in cars"
    :class="classFix(item)"
    :key="item.id"
    :style="item.style"
    @click="onClicked(item)"
  >
    <div :style="geMaterial(item)" class="core"></div>
    <div class="nameplate">
      {{ getPlateName(item.originalCar) }}
    </div>

    <div
      class="tracker"
      v-if="hasWave(item)"
    ></div>

    <RoadEvent v-if="eventMap && eventMap[item.id]" :scene :event="eventMap[item.id]" />

  </div>

</div>

</template>

<script lang='ts' setup>

import RoadEvent from '../RoadEvent/index.vue'

import TrafficSocket from '@/views/traffic/utils/socket'
import { numToStone, awaitGet } from '@/utils/tunnel'
import { useRoute } from 'vue-router'
import { useTrafficStoreOut } from '@/store/modules/traffic'

import { setRunFlows, setUpdateFlows } from '@/flash/Common'
import { CAR_TYPES } from '@/config/dict'
import bus from '@/utils/eventBus'

import DEFAULT_CAR from '@/assets/images/cars/default.png'

const props = withDefaults(defineProps<{
  scene: string,
  _traffic: any,
  _events: any[], // 事件列表
  tunnel: any,
  direction: number,
  useMaterial: boolean,
  plateType: number, // 铭牌类型
  trackers: any, // 追踪车辆
  evtConfigs: any, // 当前事件
  filterType?: null | string // 筛选类型
}>(), {
  filterType: null
})

const emits = defineEmits(['car-socket'])
const route = useRoute()
const trafficStore = useTrafficStoreOut()

const IMAGE_BASE = import.meta.env.VITE_IMAGE_BASE

const cars = defineModel<any[]>('cars') // 车流
const selected = defineModel<any>('selected') // 选中车辆

const trackCar = ref(null) // 追踪车辆
// const events = ref<any[]>([]) // 事件

// const eventCars = ref<any[]>([]) // 事件车辆

let engine: any = null // 动画引擎
let timmer: any = null

const funclink = inject('funclink')

// 事件动画 map
const mapEvents = computed(() => {
  const codes = [0, 1, 2, 3, 4, 8]
  return Object.fromEntries(
    [...trafficStore.getOldEvents, ...trafficStore.getNowEvents].filter(item => codes.includes(item.type))
    .map(item => {
      return [item.id, item.type]
    })
  )
})

// 开启车流
const scoketStart = () => {

  props._traffic.startTraffic(res => {
    const { dangerousCount, truckCount, passengerCount, sedanCount, otherCount, vehicleInfoList = [] } = res

    emits('car-socket', {
      dangerousCount, truckCount, passengerCount, sedanCount, otherCount,
      total: dangerousCount + dangerousCount + passengerCount + sedanCount + otherCount
    })
  })

}

// 模拟车流
const replayStart = (frames) => {
  props._traffic.startMook(res => {
    const tempArr = res.map(xcar => {
      const { carId, roadNo, speed, carMilestone, vehicleType, carPlate } = xcar
      const { car_width, car_length } = CAR_TYPES[vehicleType]

      const distance = props.direction ? carMilestone - props.tunnel.start : props.tunnel.end - carMilestone

      return {
        id: carId,
        mook: true,
        direction: props.direction, // 方向
        carMilestone,
        plate: carPlate, // 车牌
        type: vehicleType, // 类型
        speed, // 速度
        line: roadNo + 1, // 车道
        distance: distance < 0 ? 0 : distance, // 行驶距离
        car_width, // 车宽
        car_length, // 车长
    
        originalCar: JSON.parse(JSON.stringify(xcar)) // 车辆数据副本
      }
    })

  }, frames)
}

// class 补全
const classFix = (item) => {
  const {
    type,
    originalCar: { isFocusMark, isDangerous }
  } = item
  const classArr = ['running-car', 'type-' + type]

  if (isDangerous) {
    classArr.push('collected')
  } else if (isFocusMark) {
    classArr.push('collected')
  } else if (type == props.filterType || item.id === selected.value ) {
    classArr.push('selected')
  }

  return classArr
}

// 追踪波查询
const hasWave = (xcar: any) => {
  const ids = [
    ...trafficStore.getWaves,
    props?.trackers?.id || null
  ].filter(item => item)

  return ids.includes(xcar.id)
}

// 获取贴图
const geMaterial = (xcar) => {
  if (!props.useMaterial) {
    return null
  }
  return {
    backgroundImage: `url(${xcar.originalCar.carImageUrl ? IMAGE_BASE + xcar.originalCar.carImageUrl : DEFAULT_CAR })`,
    backgroundRepeat: 'no-repeat',
    backgroundPosition: 'center',
    backgroundSize: 'contain',
    transform: `rotateY(${props.direction ? 0 : 180}deg)`
  }
}

// 铭牌计算
const getPlateName = (xcar) => {
  if (props.plateType === 1) {
    return xcar.carPlate
  }

  if (props.plateType === 2) {
    return CAR_TYPES[xcar.vehicleType].name
  }

  if (props.plateType === 3) {
    return xcar.speed + ' km/h'
  }

  if (props.plateType === 4) {
    return numToStone(xcar.carMilestone)
  }
}

// 车辆展示
const onClicked = (car) => {
  selected.value = car.id
}

const trafficStart = () => {

  clearInterval(timmer)
  cars.value = []
  scoketStart()

}

const mookTrafficStart = (frames) => {
  clearInterval(timmer)
  cars.value = []
  replayStart(frames)
}

const runFrame = () => {
  cars.value = props._traffic?.exportCars() || []
  engine = window.requestAnimationFrame(() => {
    runFrame()
  })
}

const flowStart = async (frames) => {

  const isAvl = await awaitGet(() => props._traffic)
  if (!isAvl) return
  props._traffic.startMook(frames)

}

const flowRestart = async () => {

  const isAvl = await awaitGet(() => props._traffic)
  if (!isAvl) return
  props._traffic.reMook()

}


// 数据同步
const onlineRunning = async () => {

  const isAvl = await awaitGet(() => props._traffic)

  if (isAvl) {
    props._traffic.startTraffic(res => {

      const { dangerousCount, truckCount, passengerCount, sedanCount, otherCount, vehicleInfoList = [] } = res

      emits('car-socket', {
        dangerousCount, truckCount, passengerCount, sedanCount, otherCount,
        total: dangerousCount + dangerousCount + passengerCount + sedanCount + otherCount
      })

    })
  }

}


onMounted(() => {

  runFrame()

  // if (!['HistoryTrack', 'HistoryEvent', 'Detail'].includes(route.name)) {
  //   onlineRunning()
  // }

  // if (funclink) {
  //   funclink('flowStart', flowStart)
  //   funclink('flowRestart', flowRestart)
  //   funclink('onlineRunning', onlineRunning)
  // }
  
})

onUnmounted(() => {
  if (engine) {
    cancelAnimationFrame(engine)
  }
})

</script>

<style lang='scss' scoped>

@import url(@/views/traffic/css/car.scss);
$base-event: '@/assets/images/event/';

.panorama {

  .running-car {
    width: 36px;
    height: 12px;
    .tracker {
      width: 84px;
      height: 84px;
      position: absolute;
      left: 50%;
      top: 50%;
      z-index: -1;
      background: url($base-event + 'tracker.png') no-repeat;
      background-size: cover;
      transform: translate(-50%, -50%);
    }

    .nameplate {
      font-size: 12px;
      top: -24px;
      padding: 2px 5px;
    }

  }
  
}

.section {

  .running-car {
    width: 120px;
    height: 40px;
    .nameplate {
      font-size: 16px;
      top: -28px;
      padding: 2px 8px;
    }

    .tracker {
      width: 150px;
      height: 150px;
      position: absolute;
      left: 50%;
      top: 50%;
      z-index: -1;
      background: url($base-event + 'tracker.png');
      background-size: cover;
      transform: translate(-50%, -50%);
    }
  }
  
}

.in {
  .running-car {
    right: 0px;
    bottom: 0px;
  }
}

.out {
  .running-car {
    left: 0px;
    top: 0px;
    .core {
      transform: rotateY(180deg);
    }
  }
}


</style>