<script setup>
import { ref, onMounted, onUnmounted, nextTick, watch } from 'vue'
import { getDeviceList } from '@/api/device'
import { createFlvPlayer, destroyFlvPlayer } from '@/utils/videoPlayer'
import * as echarts from 'echarts'
import { generateChartData } from '@/api/chart'
import { ElNotification, ElMessage } from 'element-plus'
import {
  Monitor,
  Connection,
  Loading
} from '@element-plus/icons-vue'
import soundEffect from '@/utils/SoundEffect'

// 添加用户交互标记
let hasUserInteracted = false

// 监听用户交互
const handleUserInteraction = () => {
  hasUserInteracted = true
  // 移除事件监听器
  document.removeEventListener('click', handleUserInteraction)
  document.removeEventListener('keydown', handleUserInteraction)
}

// 无人机数据
const drone = ref(null)
const loading = ref(false)
const videoRef = ref(null)
const flvPlayer = ref(null)
const chartRef = ref(null)
const videoLoading = ref(true)  // 添加视频加载状态
const isPlaying = ref(false)    // 添加视频播放状态标志
const isBuffering = ref(false)  // 添加缓冲状态标志
let chart = null
let ws = null

// 添加 WebSocket 状态管理
const wsConnected = ref(false)
let wsRetryCount = 0
const MAX_RETRY_COUNT = 3
let wsRetryTimer = null

// 存储键名常量
const CHART_DATA_STORAGE_KEY = 'wetland_ph_chart_data'
const CHART_DATA_TIMESTAMP_KEY = 'wetland_ph_chart_timestamp'
const CHART_DATA_EXPIRE_TIME = 24 * 60 * 60 * 1000 // 24小时过期

// 保存图表数据到本地存储
const saveChartDataToStorage = (data) => {
  try {
    localStorage.setItem(CHART_DATA_STORAGE_KEY, JSON.stringify(data))
    localStorage.setItem(CHART_DATA_TIMESTAMP_KEY, Date.now().toString())
  } catch (error) {
    console.error('保存图表数据到本地存储失败:', error)
  }
}

// 从本地存储获取图表数据
const getChartDataFromStorage = () => {
  try {
    const timestamp = localStorage.getItem(CHART_DATA_TIMESTAMP_KEY)
    if (!timestamp) return null

    // 检查数据是否过期
    if (Date.now() - parseInt(timestamp) > CHART_DATA_EXPIRE_TIME) {
      localStorage.removeItem(CHART_DATA_STORAGE_KEY)
      localStorage.removeItem(CHART_DATA_TIMESTAMP_KEY)
      return null
    }

    const data = localStorage.getItem(CHART_DATA_STORAGE_KEY)
    return data ? JSON.parse(data) : null
  } catch (error) {
    console.error('从本地存储获取图表数据失败:', error)
    return null
  }
}

// 获取图表数据
const getChartData = async () => {
  try {
    const res = await generateChartData({
      message: "ph柱状图"
    })
    
    if (res.success) {
      console.log('完整的响应数据:', res);
      console.log('图表配置数据:', res.data?.echart_options);
      
      if (!res.data?.echart_options) {
        console.error('图表配置数据结构不完整');
        // 尝试使用本地存储的数据
        const storageData = getChartDataFromStorage()
        if (storageData) {
          console.log('使用本地存储的图表数据');
          initChart(storageData)
        } else {
          initChart(getDefaultChartData().echart_options)
        }
        return;
      }
      
      // 保存新数据到本地存储
      saveChartDataToStorage(res.data.echart_options)
      initChart(res.data.echart_options)
    } else {
      console.error('获取图表数据失败:', res.message)
      // 尝试使用本地存储的数据
      const storageData = getChartDataFromStorage()
      if (storageData) {
        console.log('使用本地存储的图表数据');
        initChart(storageData)
      } else {
        initChart(getDefaultChartData().echart_options)
      }
    }
  } catch (error) {
    console.error('获取图表数据失败:', error)
    // 尝试使用本地存储的数据
    const storageData = getChartDataFromStorage()
    if (storageData) {
      console.log('使用本地存储的图表数据');
      initChart(storageData)
    } else {
      initChart(getDefaultChartData().echart_options)
    }
  }
}

