/**
 * 昼夜切换组件, 白天切换到晚上10点
 */
export default class DayNight extends THING.Component {
  constructor(options) {
    super()
    this.isSmooth = options.isSmooth || true
    this.intensity = options.intensity || 0.1
    this.lights = app.root.helper.lights
    this.prevBg = Symbol()
    this.map = new Map()
    this.timer = null
    this.bgTimer = null
    this.cacheInitData()
  }

  /**
   * @description 改变切换模式
   * @param {Boolean} bol 是否平滑切换
   */
  changeSmooth(bol) {
    this.isSmooth = bol
  }

  /**
   * @description 缓存初始化时的数据
   */
  cacheInitData() {
    this.lights.forEach((v) => {
      this.map.set(v, v.intensity)
    })
    this.map.set(this.prevBg, app.background)
  }

  /**
   * @description 切换到白天
   */
  day() {
    this.isSmooth ? this._smoothToDay() : this._switchToDay()
  }

  /**
   * @description 切换到黑夜
   */
  night() {
    this.isSmooth ? this._smoothToNight() : this._switchToNight()
  }

  /**
   * @description 平滑切换到白天
   */
  _smoothToDay() {
    this.lights.forEach((v) => {
      this._dayAndNight(v, this.map.get(v), true)
    })
    this._changebgLights(app.background, this.map.get(this.prevBg), true)
  }

  /**
   * @description 一键切换到白天
   */
  _switchToDay() {
    this.lights.forEach((v) => {
      v.intensity = this.map.get(v)
    })
    app.background = this.map.get(this.prevBg)
  }

  /**
   * @description 平滑切换到黑夜
   */
  _smoothToNight() {
    this.lights.forEach((v) => {
      this._dayAndNight(v, this.intensity)
    })
    this._changebgLights(app.background, Array(3).fill(this.intensity))
  }

  /**
   * @description 一键切换到黑夜
   */
  _switchToNight() {
    this.lights.forEach((v) => {
      v.intensity = this.intensity
    })
    app.background = Array(3).fill(this.intensity)
  }

  /**
   * @description app.background 平滑切换
   * @param {Array<Number>} current 当前app.background数值
   * @param {Array<Number>} target 目标app.background数值
   * @param {Boolean} toDay 是否切换到白天
   */
  _changebgLights(current, target, toDay) {
    if (!Array.isArray(current)) {
      return
    }
    const c = current.map((v) => Number(v.toFixed(2)))
    const t = target.map((v) => Number(v.toFixed(2)))
    if (c.toString() === t.toString()) {
      clearTimeout(this.bgTimer)
      this.bgTimer = null
      return
    }
    this.bgTimer = setTimeout(() => {
      app.background = c.map((v) => {
        return toDay
          ? Number((v + 0.02).toFixed(2))
          : Number((v - 0.02).toFixed(2))
      })

      this._changebgLights(app.background, t, toDay)
    }, 50)
  }

  /**
   * @description 白天/黑夜平滑切换方法(切换光照强度)
   * @param {Object} v app.root.helper.lights数组项，为光照相关对象
   * @param {Number} target 目标光照强度
   * @param {Boolean} toDay 是否切换到白天
   */
  _dayAndNight(v, target, toDay) {
    const c = Number(v.intensity.toFixed(2))
    const t = Number(target.toFixed(2))
    if (c === t) {
      clearTimeout(this.timer)
      this.timer = null
      return
    }
    this.timer = setTimeout(() => {
      v.intensity = toDay
        ? Number((c + 0.02).toFixed(2))
        : Number((c - 0.02).toFixed(2))
      this._dayAndNight(v, target, toDay)
    }, 50)
  }

  onDestroy() {
    this.timer && clearTimeout(this.timer)
    this.timer = null
    this.bgTimer && clearTimeout(this.bgTimer)
    this.bgTimer = null

    // 将亮度恢复到初始状态
    this.lights.forEach((v) => {
      v.intensity = this.map.get(v)
    })
  }
}
