<template>
  <div class="left-data-box3">
    <LDBTitleBox title="零部件智能预测性维护(h)" align="left" />
    <div class="ldb3-chart-box">
      <div v-show="error != ''" class="chart-error">{{ error }}</div>
      <div id="ldb3-chart" class="ldb3-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 componentData = ref({
  names: [] as string[],
  planned: [] as number[],
  used: [] as number[],
  remaining: [] as number[],
})

const loading = ref(false)
const error = ref('')
const chartInitialized = ref(false)

let chartInstance: echarts.ECharts | null = null

// ==================== 数据获取与处理 ====================
// 加载零部件维护数据
const loadComponentMaintenanceData = async (): Promise<void> => {
  try {
    loading.value = true
    error.value = ''

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

    // 构造查询参数
    const param: ParameterTuple[] = [
      ['TableName', '零部件智能预测性维护_基础表'],
      ['PageNumber', 1],
      ['PageSize', 20],
      ['FieldsToSelect', '*'],
      ['WhereConditions', `工位号 = '${deviceCode}'`],
      ['SortField', null],
      ['SortDirection', null],
      ['GroupByFields', null],
    ]

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

    if (response && response.data) {
      if (Array.isArray(response.data) && response.data.length > 0) {
        // 检查是否有存储过程错误
        if (response.data[0].hasOwnProperty('result')) {
          console.error('存储过程执行错误:', response.data[0].result)
          error.value = '数据查询失败'
          setDefaultData()
        } else {
          processComponentData(response.data)
        }
      } else {
        // 没有数据时使用默认数据
        console.warn('没有找到零部件维护数据，使用默认数据')
        setDefaultData()
      }
    } else {
      throw new Error('响应数据格式不正确')
    }
  } catch (err: any) {
    console.error('加载零部件维护数据失败:', err)
    error.value = `数据加载失败: ${err.message}`
    setDefaultData()
  } finally {
    loading.value = false
  }
}

// 处理零部件数据
const processComponentData = (data: any[]) => {
  const names: string[] = []
  const planned: number[] = []
  const used: number[] = []
  const remaining: number[] = []

  // 解析数据并填充数组
  data.forEach((item) => {
    if (
      item.名称 &&
      item.制定寿命 !== undefined &&
      item.使用次数 !== undefined
    ) {
      names.push(item.名称)
      planned.push(parseFloat(item.制定寿命) || 0)
      used.push(parseFloat(item.使用次数) || 0)

      // 计算剩余寿命：制定寿命 - 使用次数
      const plannedLife = parseFloat(item.制定寿命) || 0
      const usedLife = parseFloat(item.使用次数) || 0
      const remainingLife = Math.max(0, plannedLife - usedLife) // 确保不为负数
      remaining.push(remainingLife)
    }
  })

  // 如果数据为空，设置默认数据
  if (names.length === 0) {
    setDefaultData()
    return
  }

  componentData.value = {
    names,
    planned,
    used,
    remaining,
  }
}

// 设置默认数据（用于演示或数据为空时）
const setDefaultData = () => {
  componentData.value = {
    names: ['轴承', '齿轮', '电机', '传感器', '控制器'],
    planned: [1000, 800, 1200, 600, 900],
    used: [300, 500, 400, 200, 600],
    remaining: [700, 300, 800, 400, 300],
  }
}

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

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

  // 确保DOM元素已渲染
  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 = {
      backgroundColor: 'transparent',
      animation: false,
      xAxis: {
        type: 'category',
        data: [],
      },
      yAxis: {
        type: 'value',
      },
      series: [
        {
          type: 'bar',
          data: [],
        },
      ],
    }

    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
  }

  // 检查是否有数据
  if (!componentData.value.names || componentData.value.names.length === 0) {
    showNoDataState()
    return
  }

  const { names, planned, used, remaining } = componentData.value

  ensureCanvasExists()

  try {
    chartInstance.clear()

    setTimeout(() => {
      const option = getChartOption(names, planned, used, remaining)
      chartInstance.setOption(option, true)

      setTimeout(() => {
        chartInstance.resize()
      }, 50)
    }, 10)
  } catch (err) {
    recoverChart()
  }
}

