<template>
  <div class="flex flex-row overflow-auto position-relative" style="height: calc(100vh - 125px)">
    <div class="flex-1 h-full position-relative">
      <OpenLayerMap
        ref="mapRef"
        class="map-container"
        :showTrajectories="true"
        :showDrawFences="false"
        :markers="filterMarkers"
        :fences="fences"
        @time-range-change="timeRangeChange"
        @on-click-marker="onClickMarker"
      />
      <TopPanel
        v-model:search="search"
        v-model:selectStatus="selectStatus"
        :handDetectorCount="handDetectorCount"
        :onlineCount="onlineCount"
      />
    </div>
    <div class="markerList">
      <div style="height: 100%">
        <VirtualCollapsePanel
          ref="scrollbarRef"
          :data="filterMarkers"
          key-field="id"
          name-field="name"
          :min-item-size="40"
        >
          <template #header="{ item }">
            <div class="marker-item">
              <div class="flex-1 text-13px"> {{ item.name }}</div>
              <div class="text-12px pr-1" :style="{ color: item.statusColor }">
                {{ item.statusLabel }}
              </div>
            </div>
          </template>
          <template #content="{ item }">
            <div class="markerList-content">
              <div><span>SN：</span>{{ item.sn }}</div>
              <div><span>类型：</span>{{ item.gasChemical }}</div>

              <div
                ><span>气体状态：</span
                >{{ getLabelWithTypeValue('gasStatus', item.gasStatus) }}</div
              >
              <div
                ><span>围栏状态：</span
                >{{ getLabelWithTypeValue('fenceStatus', item.fenceStatus) }}</div
              >
              <div
                ><span>电池状态：</span
                >{{ getLabelWithTypeValue('batteryStatus', item.batteryStatus) }}</div
              >

              <div><span>电量：</span>{{ item.battery }}</div>
              <div><span>数值：</span>{{ item.value }} {{ item.unit }}</div>
               
              <div><span>信号：</span>{{ item.sig||'' }}</div> 

              <div><span>时间：</span>{{ item.timeStr }}</div>

              <div style="margin-top: 10px">
                <el-button
                  plain
                  size="small"
                  v-if="item.latitude && item.longitude"
                  @click="setCenter(item)"
                  >定位</el-button
                >
                <el-button
                  v-hasPermi="['gas:hand-td:HistoricalSn']"
                  plain
                  size="small"
                  @click="onClickTrajectory(item)"
                  >轨迹</el-button
                >
                <el-button
                  v-hasPermi="['gas:hand-td:HistoricalSn']"
                  plain
                  size="small"
                  @click="onClickHistoricalCurve(item)"
                  >历史曲线</el-button
                >
              </div>
            </div>
          </template>
        </VirtualCollapsePanel>
      </div>
    </div>
    <HistoricalCurve ref="historicalCurveRef" />
  </div>
</template>
<script lang="ts" setup>
import OpenLayerMap from './components/OpenLayerMap.vue'
import TopPanel from './components/TopPanel.vue'
import HistoricalCurve from './components/HistoricalCurve.vue'
import VirtualCollapsePanel from '@/components/VirtualCollapsePanel/index.vue'

import { getLastDetectorData } from '@/api/gas'
import type { HandDetectorData } from '@/api/gas/handdetector'
import { tdengineApi } from '@/api/gas/tdengine/index'

import {
  getLabelWithTypeValue,
  getHighestPriorityStatus,
  getStatusLabel,
  getStatusColor,
  getStatusPriority
} from './components/utils/map.utils'

import { MarkerData, FenceData } from './components/types/map.types'

import { useHandDetectorStore } from '@/store/modules/handDetector'
import { ElMessage, ElScrollbar } from 'element-plus'
import dayjs from 'dayjs'
import { getDistance } from 'ol/sphere'
import { shallowRef } from 'vue'
const componentsIsActive = ref(false)

const handDetectorStore = useHandDetectorStore() // 手持探测器 store

