<template>
  <div class="left-data-box1">
    <LDBTitleBox title="主轴负载曲线" align="left" />
    <div class="axis-controls">
      <el-button v-for="button in axisButtons" :key="button.name" size="small" @click="toggleAxis(button.name)"
        :class="['axis-button', button.active ? 'axis-button-active' : 'axis-button-inactive']">
        {{ button.name }}
      </el-button>
    </div>
    <div class="ldb1-chart-box">
      <!-- <div v-show="loading" class="chart-loading">加载中...</div> -->
      <div v-show="error != ''" class="chart-error">{{ error }}</div>
      <div id="ldb1-chart" class="ldb1-chart" v-show="!loading && error == ''"></div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, onUnmounted, watch, nextTick } from 'vue'
import * as echarts from 'echarts'
import { CreateData, ExecDatabase, type ParameterTuple } from '../../utils/webApiCall'

// 响应式数据
const chartData = ref({
  X: [] as number[],
  Y: [] as number[],
  Z: [] as number[],
})
const timeData = ref<string[]>([])
const loading = ref(false)
const error = ref('')
const chartInitialized = ref(false)
const timer = ref<NodeJS.Timeout | null>(null)
const latestCreateTime = ref<string>('') // 记录数据库中最新的创建时间

const axisButtons = ref([
  { name: 'X', active: true },
  { name: 'Y', active: true },
  { name: 'Z', active: true },
])

let chartInstance: echarts.ECharts | null = null

