<template>
  <div class="events">
    <div
      v-for="point in [currentEvents, nowEvent].flat()"
      class="event-x"
      :style="getStyle(point)"
      :key="point.id"
      @click="onClicked(point)"
      @animationend="onAnimationEnd"
    >
      <div v-if="EVENT_TYPE[point.eventType]" class="chip">
        <div class="text">{{ EVENT_TYPE[point.eventType] || '' }}</div>
        <div :class="['type-icon', `type-${point.eventType}`]"></div>
      </div>

      <div v-else class="chip">
        <div class="text">其他事件</div>
        <div class="type-icon type-0"></div>
      </div>

      <img :src="EVENT_IMAGE" />
    </div>
  </div>
</template>

<script lang="ts" setup>
// import { EVENT_TYPE } from '@/config/enum'
import { EVENT_TYPES } from '@/config/dict'
import EVENT_IMAGE from '@/assets/images/event/event.png'
import TrafficSocket from '@/views/traffic/utils/socket'
import { useRoute } from 'vue-router'
import { useTrafficStoreOut } from '@/store/modules/traffic'

const props = defineProps<{
  scene: string
  _traffic: any
  tunnel: any
  direction: number
  evtConfigs: any
}>()

const events = defineModel<any[]>('events') // 实时事件
const selected = defineModel<any>('selected') // 选中事件
const socketEvent = ref<any>(null) // 事件流
const trafficStore = useTrafficStoreOut()

const route = useRoute()

const EVENT_TYPE = Object.fromEntries(
  EVENT_TYPES.map((item) => {
    return [item.key, item.name]
  })
)

// 不自动隐藏的事件
const NO_HIDE_EVENT = [7, 14]

// 多车事件
const currentEvents = computed(() => {
  if (!events.value || !props.tunnel || !props._traffic) {
    return []
  }

  // const codes = [5, 6, 7]

  const evts = events.value
    // .filter(item => codes.includes(item.eventType))
    .map((item) => {
      const distance = !props.direction
        ? +item.milestone - props.tunnel.start
        : props.tunnel.end - +item.milestone
      return {
        ...item,
        distance
      }
    })

  return props._traffic.eventFormate(evts)
})

// 当前事件
const nowEvent = computed(() => {
  return []

  // if (route.name !== 'Detail' || !props.evtConfigs.status || !props.tunnel) {
  //   return []
  // }

  // const temp = { ...props.evtConfigs.infos };
  // delete temp.hisVehicleInfo

  // const distance = props.direction ? +temp.milestone - props.tunnel.start : props.tunnel.end - +temp.milestone

  // const evts = props._traffic.eventFormate([{
  //   ...temp,
  //   distance
  // }])

  // return evts
})

// 开启实时事件
const evtFlowStart = async () => {
  if (socketEvent.value) {
    socketEvent.value.close()
    socketEvent.value = null
  }

  socketEvent.value = new TrafficSocket(props.direction ? 'OUT_EVENT' : 'IN_EVENT')

  socketEvent.value.start((res) => {
    trafficStore.setEventCount(res.eventCount)
    trafficStore.setEventNotify(res.eventDetailRespVO)
    // events.value = props._traffic.eventFormate(res.eventThirdEventStatusNotFinishList)
    events.value = res.eventThirdEventStatusNotFinishList
  })
}

// 关闭事实事件
const evtFlowClose = () => {
  if (socketEvent.value) {
    socketEvent.value.close()
    socketEvent.value = null
  }
  events.value = []
}

// 处理动画结束事件
const onAnimationEnd = (event) => {
  if (event.animationName === 'fadeOut') {
    const target = event.target as HTMLElement;
    target.style.display = 'none';
  }
}

// 距离计算
const getStyle = (point) => {
  let style: any = {
    top: point.y + 'px',
    left: point.x + 'px',
    transform: point.transform
  }
  if (!NO_HIDE_EVENT.includes(point.eventType)) {
    style.animation = 'fadeOut 0.5s 5s forwards'
  }
  return style
}

const openEventAlert = inject<(info) => void>('openEventAlert')

// 事件点击
const onClicked = (event) => {
  // 回溯模式下不支持点击
  if (props?.evtConfigs?.status) {
    return
  }

  if (openEventAlert) {
    openEventAlert({id: event.id})
    return
  }
  selected.value = event.id
}

// 事件详情控制
watch(
  () => [props._traffic, props.evtConfigs],
  (e) => {
    if (!props._traffic) return

    if (route.name !== 'Detail') {
      evtFlowStart()
      return
    }

    e.status ? evtFlowClose() : evtFlowStart()
  },
  {
    immediate: true
  }
)

onMounted(() => {
  // evtFlowStart()
})

onBeforeUnmount(() => {
  // 清理事件实例的 WebSocket 连接
  evtFlowClose()
})
</script>

<style lang="scss" scoped>
$base-event: '@/assets/images/event/';

.event-x {
  width: 90px;
  height: 90px;
  position: absolute;
  z-index: 3;
  cursor: pointer;
  transform: translate(-50%, -50%);

  img {
    display: block;
    width: 100%;
    height: 100%;
  }
  .chip {
    position: absolute;
    top: -34px;
    left: 50%;
    transform: translateX(-50%);
    z-index: 2;
    display: flex;
    flex-direction: column;
    align-items: center;
    animation-name: wave;
    animation-duration: 1.85s;
    animation-fill-mode: forwards;
    animation-iteration-count: infinite;

    .text {
      font-size: 12px;
      background: #772727;
      border: 1px solid rgba(238, 89, 97, 0.8);
      padding: 2px 4px;
      border-radius: 2px;
      white-space: nowrap;
      color: white;
      margin-bottom: 4px;
    }

    .type-icon {
      width: 24px;
      height: 24px;
      background: url($base-event + 'event_01.png') no-repeat;
      background-size: cover;
    }

    .type-0,
    .type-1,
    .type-2,
    .type-3,
    .type-4,
    .type-8 {
      background: url($base-event + 'event_01.png') no-repeat;
      background-size: cover;
    }
  }
}

@keyframes wave {
  0% {
    transform: translate(-50%, 0px);
  }
  25% {
    transform: translate(-50%, 5px);
  }
  50% {
    transform: translate(-50%, 0px);
  }
  75% {
    transform: translate(-50%, 5px);
  }
  100% {
    transform: translate(-50%, 0px);
  }
}

@keyframes fadeOut {
  from {
    opacity: 1;
    visibility: visible;
  }
  to {
    opacity: 0;
    visibility: hidden;
  }
}
</style>