// 初始化图表
const initChart = (options) => {
  
  if (!chartRef.value) {
    console.error('图表DOM引用未找到');
    return;
  }

  try {
    if (chart) {
      chart.dispose()
    }

    chart = echarts.init(chartRef.value)

    // 检查必要的数据结构
    if (!options.xAxis?.data && !options.series?.[0]?.data) {
      console.error('数据结构不正确，使用默认配置');
      options = getDefaultChartData().echart_options;
    }

    // 确保 yAxis 配置正确
    const yAxisConfig = Array.isArray(options.yAxis) ? options.yAxis[0] : options.yAxis;

    const option = {
      backgroundColor: 'transparent',
      title: {
        ...(options.title || { text: 'pH值变化趋势' }),
        textStyle: {
          color: '#fff'
        }
      },
      tooltip: options.tooltip || {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow'
        }
      },
      legend: {
        ...(options.legend || {}),
        textStyle: {
          color: '#fff'
        }
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true
      },
      xAxis: {
        type: 'category',
        data: options.xAxis?.data || [],
        axisLine: {
          lineStyle: {
            color: 'rgba(255, 255, 255, 0.3)'
          }
        },
        axisLabel: {
          color: 'rgba(255, 255, 255, 0.7)'
        }
      },
      yAxis: {
        type: 'value',
        name: 'pH值',
        max: 8,
        ...(yAxisConfig || {}),
        axisLine: {
          lineStyle: {
            color: 'rgba(255, 255, 255, 0.3)'
          }
        },
        axisLabel: {
          color: 'rgba(255, 255, 255, 0.7)'
        },
        splitLine: {
          lineStyle: {
            color: 'rgba(255, 255, 255, 0.1)'
          }
        }
      },
      series: Array.isArray(options.series) ? options.series.map(series => ({
        ...series,
        yAxisIndex: 0, // 确保所有系列都使用同一个 yAxis
        areaStyle: series.areaStyle || {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: 'rgba(64, 158, 255, 0.7)' },
            { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
          ])
        }
      })) : [
        {
          name: 'pH值',
          type: 'line',
          smooth: true,
          yAxisIndex: 0,
          data: [],
          areaStyle: {
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(64, 158, 255, 0.7)' },
              { offset: 1, color: 'rgba(64, 158, 255, 0.1)' }
            ])
          }
        }
      ]
    }
    
    // 设置配置前确保数据结构完整
    if (!option.yAxis || !option.xAxis || !option.series) {
      throw new Error('图表配置数据结构不完整');
    }

    chart.setOption(option)
    
    // 确保图表正确渲染
    nextTick(() => {
      if (chart) {
        chart.resize()
      }
    })
  } catch (error) {
    console.error('图表初始化失败:', error);
    // 尝试使用完全默认的配置重新初始化
    try {
      if (chart) {
        const defaultOption = getDefaultChartData().echart_options;
        chart.setOption(defaultOption);
      }
    } catch (retryError) {
      console.error('使用默认配置重试失败:', retryError);
    }
  }
}

// 修改默认图表数据的结构
const getDefaultChartData = () => {
  return {
    echart_options: {
      title: {
        text: "pH值变化趋势"
      },
      tooltip: {
        trigger: "axis",
        axisPointer: {
          type: "shadow"
        }
      },
      legend: {
        data: ["pH值"]
      },
      xAxis: {
        type: "category",
        data: []
      },
      yAxis: {
        type: "value",
        name: "pH值",
        max: 8
      },
      series: [
        {
          name: "pH值",
          type: "line",
          smooth: true,
          yAxisIndex: 0,
          areaStyle: {},
          data: []
        }
      ]
    }
  }
}

