import { twoline2satrec, propagate } from 'satellite.js'
import CreateFrustum from './sensor.js'
// import './polylineTrail.js'
import chroma from 'chroma-js'

class SatelliteEntity {
  constructor(tle = '', options = {}) {
    const [name, tleLine1, tleLine2] = this._checkTle(tle)
    let circle = tleLine2.slice(52, 64)

    this.name = name.trim()
    this.tleLine1 = tleLine1.trim()
    this.tleLine2 = tleLine2.trim()
    this.satrec = twoline2satrec(this.tleLine1, this.tleLine2)

    this.totalSeconds = 7 * 86400 // 24小时
    this.stepSeconds = 100
    this.leadTime = parseInt((24 * 3600) / circle)
    this.trailTime = 0
    this.sensor = false
    this.entity = null
    this.sensorType = 'rectangle'
  }
  get sensor() {
    return this.sensor
  }
  set sensor(showSensor) {
    console.log(showSensor, 'showSensor')
    if (showSensor) {
      if (this.sensorType === 'conic') {
        this.createConicSensor(this.entity)
      } else {
        this.createRectangleSensor(this.entity)
      }
    }
    //showSensor &&
  }

  _checkTle(tle) {
    let elements = tle.split('\n')
    if (elements.length !== 3) {
      throw new Error('tle data error')
    }
    return elements
  }

  // 获取地心惯性坐标系坐标
  getPositionEci(time) {
    return propagate(this.satrec, time).position
  }

  // 创建PositionProperty
  _getPositionProperty() {
    const start = Cesium.JulianDate.fromIso8601(new Date().toISOString())
    const positionProperty = new Cesium.SampledPositionProperty(
      Cesium.ReferenceFrame.INERTIAL
    )

    let now = Date.now()
    for (let i = 0; i < this.totalSeconds / this.stepSeconds; i++) {
      let sateTime = new Date(now + i * this.stepSeconds * 1000)
      let sateCoord = this.getPositionEci(sateTime)
      if (!sateCoord) {
        continue
      }
      const cesiumTime = Cesium.JulianDate.addSeconds(
        start,
        i * this.stepSeconds,
        new Cesium.JulianDate()
      )
      const cesiumPosition = {
        x: sateCoord.x * 1000,
        y: sateCoord.y * 1000,
        z: sateCoord.z * 1000,
      }
      positionProperty.addSample(cesiumTime, cesiumPosition)
    }
    return positionProperty
  }

