<template>
  <div class="w-100 batteryBar">
    <!-- 进度条显示剩余电量 -->
    <el-progress class="z90" :percentage="batteryRemaining" :show-text="false" :stroke-width="3"
      :color="statusColor"></el-progress>

    <!-- Tooltip 组件，用于显示电量或续航时间 -->
    <tooltip v-if="showTooltip" class="z90" :horizontalPosition="`${batteryRemaining}%`" :backgroundColor="statusColor">
      <template v-if="showBattery">
        <!-- {{ batteryRemainingPower }} mAh -->
        {{ batteryRemaining}}%
      </template>
      <template v-else>
        {{ endurance }} 分钟
      </template>
    </tooltip>

    <!-- 当返航剩余电量大于 5 时，显示返航提示 -->
    <tooltip v-if="rtlRemaining > 0" class="z90" :horizontalPosition="`${rtlRemaining}%`" backgroundColor="#ff3333">
      返
    </tooltip>
  </div>
</template>

<script>
import Tooltip from '@/components/Tooltip'
import geodist from 'geodist'

export default {
  name: 'BatteryStatus',
  data () {
    return {
      batteryValues: [], // 存储最近的 7 个电量值
      filteredBattery: 0, // 滤波后的电量值
      showBattery: true, // 用于控制显示电量或续航时间
      interval: null // 用于存储定时器 ID
    }
  },
  computed: {
    batteryValue () {
      if (this.plane && this.plane.planeState && this.plane.planeState.currentBattery) {
        return this.plane.planeState.currentBattery
      }
      return 0
    },
    statusColor () {
      // 获取剩余电量百分比和返航电量百分比
      const remaining = this.batteryRemaining
      const rtl = this.rtlRemaining
      // 计算剩余电量与返航电量的差值
      const percentage = remaining - rtl
      // 将百分比值限制在 0 到 100 范围内
      const normalizedPercentage = Math.max(0, Math.min(100, percentage))
      // 定义起始和结束的色相值 (0 - 360)
      const startHue = 200 // 代表 #00C8C8
      const endHue = 0 // 代表 #FF0000
      // 根据百分比计算色相
      const hue = Math.round(startHue + (endHue - startHue) * (100 - normalizedPercentage) / 100)
      // 设置饱和度和亮度（可以根据需要调整）
      const saturation = 90 // 饱和度保持不变
      const lightness = 50 // 亮度保持不变
      // 返回 HSL 颜色值
      return `hsl(${hue}, ${saturation}%, ${lightness}%)`
    },
    // 电池剩余电量值 (mAh)
    batteryRemainingPower () {
      if (this.plane && this.plane.planeState) {
        const battCapacity = this.plane.planeState.battCapacity
        const batteryRemaining = this.plane.planeState.batteryRemaining
        if (battCapacity !== undefined && batteryRemaining !== undefined) {
          return (battCapacity / 100) * batteryRemaining
        }
      }
      return 0
    },
    // 剩余飞行时间 (分钟)
    endurance () {
      if (this.filteredBattery > 2) {
        return Math.floor(this.batteryRemainingPower / 1000 / this.filteredBattery * 60)
      }
      return 0
    },
    // 控制 Tooltip 显示的条件
    showTooltip () {
      return Number(this.batteryRemainingPower) > 0 || Number(this.endurance) > 0
    },
    // 剩余电量 (百分比)
    batteryRemaining () {
      if (this.plane && this.plane.planeState && this.plane.planeState.batteryRemaining !== undefined) {
        const remaining = this.plane.planeState.batteryRemaining
        if (remaining < 0) {
          return 0
        } else if (remaining > 100) {
          return 100
        } else {
          return Number(remaining)
        }
      }
      return 0
    },
    // 返航所需电量 (百分比)
    rtlRemaining () {
      let rtlTime = 0 // 返航所需时间（秒）
      if (this.planePosition && this.homePosition && this.wpnavSpeed) {
        const planeLonLat = { lat: this.planePosition[1], lon: this.planePosition[0] }
        const homeLonLat = { lat: this.homePosition.lat, lon: this.homePosition.lon }
        const horizontalDistance = geodist(planeLonLat, homeLonLat, { unit: 'meters' }) // 水平距离
        const verticalDistance = Math.abs(this.planePosition[2] - this.homePosition.alt) // 垂直距离
        const rtlDistance = horizontalDistance + verticalDistance // 返航总距离 水平+高度
        rtlTime = Math.floor(Number(rtlDistance) / Number(this.wpnavSpeed)) // 返航需要时间 单位：秒
      }
      if (rtlTime <= 0) {
        return 0
      }
      const currentBattery = this.filteredBattery // 滤波之后 电流 (安培)
      const batteryCapacity = this.plane.planeState.battCapacity // 电池总容量 (mAh)
      // 计算返航所需电量（mAh），假设电流与电量是线性关系
      const rtlPowerRequired = rtlTime * currentBattery / 3.6 // 返航所需电量 (mAh)
      // 计算返航所需电量占总电量的百分比
      const rtlPowerPercentage = (rtlPowerRequired / batteryCapacity) * 100
      // 将百分比限制在 0 到 100 范围内
      return Math.max(0, Math.min(100, rtlPowerPercentage))
    },
    // 返航点
    homePosition () {
      if (this.plane && this.plane.planeState) {
        return this.plane.planeState.homePosition
      }
      return null
    },
    // 飞机当前位置
    planePosition () {
      if (this.plane && this.plane.planeState) {
        return this.plane.planeState.position[0]
      }
      return null
    },
    // 飞机返航速度
    wpnavSpeed () {
      if (this.plane && this.plane.planeState) {
        return this.plane.planeState.wpnavSpeed
      }
      return null
    }
  },
  props: {
    plane: {
      type: Object,
      deep: true
    }
  },
  components: {
    Tooltip
  },
  methods: {
    /**
     * 剩余电量与剩余续航时间轮播
     */
    startInterval () {
      this.interval = setInterval(() => {
        this.showBattery = !this.showBattery
      }, 3000)
    },
    clearInterval () {
      if (this.interval) {
        clearInterval(this.interval)
        this.interval = null
      }
    },
    checkDisplayConditions () {
      this.clearInterval()
      // 如果存在剩余电量和剩余续航时间，则启动轮播
      if (this.batteryRemainingPower > 0 && this.endurance > 0) {
        this.startInterval()
      }
    }
  },
  watch: {
    // 电量更新时 进行滤波
    batteryValue (val) {
      // 添加新值到数组
      this.batteryValues.push(Number(val))
      // 数组长度超出 7，删除最早的元素，保证数组不超过 7 元素
      if (this.batteryValues.length > 7) {
        this.batteryValues.shift()
      }
      // 如果数组长度超过 3，执行滤波计算
      if (this.batteryValues.length >= 3) {
        // 复制并排序数组
        const sortedValues = [...this.batteryValues].sort((a, b) => a - b)
        // 去掉最高值和最低值
        sortedValues.pop()
        sortedValues.shift()
        // 计算平均值
        const average = sortedValues.reduce((acc, val) => acc + val, 0) / sortedValues.length
        this.filteredBattery = average.toFixed(2)
      } else {
        this.filteredBattery = val
      }
    },
    batteryRemainingPower () {
      this.checkDisplayConditions()
    },
    endurance (val) {
      this.checkDisplayConditions()
      if (val === 0) {
        this.showBattery = true
      }
    }
  },
  mounted () {
    // 在组件挂载时检查显示条件
    this.checkDisplayConditions()
  },
  destroyed () {
    // 在组件销毁前清除定时器
    this.clearInterval()
  }
}
</script>

<style lang="scss" scoped>
@import "@/styles/theme.scss";

.batteryBar {
  position: absolute;
}
</style>