// 显示设备状态通知
const showDeviceStatusNotification = (status) => {
  // 播放对应音效
  soundEffect.playStatusSound(status === 'online')

  ElNotification({
    title: status === 'online' ? '设备已接入' : '设备已接出',
    message: status === 'online' ?
      `设备 ${drone.value?.name || '无人机'} 已接入，正在获取视频流...` :
      `设备 ${drone.value?.name || '无人机'} 已接出，切换为数据图表显示`,
    type: status === 'online' ? 'success' : 'warning',
    duration: 3000
  })
}

// 修改 WebSocket 初始化和重连逻辑
const initWebSocket = () => {
  if (wsRetryCount >= MAX_RETRY_COUNT) {
    console.warn('WebSocket重试次数超过限制，切换到HTTP轮询模式')
    startPolling()
    return
  }

  try {
    if (ws) {
      ws.close()
      ws = null
    }

    // 修改为本地地址
    ws = new WebSocket('ws://127.0.0.1:6894')

    ws.onopen = () => {
      wsConnected.value = true
      wsRetryCount = 0 // 重置重试次数
      if (wsRetryTimer) {
        clearTimeout(wsRetryTimer)
        wsRetryTimer = null
      }

      // WebSocket连接成功后立即查询设备状态
      if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify({
          type: 'query_status',
          device_code: 'BC13292E5A49914F4D62B9F356E39F56'
        }))
      }
    }

    ws.onmessage = (event) => {
      try {
        const data = JSON.parse(event.data)
        if (data.type === 'device_status') {
          const newStatus = data.status === 1 ? 'online' : 'offline'
          const oldStatus = drone.value?.status

          // 只在状态真实发生变化时更新
          if (!drone.value || oldStatus !== newStatus) {
            // 立即更新设备状态
            if (!drone.value) {
              drone.value = {
                id: data.device_id,
                name: data.device_name || '无人机',
                code: data.device_code,
                status: newStatus,
                battery: data.battery_level || 0,
                signal: data.signal_strength || 0
              }
            } else {
              drone.value.status = newStatus
            }

            // 显示状态变化通知
            showDeviceStatusNotification(newStatus)

            // 根据新状态初始化视频或图表
            nextTick(async () => {
              if (newStatus === 'online') {
                if (chart) {
                  chart.dispose()
                  chart = null
                }
                await initVideoPlayer()
              } else {
                if (flvPlayer.value) {
                  destroyFlvPlayer(flvPlayer.value)
                  flvPlayer.value = null
                }
                getChartData()
              }
            })
          }
        }
      } catch (error) {
        console.error('WebSocket消息处理错误:', error)
      }
    }

    ws.onerror = (error) => {
      console.error('WebSocket错误:', error)
      wsConnected.value = false
      wsRetryCount++

      // 如果重试次数超过限制，切换到HTTP轮询
      if (wsRetryCount >= MAX_RETRY_COUNT) {
        console.warn('WebSocket连接失败，切换到HTTP轮询模式')
        startPolling()
      } else {
        // 否则尝试重连
        wsRetryTimer = setTimeout(() => {
        
          console.log(`尝试WebSocket重连 (${wsRetryCount}/${MAX_RETRY_COUNT})...`)
          initWebSocket()
        }, 5000 * Math.min(wsRetryCount, 3)) // 重试间隔随次数增加但最多15秒
      }
    }

    ws.onclose = () => {
      console.log('WebSocket连接关闭')
      wsConnected.value = false

      // 只有在非主动关闭的情况下才重连
      if (!ws._closeInitiated) {
        wsRetryTimer = setTimeout(() => {
          initWebSocket()
        }, 5000)
      }
    }
  } catch (error) {
    console.error('WebSocket初始化失败:', error)
    startPolling()
  }
}

// 添加HTTP轮询模式
let pollingTimer = null
const startPolling = () => {
  // 清理已有的定时器
  if (pollingTimer) {
    clearInterval(pollingTimer)
  }

  // 立即执行一次
  getDroneInfo()

  // 设置轮询间隔
  pollingTimer = setInterval(() => {
    getDroneInfo()
  }, 10000) // 10秒轮询一次
}