const getDataTimer = ref<NodeJS.Timeout | null>(null)
const markers = shallowRef<MarkerData[]>([])
const fences = ref<FenceData[]>([])

const mapRef = ref<InstanceType<typeof OpenLayerMap>>()
const search = ref('')
const selectStatus = ref(['normal', 'offline', 'fenceStatus_1', 'alarm', 'batteryStatus_1'])
watch(
  () => search.value,
  (newSearch, oldSearch) => {
    if (newSearch !== oldSearch) {
      mapRef.value?.fitToMarkers()
    }
  },
  { immediate: false }
)

// 手持设备数量
const handDetectorCount = computed(() => markers.value.length)
const onlineCount = computed(() => markers.value.filter((item) => item.onlineStatus === 1).length)
const filterMarkers = computed(() => {
  var arr = markers.value
  if (search.value) {
    arr = markers.value.filter((item) => {
      var isName = item?.name?.includes(search.value)
      var isSn = item.sn?.includes(search.value)
      var isGasChemical = item.gasChemical?.includes(search.value)

      return isName || isSn || isGasChemical
    })
  }

  if (selectStatus.value.length !== 0) {
    arr = arr.filter((item) => {
      // console.log('selectStatus', selectStatus.value,item.statusStr);
      if (!item.statusStr) {
        return true
      }
      if (item.statusStr == 'gasStatus_2' || item.statusStr == 'gasStatus_1') {
        return selectStatus.value.includes('alarm')
      }
 
      return selectStatus.value.includes(item.statusStr)
    })
  }
 

  return arr
})