// 确保canvas元素存在
const ensureCanvasExists = () => {
  const chartDom = document.getElementById('ldb3-chart')
  if (!chartDom) return

  const canvas = chartDom.querySelector('canvas')
  if (!canvas) {
    recoverChart()
  }
}

// 恢复图表状态
const recoverChart = async () => {
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  chartInitialized.value = false
  await initChart()

  setTimeout(() => {
    if (componentData.value.names.length > 0) {
      updateChart()
    }
  }, 200)
}

// 显示无数据状态
const showNoDataState = () => {
  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 = (
  names: string[],
  planned: number[],
  used: number[],
  remaining: number[]
) => {
  return {
    backgroundColor: 'transparent',
    animation: false,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      formatter: function (params: any) {
        let result = params[0].name + '<br/>'
        params.forEach((param: any) => {
          result += `${param.seriesName}: ${param.value}小时<br/>`
        })
        return result
      },
    },
    legend: {
      data: ['制定寿命', '已使用', '剩余寿命'],
      textStyle: {
        color: '#ffffff',
      },
      top: 10,
      right: 20,
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '15%',
      top: '60px',
      containLabel: true,
    },
    xAxis: {
      type: 'category',
      data: names,
      axisLabel: {
        color: '#ffffff',
        fontSize: 10,
        interval: 0,
        rotate: 0,
        formatter: function (value: string) {
          // 长文本换行处理
          if (value.length > 4) {
            return value.substring(0, 4) + '\n' + value.substring(4)
          }
          return value
        },
      },
      axisLine: {
        lineStyle: {
          color: '#ffffff',
        },
      },
      axisTick: {
        alignWithLabel: true,
      },
    },
    yAxis: {
      type: 'value',
      name: '小时(h)',
      nameTextStyle: {
        color: '#ffffff',
      },
      axisLabel: {
        color: '#ffffff',
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#ffffff',
        },
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(255, 255, 255, 0.1)',
        },
      },
    },
    series: [
      {
        name: '制定寿命',
        type: 'bar',
        barWidth: '20%',
        itemStyle: {
          color: '#409EFF',
          borderRadius: [2, 2, 0, 0],
        },
        data: planned,
        label: {
          show: true,
          position: 'top',
          color: '#ffffff',
          fontSize: 10,
          formatter: '{c}',
        },
        emphasis: {
          itemStyle: {
            color: '#409EFF',
          },
        },
      },
      {
        name: '已使用',
        type: 'bar',
        barWidth: '20%',
        itemStyle: {
          color: '#E6A23C',
          borderRadius: [2, 2, 0, 0],
        },
        data: used,
        label: {
          show: true,
          position: 'top',
          color: '#ffffff',
          fontSize: 10,
          formatter: '{c}',
        },
        emphasis: {
          itemStyle: {
            color: '#E6A23C',
          },
        },
      },
      {
        name: '剩余寿命',
        type: 'bar',
        barWidth: '20%',
        itemStyle: {
          color: '#67C23A',
          borderRadius: [2, 2, 0, 0],
        },
        data: remaining,
        label: {
          show: true,
          position: 'top',
          color: '#ffffff',
          fontSize: 10,
          formatter: '{c}',
        },
        emphasis: {
          itemStyle: {
            color: '#67C23A',
          },
        },
      },
    ],
  }
}

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

// ==================== 生命周期 ====================
onMounted(async () => {
  await nextTick()
  await nextTick()

  await initChart()

  setTimeout(async () => {
    await loadComponentMaintenanceData()
  }, 300)
})

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

<style scoped>
.ldb3-chart-box {
  flex: 1;
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 180px;
  overflow: hidden;
}

.ldb3-chart {
  width: 100% !important;
  height: 100% !important;
  min-height: 220px;
}

.chart-error {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 100%;
  color: #ff6b6b;
  font-size: 14px;
}
</style>

<script lang="ts">
export default {
  name: 'PartMaintenance',
}
</script>