// 修改获取设备信息的逻辑
const getDroneInfo = async () => {
  if (loading.value) return
  loading.value = true

  try {
    const res = await getDeviceList({
      page: 1,
      page_size: 10,
      device_type: '10001'
    })

    if (res.code === 200) {
      const targetDrone = res.data.list.find(item =>
        item.device_code === 'BC13292E5A49914F4D62B9F356E39F56'
      )

      if (targetDrone) {
        // 设备状态判断逻辑
        const deviceStatus = targetDrone.status?.code || targetDrone.status
        const deviceOnline = deviceStatus === 1
        const newStatus = deviceOnline ? 'online' : 'offline'

        // 检查状态是否发生变化
        const oldStatus = drone.value?.status
        if (oldStatus && oldStatus !== newStatus) {
          showDeviceStatusNotification(newStatus)
        }

        // 只有在状态发生变化或首次加载时才更新数据
        if (!drone.value || oldStatus !== newStatus) {
          drone.value = {
            id: targetDrone.id,
            name: targetDrone.device_name,
            code: targetDrone.device_code,
            status: newStatus,
            battery: targetDrone.battery_level || 0,
            signal: targetDrone.signal_strength || 0
          }
        }
      } else {
        if (drone.value !== null) {
          drone.value = null
          getChartData()
        }
      }
    }
  } catch (error) {
    console.error('获取设备信息失败:', error)
    if (!drone.value) {
      getChartData()
    }
  } finally {
    loading.value = false
  }
}

// 初始化视频播放器
const initVideoPlayer = async () => {
  videoLoading.value = true  // 开始加载时显示loading
  isPlaying.value = false    // 重置播放状态
  isBuffering.value = false  // 重置缓冲状态

  try {
    // 销毁之前的播放器
    if (flvPlayer.value) {
      destroyFlvPlayer(flvPlayer.value)
      flvPlayer.value = null
    }

    // 等待 DOM 更新
    await nextTick()

    // 初始化新的播放器
    if (videoRef.value && drone.value?.status === 'online') {
      // 重置视频元素
      const videoElement = videoRef.value
      videoElement.pause()
      videoElement.currentTime = 0
      videoElement.muted = true

      // 移除旧的事件监听器
      const oldListeners = videoElement._eventListeners || []
      oldListeners.forEach(({ event, handler }) => {
        videoElement.removeEventListener(event, handler)
      })
      videoElement._eventListeners = []

      // 创建新的播放器
      flvPlayer.value = createFlvPlayer(videoElement, drone.value.code)

      if (flvPlayer.value) {
        // 添加 flv.js 事件监听
        flvPlayer.value.on('loading', () => {
          if (!isPlaying.value) {
            videoLoading.value = true
            isBuffering.value = true
          }
        })

        flvPlayer.value.on('error', (errorType, errorDetail) => {
          console.error('视频播放错误:', errorType, errorDetail)
          ElMessage.error('视频加载失败，请检查网络连接')
          videoLoading.value = false
          isPlaying.value = false
          isBuffering.value = false
        })

        // 添加视频元素事件监听
        const addVideoListener = (event, handler) => {
          videoElement.addEventListener(event, handler)
          videoElement._eventListeners.push({ event, handler })
        }

        addVideoListener('loadstart', () => {
          videoLoading.value = true
          isBuffering.value = true
        })

        addVideoListener('waiting', () => {
          isBuffering.value = true
          if (!isPlaying.value) {
            videoLoading.value = true
          }
        })

        addVideoListener('playing', () => {
          videoLoading.value = false
          isPlaying.value = true
          isBuffering.value = false
        })

        addVideoListener('canplay', () => {
          isBuffering.value = false
          if (!isPlaying.value) {
            videoLoading.value = false
          }
        })

        addVideoListener('error', (e) => {
          console.error('视频元素错误:', e)
          videoLoading.value = false
          isPlaying.value = false
          isBuffering.value = false
          ElMessage.error('视频加载失败，请检查网络连接')
        })

        // 尝试播放视频
        try {
          await videoElement.play()
        } catch (error) {
          if (error.name === 'AbortError') {
            console.log('视频播放被中断，重试中...')
            // 短暂延迟后重试播放
            setTimeout(async () => {
              try {
                await videoElement.play()
              } catch (retryError) {
                console.error('视频重试播放失败:', retryError)
                ElMessage.error('视频播放失败，请刷新页面重试')
              }
            }, 100)
          } else {
            console.error('视频播放失败:', error)
            ElMessage.error('视频播放失败，请检查网络连接')
          }
        }
      } else {
        console.error('播放器创建失败')
        ElMessage.error('视频播放器初始化失败')
        videoLoading.value = false
        isPlaying.value = false
      }
    }
  } catch (error) {
    console.error('视频播放器初始化失败:', error)
    ElMessage.error('视频播放器初始化失败')
    videoLoading.value = false
    isPlaying.value = false
    isBuffering.value = false
  }
}