const filterMarkers2 = function getFilterMarkers2() {
  var arr: MarkerData[] = []
  var nowTime = dayjs().format('YYYY-MM-DD HH:mm:ss')
  const arr2=[
    {
      statusStr: 'normal',
      statusColor: '#67c23a',
      statusLabel: '正常',
      statusPriority: 7,
      
    },{
      statusStr: 'offline',
      statusColor: '#909399',
      statusLabel: '离线',
      statusPriority: 6,

    },{
      statusStr: 'fenceStatus_1',
      statusColor: '#e6a23c',
      statusLabel: '电子围栏报警',
      statusPriority: 5,
    },{
      statusStr: 'gasStatus_1',
      statusColor: '#f56c6c',
      statusLabel: '报警',
      statusPriority: 4,
    },{
      statusStr: 'batteryStatus_1',
      statusColor: '#f56c6c',
      statusLabel: '电池报警',
      statusPriority: 3,
    }
  ]
  for (let i = 0; i < 10000; i++) {
    const statusInfo = arr2[Math.floor(Math.random() * arr2.length)]
    const lon = 100 + Math.random() * 2
    const lat = 30 + Math.random() * 2
    arr.push({
      id: i + 1,
      sn: '867989072728120',
      battery: 3786,
      value: 4,
      longitude: lon,
      latitude: lat,
      time: 1762937859776,
      name: '侯荣刚',
      fenceIds: '',
      fenceType: 1,
      gasTypeId: 1,
      unit: 'ppm',
      gasChemical: 'CO',
      batteryAlarmValue: 20,
      accuracy: 1,
      alarmLevel: 1,
      maxAlarmLevel: null,
      firstValue: null,
      maxValue: null,
      gpsType: 0,
      gasStatus: 2,
      alarmId: 200,
      batteryStatus: 0,
      batteryStatusAlarmId: null,
      fenceStatus: 0,
      fenceAlarmId: null,
      onlineStatus: 1,
      enableStatus: 1,
      distance: null,
      maxDistance: null,
      tenantId: null,
      talarmStart: null,
      talarmEnd: null,
      coordinates: [lon, lat],
      timeStr: nowTime,
      statusStr: statusInfo.statusStr,
      statusColor: statusInfo.statusColor,
      statusLabel: statusInfo.statusLabel,
      statusPriority: statusInfo.statusPriority,
      expanded: false
    })
  }
  markers.value = arr
}
const getMarkers = async () => {
  console.log('getMarkers')
  return await getLastDetectorData().then((res: HandDetectorData[]) => {
    res = res.filter((i) => i.enableStatus === 1)
    var res2 = res
      .map((i) => {
        let statusStr = getHighestPriorityStatus({
          gasStatus: i.gasStatus, //气体报警状态
          batteryStatus: i.batteryStatus, //电池报警状态
          fenceStatus: i.fenceStatus, //电子围栏报警状态
          onlineStatus: i.onlineStatus //在线状态
        }) //状态字符串
        return {
          ...i,
          coordinates: [i.longitude || 0, i.latitude || 0] as [number, number],

          timeStr: i.time ? dayjs(i.time).format('YYYY-MM-DD HH:mm:ss') : '',

          statusStr: statusStr, //状态字符串
          statusColor: getStatusColor(statusStr), //状态颜色
          statusLabel: getStatusLabel(statusStr), //状态标签
          statusPriority: getStatusPriority(statusStr) //状态优先级,
        }
      })
      .sort((a, b) => a.statusPriority - b.statusPriority)

    markers.value = res2
  })
}
const getFences = async () => {
  return await handDetectorStore.getAllFences().then((res) => {
   
    let fencesData = res
      .map((i) => {
        return {
          ...i,
          fenceRange: JSON.parse(i.fenceRange)
        }
      })
      .filter((i) => i.status === 1)
    fences.value = fencesData as unknown as FenceData[]
  })
}
// 定位到手持设备
function setCenter(item: MarkerData) {
  if (item.longitude && item.latitude) {
    mapRef.value?.setCenter([item.longitude || 0, item.latitude || 0])
  }
}
// 记录当前选中的手持设备，主要用于重新获取轨迹
let currentMarker: MarkerData | null = null
var trajectoryTimeRange = ref([dayjs().subtract(1, 'hour').valueOf(), dayjs().valueOf()])
// 时间范围改变
function timeRangeChange(range: { startTime: number; endTime: number }) {
  console.log('timeRangeChange', range)
  trajectoryTimeRange.value = [range.startTime, range.endTime]
  if (currentMarker) {
    showTrajectory(currentMarker)
  }
}
// 显示手持设备轨迹
async function showTrajectory(item: MarkerData) {
  console.log('showTrajectory', item)
  try {
    if (!item.sn) {
      ElMessage.error('手持设备无效')
      return
    }
    currentMarker = item
    const data = await tdengineApi.getHistoricalSn({
      sn: item.sn,
      startTime: dayjs(trajectoryTimeRange.value[0]).format('YYYY-MM-DD HH:mm:ss'),
      endTime: dayjs(trajectoryTimeRange.value[1]).format('YYYY-MM-DD HH:mm:ss')

      // sn: '867989072729904'
    })
    if (!data || data.length === 0) {
      ElMessage.error(
        `${dayjs(trajectoryTimeRange.value[0]).format('YYYY-MM-DD HH:mm:ss')}至${dayjs(trajectoryTimeRange.value[1]).format('YYYY-MM-DD HH:mm:ss')}时段没有轨迹数据`
      )
      // return
    }
    // 过滤前
    // console.log('过滤前', data.length)
    // 过滤掉重复点位和无效点位
    var newData = data.filter((item, index, arr) => {
      if (!item.longitude || !item.latitude) {
        return false
      }
      if (index === 0) {
        return true
      }
      // 过滤掉前后点位一样的
      return (
        item.longitude !== arr[index - 1]?.longitude || item.latitude !== arr[index - 1]?.latitude
      )
    })
    // 过滤后
    // console.log('过滤后', newData.length)

    item.data = newData
      .filter((item, index, arr) => {
        if (index === 0) {
          return true
        }
        if (index == arr.length - 1) {
          return true
        }

        // 过滤掉前后点位相差超过100m的
        let before = arr[index - 1]
        let after = arr[index + 1]

        let before_after_distance = getDistance(
          [after.longitude, after.latitude],
          [before.longitude, before.latitude]
        )

        // 过滤小范围移动点位
        if (before_after_distance < 6) {
          console.log('过滤小范围移动点位', before_after_distance)
          return false
        }

        let beforeDistance = getDistance(
          [before.longitude, before.latitude],
          [item.longitude, item.latitude]
        )

        let afterDistance = getDistance(
          [after.longitude, after.latitude],
          [item.longitude, item.latitude]
        )

        // 过滤掉前、后点位都超过40m的,且前和后点位小于20m的，
        if (beforeDistance > 40 && afterDistance > 40 && before_after_distance < 20) {
          console.log(
            '过滤掉前和后点位相差小于20m的，且与前、后点位都超过40m的',
            beforeDistance,
            afterDistance,
            before_after_distance
          )
          return false
        }

        // console.log('beforeDistance', afterDistance)
        // console.log('前距离', beforeDistance,'后距离',afterDistance,'前后距离',before_after_distance)

        return true
      })
      .map((j) => {
        return {
          ...j,
          lng: j.longitude,
          lat: j.latitude,
          time: dayjs(j.ts).format('YYYY-MM-DD HH:mm:ss'),
          timeStr: dayjs(j.ts).format('YYYY-MM-DD HH:mm:ss')
        }
      })
    console.log('item.data', item.data)

    mapRef.value?.showTrajectory(trajectoryTimeRange.value[0], trajectoryTimeRange.value[1], [item])
  } finally {
  }
}
const historicalCurveRef = ref<InstanceType<typeof HistoricalCurve>>()
// 点击历史曲线
function onClickHistoricalCurve(item: MarkerData) {
  historicalCurveRef.value?.openDrawer(toRaw(item))
}

