import * as THREE from 'three'
import FlowModel from './flow'
import CarModel from './car'
import { amtMount } from '../center'

import LFT_1 from '../lines/LFT_1'
import LFT_2 from '../lines/LFT_2'
import RGT_1 from '../lines/RGT_1'
import RGT_2 from '../lines/RGT_2'

export default class Tunnel {

  context = null // 环境
  models = null // 模型库

  direct = null // 方向
  miles = 0 // 隧道长
  start = 0 // 起点桩号
  end = 0 // 终点桩号
  socket // 车流连接
  
  cars = [] // 路面车流
  points = [] // 隧道点阵
  curves = [] // 轨迹引导线
  // vector = [ // 车道偏转向量
  //   { x: -8.3, y: 0, z: -3.7 },
  //   { x: -11.5, y: 0, z: -5.5 }
  // ]

  flow = null // 车流模型

  constructor(context, models, configs: { [propName: string]: any }) {

    // const car_m = models.camera.scene.clone()
    // context.scene.add(car_m)
    // car_m.position.x = 10
    // car_m.rotation.y = (Math.PI / 180) * 90
    
    const avls = ['direct', 'miles', 'points', 'start', 'end']

    this.context = context
    this.models = models

    avls.forEach(key => {
      if (configs[key] || configs[key] === 0) {
        this[key] = configs[key]
      }
    })

    this.flow = new FlowModel({
      direct: this.direct,
      mode: 'online'
    })

    if (this.direct === 0) {
      this.curves = [
        this.createCurve(this.context.scene, LFT_1),
        this.createCurve(this.context.scene, LFT_2)
      ]
    } else {
      this.curves = [
        this.createCurve(this.context.scene, RGT_1),
        this.createCurve(this.context.scene, RGT_2)
      ]
    }

  }

  createCube (pt) {
    const geometry = new THREE.BoxGeometry(0.1, 0.1, 0.1)
    const material = new THREE.MeshBasicMaterial(0xffffff)
    const cube = new THREE.Mesh(geometry, material)
    cube.position.copy(pt)
    return cube
  }

  createCurve (scene, points) {

    const curve = new THREE.CatmullRomCurve3(points.map(item => {
      const { x, y, z } = item
      return new THREE.Vector3(x, y, z)
    }))


    curve.curveType = 'chordal'
    const geoPoints = curve.getPoints(2000)
    const line = new THREE.Line(
      new THREE.BufferGeometry().setFromPoints(geoPoints),
      new THREE.LineBasicMaterial({ color: 0x00ff00, opacity: 1, transparent: false })
    )
    
    scene.add(line)

    return curve


  }

  // 开启车流
  startFlows () {

    // 车流更新
    // this.flow.start(() => {
    //   this.flowUpdate()
    // })

    this.flow.mook(() => {
      this.flowUpdate()
    })

    // 场景更新
    amtMount((delay) => {
      this.cars.forEach(xcar => {
        xcar.run(delay)
      })
    })

  }

  // 数据帧更新
  flowUpdate () {

    const flowCars = this.flow.exportCars()

    // 首次
    if (this.cars.length === 0) {
      this.cars = flowCars.map(xcar => {
        return new CarModel(this.context, {
          model: this.models.car,
          scene: this.context.scene,
          direct: this.direct,
          curves: this.curves,
          miles: this.miles,
          infos: xcar
        })
      })
      return
    }

    // 更新
    const newMap = Object.fromEntries(flowCars.map(xcar => {
      return [xcar.id, xcar]
    }))

    // 跟丢删除
    this.cars = this.cars.filter(item => {
      if (newMap[item.infos.id]) {
        item.update(newMap[item.infos.id])
        return true
      } else {
        this.context.remove(item.car)
        return false
      }
    })

  }

}