// 定时刷新设备状态和图表数据
let refreshTimer = null
const startRefreshTimer = () => {
  refreshTimer = setInterval(() => {
    // 只在WebSocket连接断开时才通过HTTP轮询获取状态
    if (ws?.readyState !== WebSocket.OPEN) {
      getDroneInfo()
    }

    // 只在设备离线时才刷新图表数据
    if (drone.value?.status !== 'online') {
      getChartData()
    }
  }, 60000) // 改为每60秒刷新一次
}

// 处理窗口大小变化
const handleResize = () => {
  chart?.resize()
}

// 监听设备状态变化
watch(() => drone.value?.status, (newStatus, oldStatus) => {
  // 设备状态变化
  if (newStatus !== oldStatus) {
    // 显示状态变化通知
    if (oldStatus) {  // 只在状态真实变化时显示通知
      showDeviceStatusNotification(newStatus)
    }

    // 根据新状态处理视频或图表
    nextTick(async () => {
      if (newStatus === 'online') {
        // 设备上线，销毁图表并初始化视频播放器
        if (chart) {
          chart.dispose()
          chart = null
        }
        await initVideoPlayer()
      } else {
        // 设备离线，销毁视频播放器并初始化图表
        if (flvPlayer.value) {
          destroyFlvPlayer(flvPlayer.value)
          flvPlayer.value = null
        }
        getChartData()
      }
    })
  }
}, { immediate: true })

onMounted(() => {
  // 添加用户交互监听
  document.addEventListener('click', handleUserInteraction)
  document.addEventListener('keydown', handleUserInteraction)

  // 初始化时先尝试使用本地存储的数据
  const storageData = getChartDataFromStorage()
  if (storageData) {
    console.log('使用本地存储的图表数据初始化');
    initChart(storageData)
  }

  // 初始化WebSocket连接
  initWebSocket()
  // 获取无人机信息
  getDroneInfo()
  // 启动定时刷新
  startRefreshTimer()
  // 监听窗口大小变化
  window.addEventListener('resize', handleResize)
})

onUnmounted(() => {
  // 移除用户交互监听
  document.removeEventListener('click', handleUserInteraction)
  document.removeEventListener('keydown', handleUserInteraction)

  // 标记WebSocket为主动关闭
  if (ws) {
    ws._closeInitiated = true
    ws.close()
    ws = null
  }

  // 清理所有定时器
  if (wsRetryTimer) {
    clearTimeout(wsRetryTimer)
  }
  if (pollingTimer) {
    clearInterval(pollingTimer)
  }
  if (refreshTimer) {
    clearInterval(refreshTimer)
  }

  // 清理播放器和图表
  if (flvPlayer.value) {
    destroyFlvPlayer(flvPlayer.value)
  }
  if (chart) {
    chart.dispose()
    chart = null
  }

  wsConnected.value = false
  window.removeEventListener('resize', handleResize)
})
</script>

