import { ref } from 'vue'
import Subscriber from '@cesium-extends/subscriber'
import { parseWKT } from '@/utils/parseWKT'
import { cesiumTime2Format } from '@/utils/date'
import { difference } from 'lodash'
import { getMubiaoPos, sendCheckedTargetIds } from '@/api/Mubiao'
import { useTree } from '@/utils/tree'
import { useMubiaoPopup } from './mubiaoPopup'
interface IMubiaoNode {
  country: string
  targetName: string
  targetType: string
  id: string
  extendInfo: Record<string, any>
}
interface IMubiao {
  dataId: string
  data: IMubiaoNode
  nodeName: string
  children?: IMubiao[]
}

const data = ref<Record<string, any>[]>([])

const mubiaoMap: Map<string | number, any> = new Map()
let subscriber: Subscriber | null = null

const { filterTreeNodeByField } = useTree()

const { popupMap, createPopup } = useMubiaoPopup()
export const useMubiao = () => {
  const addMubiao = async (ids: Array<string | number>) => {
    subscriber = new Subscriber(viewer, {
      pickResult: {
        enable: true,
      },
    })

    postCheckedIds(ids)
    // console.log(subscriber, 'subscriber')
    // const ids = data.map(item => item.id)
    const addIds = difference(ids, [...mubiaoMap.keys()])
    const removeIds = difference([...mubiaoMap.keys()], ids)

    // 添加
    if (addIds.length > 0) {
      const nodes = filterTreeNodeByField({
        treeData: data.value,
        params: addIds,
        paramName: 'dataId',
      })

      const targetIdList = nodes.map(({ dataId }: IMubiao) => dataId)
      // 获取目标坐标
      const mbPos = await getMubiaoCurPos(targetIdList)

      console.log('mbPos', mbPos)

      nodes.forEach(({ data, dataId: id }: IMubiao) => {
        const { target_time, target_geom } =
          mbPos.find(item => item.target_id === id) ?? {}
        const pos = parseWKT(target_geom).coordinates

        const mbEntity = addMubiaoEntity({ id, position: pos, target_time })

        // console.log(mbEntity, 'mbEntity')
        addEventSub(id, mbEntity, data)

        mubiaoMap.set(id, mbEntity)
      })
    }

    // 删除
    if (removeIds.length > 0) {
      removeIds.forEach(id => {
        removeMubiao(id)
      })
    }
  }

  async function postCheckedIds(ids: Array<string | number>) {
    const res = await sendCheckedTargetIds(ids)
  }

  const addMubiaoEntity = ({
    id,
    position,
    target_time,
  }: Record<string, string | number | number[]>) => {
    // 添加目标实体
    const mubiaoEntity = viewer.entities.add({
      name: id,
      position: Cesium.Cartesian3.fromDegrees(...(position as number[])),
      label: {
        text: `${id}`,
        font: '12pt sans-serif',
        fillColor: Cesium.Color.YELLOW,
        outlineColor: Cesium.Color.BLACK,
        outlineWidth: 2,
        style: Cesium.LabelStyle.FILL_AND_OUTLINE,
        pixelOffset: new Cesium.Cartesian2(20, -20),
        // disableDepthTestDistance: Number.POSITIVE_INFINITY,
      },
      model: {
        uri: '/models/驱逐舰2.glb',
        minimumPixelSize: 200,
        maximumScale: 20000,
      },
    })
    return mubiaoEntity
  }

  const addEventSub = (
    id: string | number,
    entity: Cesium.Entity,
    mbData: Record<string, any>
  ) => {
    subscriber &&
      subscriber.add(
        entity,
        (movement, entity) => {
          // console.log(movement, 'movement')
          // console.log(entity, 'entity')

          createPopup(id, entity, mbData)
        },
        'LEFT_CLICK'
      )
    // console.log(subscriber, '-------')
  }

  const removeMubiao = (id: string | number) => {
    if (mubiaoMap.has(id)) {
      subscriber && subscriber.remove(mubiaoMap.get(id), 'LEFT_CLICK')

      viewer.entities.remove(mubiaoMap.get(id))
      mubiaoMap.delete(id)
    }
    if (popupMap.has(id)) {
      popupMap.get(id).windowClose()
      popupMap.delete(id)
    }
  }

  const updateMubiaoPos = async (
    mbs: Array<Record<string, string | number>>
  ) => {
    // const existsIds = [...mubiaoMap.keys()]
    if (mbs.length === 0) {
      return
    }
    mbs.forEach(
      ({
        target_id: id,
        target_lon: lon,
        target_lat: lat,
        target_direction,
      }) => {
        if (mubiaoMap.has(id)) {
          const entity = mubiaoMap.get(id)
          const position = Cesium.Cartesian3.fromDegrees(lon, lat)
          entity.position = position

          entity.orientation = getOrientation({
            position,
            heading: target_direction as number,
          })
        }
      }
    )
  }

  const getOrientation = ({
    position,
    heading,
    pitch = 0,
    roll = 0,
  }: Record<string, number>) => {
    //模型朝向
    const h = Cesium.Math.toRadians(heading - 90)
    const p = Cesium.Math.toRadians(pitch)
    const r = Cesium.Math.toRadians(roll)
    const hpr = new Cesium.HeadingPitchRoll(h, p, r)
    const orientation = Cesium.Transforms.headingPitchRollQuaternion(
      position,
      hpr
    )
    return orientation
  }

  return {
    data,
    addMubiao,
    updateMubiaoPos,
  }
}

async function getMubiaoCurPos(ids: Array<string | number>) {
  const time = cesiumTime2Format(viewer.clock.currentTime)
  // 获取当前目标位置
  const { code, data } = await getMubiaoPos({ ids, current: time })
  if (code === '200') {
    return data
  } else {
    return []
  }
}