  // 创建卫星实例
  createSatelliteEntity() {
    const start = Cesium.JulianDate.fromIso8601(new Date().toISOString())
    const stop = Cesium.JulianDate.addSeconds(
      start,
      this.totalSeconds,
      new Cesium.JulianDate()
    )
    const color = Cesium.Color.fromCssColorString(
      chroma.random().brighten().hex()
    )
    // const color = Cesium.Color.fromRandom({ alpha: 0.5 })
    let satelliteEntity = {
      name: this.name,
      description: this.name,
      show: true,
      availability: new Cesium.TimeIntervalCollection([
        new Cesium.TimeInterval({ start: start, stop: stop }),
      ]),
      position: this._getPositionProperty(),
      // point: {
      //   pixelSize: 8,
      //   color: color,
      //   // scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1, 8.0e8, 0.5),
      // },
      path: new Cesium.PathGraphics({
        width: 2,
        show: true,
        leadTime: this.leadTime,
        trailTime: this.trailTime,
        // material: color,
        material: new Cesium.PolylineTrailLinkMaterialProperty({
          color,
          duration: 86400 * 1000,
        }),
      }),
      label: {
        show: true,
        text: this.name,
        font: '12px sans-serif',
        showBackground: true,
        backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5),
        backgroundPadding: new Cesium.Cartesian2(4, 4),
        outlineWidth: 1,
        verticalOrigin: Cesium.VerticalOrigin.TOP,
        horizontalOrigin: Cesium.VerticalOrigin.LEFT,
        pixelOffset: new Cesium.Cartesian2(0, 5),
        fillColor: Cesium.Color.WHITE,
        // distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 50000000),
      },
      billboard: {
        image: '/images/satellite.png',
        width: 40,
        height: 40,
        show: true,
        distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
          10.0,
          50000000
        ),
      },
      // model: {
      //   uri: '/GV/resources/model/wx.glb',
      //   minimumPixelSize: 64,
      //   maximumScale: 20000,
      //   show: true,
      //   distanceDisplayCondition: new Cesium.DistanceDisplayCondition(
      //     10.0,
      //     50000000
      //   ),
      // },
      // cylinder: {
      //   HeightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
      //   length: 1700000,
      //   topRadius: 0,
      //   bottomRadius: 700000 / 2,
      //   material: Cesium.Color.RED.withAlpha(0.4),
      //   outline: !0,
      //   numberOfVerticalLines: 0,
      //   outlineColor: Cesium.Color.RED.withAlpha(0.8),
      //   horizontalOrigin: Cesium.HorizontalOrigin.CENTER,
      // },
      orientation: new Cesium.VelocityOrientationProperty(
        this._getPositionProperty()
      ),
    }
    // this.createSensor(satelliteEntity)
    // return satelliteEntity

    this.entity = viewer.entities.add(satelliteEntity)
    return this.entity
  }

  createSensor(satellite) {
    // const color = '#00ffff'
    // let customSensor = new CesiumSensorVolumes.RectangularPyramidSensorVolume()
    // // const sate = tasks.value.find((item) => item.satId === sate_id);
    // // radius 是指波束的长度
    // customSensor.radius = 40000000.0
    // // customSensor.id = `${sate_id}_sensor`;
    // customSensor.id = `test_sensor`
    // customSensor.intersectionWidth = 1
    // customSensor.xHalfAngle = Cesium.Math.toRadians(1)
    // customSensor.yHalfAngle = Cesium.Math.toRadians(1)
    // customSensor.lateralSurfaceMaterial = Cesium.Material.fromType('Color')
    // customSensor.lateralSurfaceMaterial.uniforms.color =
    //   new Cesium.Color.fromCssColorString(color).withAlpha(0.3)
    // // 默认矩阵
    // customSensor.modelMatrix = new Cesium.Matrix4()
    // // 使用preRender 监听卫星每帧运动
    // viewer.scene.preRender.addEventListener((scene, time) => {
    //   customSensor.show = false
    //   // 判断数据源中所有实体是否准备就绪，viewer.dataSourceDisplay.dataSources = viewer.dataSources
    //   if (viewer.dataSourceDisplay.ready) {
    //     // const satellite = viewer.dataSources
    //     //   .getByName("simDemon")[0]
    //     //   .entities.getById(sate_id);
    //     // 根据时间获取卫星实时笛卡尔位置
    //     let position = Cesium.Property.getValueOrUndefined(
    //       satellite.position,
    //       time,
    //       new Cesium.Cartesian3()
    //     )
    //     // 根据卫星位置和朝向转换为矩阵信息，此处使用的是后台计算的四元数，实际一般情况应该使用Cesium.Transforms+position转换
    //     console.log(
    //       satellite.orientation.getValue(time),
    //       'satellite.orientation.getValue(time)'
    //     )
    //     // let m = Cesium.Matrix4.fromRotationTranslation(
    //     //   Cesium.Matrix3.fromQuaternion(
    //     //     satellite.orientation.getValue(time),
    //     //     new Cesium.Matrix3()
    //     //   ),
    //     //   position,
    //     //   new Cesium.Matrix4()
    //     // )
    //     let m = this.getModelMatrix(position, satellite.orientation)
    //     console.log(m, 'm')
    //     // // let m = Cesium.Transforms.northUpEastToFixedFrame(position)
    //     customSensor.modelMatrix = m
    //     // customSensor.modelMatrix = this.getModelMatrix()
    //     customSensor.show = true
    //   }
    // })
    // viewer.scene.primitives.add(customSensor)
    // let position = Cesium.Property.getValueOrUndefined(
    //   satellite.position,
    //   viewer.clock.currentTime,
    //   new Cesium.Cartesian3()
    // )
  }

  createRectangleSensor(satellite) {
    // viewer.scene.primitives.removeAll()
    let position = Cesium.Property.getValueOrUndefined(
      satellite.position,
      viewer.clock.currentTime,
      new Cesium.Cartesian3()
    )
    const rectangularPyramidSensor =
      new CesiumSensorVolumes.RectangularPyramidSensorVolume()
    rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position)
    rectangularPyramidSensor.radius = 20000000.0
    rectangularPyramidSensor.xHalfAngle = Cesium.Math.toRadians(20.0)
    rectangularPyramidSensor.yHalfAngle = Cesium.Math.toRadians(10.0)
    rectangularPyramidSensor.lateralSurfaceMaterial =
      Cesium.Material.fromType('Color')
    rectangularPyramidSensor.lateralSurfaceMaterial.uniforms.color =
      new Cesium.Color(0.0, 1.0, 1.0, 0.3)

    viewer.scene.preRender.addEventListener((scene, time) => {
      rectangularPyramidSensor.show = false
      let position = Cesium.Property.getValueOrUndefined(
        satellite.position,
        time,
        new Cesium.Cartesian3()
      )
      rectangularPyramidSensor.modelMatrix = this.getModelMatrix(position)
      rectangularPyramidSensor.show = true
    })

    viewer.scene.primitives.add(rectangularPyramidSensor)
  }

  getModelMatrix(location) {
    // let ellipsoid = viewer.scene.globe.ellipsoid
    // console.log(position, '----')
    // let location = ellipsoid.cartographicToCartesian(
    //   new Cesium.Cartographic(
    //     Cesium.Math.toRadians(120.0),
    //     Cesium.Math.toRadians(24.0),
    //     1300000
    //   )
    // )
    let modelMatrix = Cesium.Transforms.northEastDownToFixedFrame(location)
    let orientation = Cesium.Matrix3.multiply(
      Cesium.Matrix3.multiply(
        Cesium.Matrix3.fromRotationZ(0.0),
        Cesium.Matrix3.fromRotationY(Cesium.Math.toRadians(0.0)),
        new Cesium.Matrix3()
      ),
      Cesium.Matrix3.fromRotationX(0.0),
      new Cesium.Matrix3()
    )
    return Cesium.Matrix4.multiply(
      modelMatrix,
      Cesium.Matrix4.fromRotationTranslation(
        orientation,
        Cesium.Cartesian3.ZERO
      ),
      new Cesium.Matrix4()
    )
  }

  createConicSensor(satellite) {
    let position = Cesium.Property.getValueOrUndefined(
      satellite.position,
      viewer.clock.currentTime,
      new Cesium.Cartesian3()
    )
    // const conicSensor = new CesiumSensorVolumes.ConicSensorGraphics()
    // conicSensor.radius = 20000000.0
    // conicSensor.modelMatrix = this.getModelMatrix(position)
    // conicSensor.intersectionColor = new Cesium.ConstantProperty(
    //   new Cesium.Color(0.1, 0.2, 0.3, 0.4)
    // )
    const customSensor = new CesiumSensorVolumes.CustomSensorVolume()
    customSensor.modelMatrix = this.getModelMatrix(position)
    customSensor.radius = 20000000.0
    // customSensor.directions = directions;
    viewer.scene.primitives.add(customSensor)

    viewer.scene.preRender.addEventListener((scene, time) => {
      customSensor.show = false
      let position = Cesium.Property.getValueOrUndefined(
        satellite.position,
        time,
        new Cesium.Cartesian3()
      )
      customSensor.modelMatrix = this.getModelMatrix(position)
      customSensor.show = true
    })

    viewer.scene.primitives.add(customSensor)
  }

  // createSensor(satellite) {
  //   // let sensor = new Sensor({
  //   //   position: satellite.position,
  //   //   orientation: satellite.orientation,
  //   //   aspectRatio: 1000,
  //   // })
  //   // viewer.scene.preRender.addEventListener((scene, time) => {
  //   let position = Cesium.Property.getValueOrUndefined(
  //     satellite.position,
  //     viewer.clock.currentTime,
  //     new Cesium.Cartesian3()
  //   )
  //   console.log(position, 'position')

  //   let heading = 0
  //   let pitch = 0
  //   let roll = 90
  //   let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll)
  //   let orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr)
  //   let sensor = new CreateFrustum({
  //     position: position,
  //     orientation: orientation,
  //     far: 1000000,
  //     aspectRatio: 600 / 1080,
  //   })
  //   console.log(sensor, 'sensor')
  //   // })
  // }
}

export default SatelliteEntity