<template>
  <div class="video-monitor">
    <div class="monitor-header">
      <div class="title">{{ drone?.status === 'online' ? '无人机实时监控' : '历史数据监测' }}</div>
      <div class="status" v-if="drone">
        <el-tag :type="drone?.status === 'online' ? 'success' : 'danger'" size="small">
          {{ drone?.status === 'online' ? '在线' : '离线' }}
        </el-tag>
      </div>
    </div>

    <div class="content-container">
      <template v-if="drone?.status === 'online'">
        <!-- 在线显示视频 -->
        <div class="video-wrapper">
          <video
            ref="videoRef"
            class="video-player"
            muted
          ></video>
          <div v-if="videoLoading && !isPlaying" class="video-loading">
            <el-icon class="loading-icon"><Loading /></el-icon>
            <span class="loading-text">视频加载中...</span>
          </div>
          <div class="video-info">
            <div class="info-row">
              <span class="device-name">{{ drone.name }}</span>
              <div class="device-metrics">
                <el-tooltip content="电池电量" placement="top">
                  <div class="metric">
                    <el-icon><Monitor /></el-icon>
                    {{ drone.battery }}%
                  </div>
                </el-tooltip>
                <el-tooltip content="信号强度" placement="top">
                  <div class="metric" :class="{ 'poor-signal': isBuffering }">
                    <el-icon><Connection /></el-icon>
                    {{ isBuffering ? '-110dBm' : '-88dBm' }}
                  </div>
                </el-tooltip>
              </div>
            </div>
          </div>
        </div>
      </template>
      <template v-else>
        <!-- 离线显示图表 -->
        <div ref="chartRef" class="chart-wrapper"></div>
      </template>
    </div>
  </div>
</template>

<style lang="scss" scoped>
.video-monitor {
  height: 100%;
  padding: 20px;
  background: rgba(0, 0, 0, 0.2);
  border-radius: 8px;
  display: flex;
  flex-direction: column;

  .monitor-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;

    .title {
      font-size: 20px;
      font-weight: 500;
      color: #fff;
      display: flex;
      align-items: center;
      gap: 8px;
    }
  }

  .content-container {
    flex: 1;
    position: relative;
    border-radius: 8px;
    overflow: hidden;
    background: rgba(0, 0, 0, 0.4);

    .video-wrapper {
      width: 100%;
      height: 100%;
      position: relative;

      .video-player {
        width: 100%;
        height: 100%;
        object-fit: cover;
      }

      // 添加 loading 样式
      .video-loading {
        position: absolute;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        background: rgba(0, 0, 0, 0.7);
        display: flex;
        flex-direction: column;
        justify-content: center;
        align-items: center;
        gap: 16px;
        z-index: 2;

        .loading-icon {
          font-size: 32px;
          color: #fff;
          animation: rotate 1s linear infinite;
        }

        .loading-text {
          color: #fff;
          font-size: 14px;
        }
      }

      .video-info {
        position: absolute;
        bottom: 0;
        left: 0;
        right: 0;
        padding: 20px;
        background: linear-gradient(transparent, rgba(0, 0, 0, 0.8));

        .info-row {
          display: flex;
          justify-content: space-between;
          align-items: center;

          .device-name {
            font-size: 16px;
            font-weight: 500;
            color: #fff;
          }

          .device-metrics {
            display: flex;
            gap: 20px;

            .metric {
              display: flex;
              align-items: center;
              gap: 4px;
              color: #fff;
              font-size: 14px;
              transition: all 0.3s ease;

              &.poor-signal {
                color: #F56C6C;
                animation: blink 1s infinite;
              }

              .el-icon {
                font-size: 16px;
              }
            }
          }
        }
      }
    }

    .chart-wrapper {
      width: 100%;
      height: 100%;
      background: rgba(0, 24, 65, 0.3);
      border-radius: 8px;
      padding: 20px;
      box-sizing: border-box;
      border: 1px solid rgba(63, 167, 221, 0.2);
    }
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

@keyframes blink {
  0% { opacity: 0.6; }
  50% { opacity: 1; }
  100% { opacity: 0.6; }
}
</style>