// 辅助函数：格式化日期时间
const formatDateTime = (date: Date): string => {
  const pad = (n: number) => n.toString().padStart(2, '0')
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} ${pad(
    date.getHours()
  )}:${pad(date.getMinutes())}:${pad(date.getSeconds())}`
}

// 获取数据库中最新的创建时间
const getLatestCreateTime = async (deviceCode: string): Promise<string | null> => {
  try {
    const param: ParameterTuple[] = [
      ['TableName', '历史_设备数据_定时'],
      ['PageNumber', 1],
      ['PageSize', 100],
      ['FieldsToSelect', '创建时间'],
      ['WhereConditions', `工位号 = '${deviceCode}'`],
      ['SortField', '创建时间'],
      ['SortDirection', 'desc'],
      ['GroupByFields', ''],
    ]

    const requestData = CreateData('11', param)
    const response = await ExecDatabase(requestData)

    if (response && response.data && Array.isArray(response.data) && response.data.length > 0) {
      const latestRecord = response.data[0]
      const createTime = latestRecord.创建时间 || latestRecord.CreateTime
      if (createTime) {
        return createTime
      }
    }
    return null
  } catch (err) {
    console.error('获取最新创建时间失败:', err)
    return null
  }
}

// 计算时间范围（最新时间前两分钟）
const calculateTimeRange = (latestTime: string) => {
  const latestDate = new Date(latestTime)
  const startDate = new Date(latestDate.getTime() - 2 * 60 * 1000) // 前两分钟

  const formatDate = (date: Date) => date.toLocaleString('sv-SE').replace('T', ' ').slice(0, 19)

  return {
    startTime: formatDate(startDate),
    endTime: formatDate(latestDate),
  }
}

// 启动实时查询
const startRealtimeQuery = () => {
  stopRealtimeQuery()
  const interval = window.dt_Config?.ServoLoadCurveRefreshInterval
  console.log('曲线定时刷新间隔:', interval)
  // 立即执行第一次查询
  loadChartData(true)

  // 然后每5秒查询一次
  timer.value = setInterval(() => {
    loadChartData(false)
  }, interval)
}

// 停止实时查询
const stopRealtimeQuery = () => {
  if (timer.value) {
    clearInterval(timer.value)
    timer.value = null
  }
}

// 加载伺服负载数据
const loadChartData = async (isFirstLoad: boolean = true): Promise<void> => {
  if (!isFirstLoad && loading.value) {
    return
  }

  try {
    loading.value = true
    error.value = ''

    // 获取设备编码
    const deviceCode = window.dt_Config?.mqttTopic?.replace('SCADAMain/', '') || 'Device001'

    let whereConditions = `工位号 = '${deviceCode}'`

    // 获取最新时间
    const latestTime = await getLatestCreateTime(deviceCode)

    if (!latestTime) {
      // 如果获取不到最新时间，显示无数据状态
      error.value = '暂无数据'
      chartData.value = { X: [], Y: [], Z: [] }
      timeData.value = []
      return
    }

    // 计算时间范围
    const timeRange = calculateTimeRange(latestTime)
    whereConditions += ` AND 创建时间 >= '${timeRange.startTime}' AND 创建时间 <= '${timeRange.endTime}'`

    // console.log(`查询时间范围: ${timeRange.startTime} 到 ${timeRange.endTime}`)

    const param: ParameterTuple[] = [
      ['TableName', '历史_设备数据_定时'],
      ['PageNumber', 1],
      ['PageSize', 1000],
      ['FieldsToSelect', 'AID, 在线状态, 创建时间, 设备代码, 工位号, 变量名称, 值'],
      ['WhereConditions', whereConditions],
      ['SortField', '创建时间'],
      ['SortDirection', 'asc'],
      ['GroupByFields', ''],
    ]

    const requestData = CreateData('11', param)
    const response = await ExecDatabase(requestData)

    if (response && response.data && Array.isArray(response.data)) {
      if (response.data.length > 0 && !response.data[0].hasOwnProperty('result')) {
        // 成功获取数据
        processRealtimeData(response.data, isFirstLoad)
        error.value = ''
      } else {
        // 查询失败，清空数据
        error.value = '查询失败'
        chartData.value = { X: [], Y: [], Z: [] }
        timeData.value = []
      }
    } else {
      // 无数据
      error.value = '暂无数据'
      chartData.value = { X: [], Y: [], Z: [] }
      timeData.value = []
    }
  } catch (err: any) {
    console.error('加载数据失败:', err)
    error.value = `数据加载失败: ${err.message}`
    chartData.value = { X: [], Y: [], Z: [] }
    timeData.value = []
  } finally {
    loading.value = false
  }
}

// 处理实时数据
const processRealtimeData = (data: any[], isFirstLoad: boolean) => {
  if (data.length === 0) {
    // 没有数据时清空图表
    chartData.value = { X: [], Y: [], Z: [] }
    timeData.value = []
    error.value = '暂无数据'
    return
  }

  const xMap = new Map<string, number>()
  const yMap = new Map<string, number>()
  const zMap = new Map<string, number>()
  const timeSet = new Set<string>()

  // 处理数据
  data.forEach((item) => {
    const variableName = item.变量名称 || item.variableName || item.VariableName
    const value = parseFloat(item.值 || item.value || item.Value || '0')
    const time = item.创建时间 || item.recordTime || item.RecordTime || item.CreateTime

    if (!isNaN(value) && time) {
      timeSet.add(time)

      if (variableName && typeof variableName === 'string') {
        if (variableName.includes('X') || variableName.includes('x')) {
          xMap.set(time, value)
        } else if (variableName.includes('Y') || variableName.includes('y')) {
          yMap.set(time, value)
        } else if (variableName.includes('Z') || variableName.includes('z')) {
          zMap.set(time, value)
        }
      }
    }
  })

  // 排序时间
  const sortedTimes = Array.from(timeSet).sort(
    (a, b) => new Date(a).getTime() - new Date(b).getTime()
  )
  const xValues: number[] = []
  const yValues: number[] = []
  const zValues: number[] = []

  sortedTimes.forEach((time) => {
    xValues.push(xMap.get(time) || 0)
    yValues.push(yMap.get(time) || 0)
    zValues.push(zMap.get(time) || 0)
  })

  chartData.value = { X: xValues, Y: yValues, Z: zValues }
  timeData.value = sortedTimes
  error.value = ''
}

// 图表初始化
const initChart = async () => {
  await nextTick()

  const chartDom = document.getElementById('ldb1-chart')
  if (!chartDom) {
    return
  }

  if (chartDom.offsetWidth === 0 || chartDom.offsetHeight === 0) {
    setTimeout(initChart, 100)
    return
  }

  try {
    const existingInstance = echarts.getInstanceByDom(chartDom)
    if (existingInstance) {
      existingInstance.dispose()
    }

    chartInstance = echarts.init(chartDom)
    chartInitialized.value = true

    // 设置基础配置
    const baseOption = getChartOption()
    chartInstance.setOption(baseOption)

    window.addEventListener('resize', handleResize)
  } catch (err) {
    console.error('ECharts初始化失败:', err)
  }
}

const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

// 平滑更新图表
const updateChart = () => {
  if (!chartInstance || !chartInitialized.value) {
    return
  }

  try {
    const option = getChartOption()
    // 使用 replaceMerge 强制替换所有配置，确保图表完全更新
    chartInstance.setOption(option, {
      notMerge: true, // 不合并，完全替换
      lazyUpdate: false, // 立即更新
      silent: false // 显示更新动画
    })

    // 重新调整大小
    chartInstance.resize()
  } catch (err) {
    console.error('更新图表失败:', err)
  }
}

// 无数据状态显示
const showNoDataState = () => {
  if (!chartInstance) return

  const noDataOption = {
    title: {
      text: '暂无伺服负载数据',
      textStyle: {
        color: '#fff',
        fontSize: 16,
        fontWeight: 'normal',
      },
      left: 'center',
      top: 'center',
    },
    xAxis: { show: false },
    yAxis: { show: false },
    series: [{ data: [] }],
  }
  chartInstance.setOption(noDataOption, true)
}

// 获取图表配置
const getChartOption = () => {
  // 只过滤出激活的按钮
  const activeSeries = axisButtons.value.filter((button) => button.active)

  // 如果没有激活的系列，显示空图表
  if (activeSeries.length === 0) {
    return {
      xAxis: { show: false },
      yAxis: { show: false },
      series: [],
      grid: { show: false }
    }
  }

  const series = activeSeries.map((button) => ({
    name: button.name,
    type: 'line' as const,
    data: chartData.value[button.name as keyof typeof chartData.value] || [],
    smooth: true,
    itemStyle: {
      color: getAxisColor(button.name),
    },
    lineStyle: {
      width: 2,
    },
    showSymbol: false, // 不显示数据点，提高性能
    animation: false, // 禁用动画，提高实时性
    emphasis: {
      focus: 'series',
    },
  }))

  return {
    backgroundColor: 'transparent',
    animation: false,
    grid: {
      left: '3%',
      right: '4%',
      bottom: '15%',
      top: '15%',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: timeData.value,
      axisLabel: {
        color: '#ffffff',
        fontSize: 10,
        rotate: 45,
        formatter: (value: string) => {
          try {
            const date = new Date(value)
            if (isNaN(date.getTime())) return value
            return `${date.getHours().toString().padStart(2, '0')}:${date
              .getMinutes()
              .toString()
              .padStart(2, '0')}:${date.getSeconds().toString().padStart(2, '0')}`
          } catch {
            return value
          }
        },
      },
      axisLine: {
        lineStyle: {
          color: '#ffffff',
        },
      },
      axisTick: {
        alignWithLabel: true,
      },
    },
    yAxis: {
      type: 'value',
      name: '负载值',
      nameTextStyle: {
        color: '#ffffff',
      },
      axisLabel: {
        color: '#ffffff',
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#ffffff',
        },
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(255, 255, 255, 0.1)',
        },
      },
    },
    series,
    legend: {
      data: activeSeries.map((btn) => btn.name),
      textStyle: {
        color: '#ffffff',
      },
      top: 0,
      right: 10,
      selectedMode: false,
    },
    tooltip: {
      trigger: 'axis',
      backgroundColor: 'rgba(0, 0, 0, 0.7)',
      textStyle: {
        color: '#ffffff',
        fontSize: 12,
      },
      formatter: (params: any) => {
        let result = params[0].axisValueLabel + '<br/>'
        params.forEach((param: any) => {
          result += `${param.seriesName}: ${param.value?.toFixed(2) || '0'}<br/>`
        })
        return result
      },
    },
  }
}

const getAxisColor = (axis: string) => {
  const colors: { [key: string]: string } = {
    X: '#E6A23C',
    Y: '#67C23A',
    Z: '#F56C6C',
  }
  return colors[axis] || '#E6A23C'
}

const toggleAxis = (axis: string) => {
  const button = axisButtons.value.find((btn) => btn.name === axis)
  if (button) {
    button.active = !button.active

    // 强制触发重新渲染
    axisButtons.value = [...axisButtons.value]

    // 更新图表
    nextTick(() => {
      updateChart()
    })
  }
}

// 监听数据变化，自动更新图表
watch(
  () => [chartData.value, timeData.value],
  () => {
    if (chartInitialized.value && timeData.value.length > 0) {
      updateChart()
    }
  },
  { deep: true }
)

onMounted(async () => {
  await nextTick()
  await initChart()
  startRealtimeQuery()
})

onUnmounted(() => {
  stopRealtimeQuery()
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  window.removeEventListener('resize', handleResize)
})

// 暴露方法用于外部调用
defineExpose({
  loadChartData,
  startRealtimeQuery,
  stopRealtimeQuery,
})
</script>

<style scoped>
/* 样式保持不变 */

.axis-controls {
  display: flex;
  justify-content: center;
  margin: 5px 0;
}

.axis-button {
  margin: 0 5px;
  padding: 3px 8px;
  font-size: 12px;
  border: 1px solid transparent;
  transition: all 0.3s ease;
}

.axis-button-active {
  background-color: rgba(56, 179, 241, 0.8);
  color: #fff;
  border-color: #38b3f1;
}

.axis-button-inactive {
  background-color: rgba(255, 255, 255, 0.1);
  color: #ccc;
  border-color: rgba(255, 255, 255, 0.2);
}

.axis-button:hover {
  background-color: rgba(56, 179, 241, 0.5);
  color: #fff;
}

.ldb1-chart-box {
  flex: 1;
  position: relative;
  width: 100%;
  height: calc(100% - 40px);
  min-height: 180px;
  overflow: hidden;
}

.ldb1-chart {
  width: 100% !important;
  height: 100% !important;
  min-height: 180px;
  display: block !important;
  position: relative !important;
}

.ldb1-chart canvas {
  display: block !important;
  width: 100% !important;
  height: 100% !important;
}

.chart-loading,
.chart-error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #fff;
  font-size: 14px;
}

.chart-error {
  color: #ff6b6b;
}
</style>
<script lang="ts">
export default {
  name: 'ServoLoadCurve',
}
</script>