// 点击轨迹
function onClickTrajectory(item: MarkerData) {
  trajectoryTimeRange.value = [dayjs().subtract(1, 'hour').valueOf(), dayjs().valueOf()]
  showTrajectory(item)
}

const scrollbarRef = useTemplateRef<InstanceType<typeof VirtualCollapsePanel>>('scrollbarRef')
// 点击手持设备
function onClickMarker(markerItem: MarkerData) {
  var findIndex = filterMarkers.value.findIndex((item) => item.id === markerItem.id)
  if (findIndex === -1) {
    return
  }
  // console.log('findIndex', findIndex, filterMarkers.value[findIndex])

  scrollbarRef.value?.scrollToIndex(findIndex)
}

onMounted(() => {
  getMarkers()
  // filterMarkers2()

  getFences()

  getDataTimer.value = setInterval(() => {
    if (!componentsIsActive.value) {
      return
    }
    getMarkers()
    // filterMarkers2()
    getFences()
  }, 4000)
})

onActivated(() => {
  componentsIsActive.value = true
})
onDeactivated(() => {
  componentsIsActive.value = false
})
onUnmounted(() => {
  clearInterval(getDataTimer.value as NodeJS.Timeout)
})
</script>
<style scoped lang="scss">
.map-container {
  width: 100%;
  height: 100%;
}
.markerList {
  position: absolute;
  top: 60px;
  right: 10px;
  bottom: 10px;
  width: 240px;
  border-radius: 8px;

  // height: 100%;
  overflow: hidden;
  background-color: rgba(255, 255, 255, 0.8);
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
  padding: 5px 0 10px 10px;
  margin-left: 10px;

  .marker-item {
    display: flex;
    flex-direction: row;
    font-family: var(--el-font-family);
  }
  .markerList-content {
    // border-top: 1px solid rgba(0, 0, 0, 0.1);
    padding: 10px;
    font-size: 12px;
    font-weight: 400;
    color: #444343;

    span {
      display: inline-block;
      min-width: 70px;
    }
  }
}
</style>
<style>
.el-collapse-item__header {
  background-color: transparent;
  color: #444343;
}
.el-collapse-item__wrap {
  background-color: rgba(255, 255, 255, 0.8);
}
</style>
