<template>
  <div class="left-data-box2">
    <LDBTitleBox title="刀具寿命管理" align="left" />
    <div class="ldb2-chart-box">
      <div v-show="loading" class="chart-loading">加载中...</div>
      <div v-show="error != ''" class="chart-error">{{ error }}</div>
      <div id="ldb2-chart" class="ldb2-chart" v-show="!loading && error == ''"></div>
    </div>
  </div>
</template>

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

// ==================== 数据定义 ====================
const toolData = ref({
  toolNames: [] as string[],
  planned: [] as number[],
  actual: [] as number[],
})

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

let chartInstance: echarts.ECharts | null = null

// ==================== 计算属性 ====================
// 计算刀具统计数据
const statistics = computed(() => {
  const totalTools = toolData.value.toolNames.length
  const totalUsage = toolData.value.actual.reduce((sum, usage) => sum + usage, 0)
  const averageUsage = totalTools > 0 ? totalUsage / totalTools : 0

  return {
    totalTools,
    averageUsage,
  }
})

// ==================== 数据获取与处理 ====================
// 加载刀具数据
const loadToolData = 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', 10],
      ['FieldsToSelect', null],
      ['WhereConditions', `工位号 = '${deviceCode}'`],
      ['SortField', '创建时间'],
      ['SortDirection', 'desc'],
      ['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 {
          processToolData(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 processToolData = (data: any[]) => {
  const toolNames: string[] = []
  const planned: number[] = []
  const actual: number[] = []

  // 解析数据并填充数组
  data.forEach((item, index) => {
    const toolName = item.toolName || item.刀具号 || `刀具${index + 1}`
    const plannedTime = parseFloat(item.plannedTime || item.设定时长 || '0')
    const actualTime = parseFloat(item.actualTime || item.使用时长 || '0')

    // 只有存在刀具名称时才添加数据
    if (toolName) {
      toolNames.push(toolName)
      planned.push(isNaN(plannedTime) ? 0 : plannedTime)
      actual.push(isNaN(actualTime) ? 0 : actualTime)
    }
  })

  // 如果解析后没有有效数据，则使用默认数据
  if (toolNames.length === 0) {
    console.warn('处理后的刀具数据为空，使用默认数据')
    setDefaultData()
    return
  }

  toolData.value = {
    toolNames,
    planned,
    actual,
  }
}

// 设置默认数据（用于演示或数据为空时）
const setDefaultData = () => {
  toolData.value = {
    toolNames: ['刀具A', '刀具B', '刀具C', '刀具D', '刀具E'],
    planned: [120, 100, 150, 80, 200],
    actual: [80, 95, 120, 60, 180],
  }
}

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

  const chartDom = document.getElementById('ldb2-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: 'value',
      },
      yAxis: {
        type: 'category',
        data: [],
      },
      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 (!toolData.value.toolNames || toolData.value.toolNames.length === 0) {
    showNoDataState()
    return
  }

  const { toolNames, planned, actual } = toolData.value

  ensureCanvasExists()

  try {
    chartInstance.clear()

    setTimeout(() => {
      const option = getChartOption(toolNames, planned, actual)
      chartInstance.setOption(option, true)

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

// 确保canvas元素存在
const ensureCanvasExists = () => {
  const chartDom = document.getElementById('ldb2-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 (toolData.value.toolNames.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 = (toolNames: string[], planned: number[], actual: number[]) => {
  return {
    backgroundColor: 'transparent',
    animation: false,
    tooltip: {
      trigger: 'axis',
      axisPointer: {
        type: 'shadow',
      },
      formatter: (params: any) => {
        let result = `${params[0].name}<br/>`
        params.forEach((param: any) => {
          const value = param.value ? `${param.value}h` : '0h'
          result += `${param.seriesName}: ${value}<br/>`
        })
        return result
      },
    },
    legend: {
      data: ['计划使用时长', '实际使用时长'],
      textStyle: {
        color: '#ffffff',
      },
      orient: 'horizontal',
      right: 10,
      top: 0,
    },
    grid: {
      left: '3%',
      right: '4%',
      bottom: '0%',
      top: '15%',
      containLabel: true,
    },
    xAxis: {
      type: 'value',
      boundaryGap: [0, 0.01],
      axisLabel: {
        color: '#ffffff',
        formatter: '{value}h',
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#ffffff',
        },
      },
      splitLine: {
        lineStyle: {
          color: 'rgba(255, 255, 255, 0.1)',
        },
      },
    },
    yAxis: {
      type: 'category',
      data: toolNames,
      axisLabel: {
        color: '#ffffff',
        fontSize: 10,
        formatter: (value: string) => {
          // 长文本处理
          if (value.length > 4) {
            return value.substring(0, 4) + '...'
          }
          return value
        },
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#ffffff',
        },
      },
      axisTick: {
        alignWithLabel: true,
      },
    },
    series: [
      {
        name: '计划使用时长',
        type: 'bar',
        data: planned,
        itemStyle: {
          color: '#409EFF',
          borderRadius: [0, 2, 2, 0],
        },
        label: {
          show: false,
          position: 'right',
          color: '#ffffff',
          fontSize: 10,
          formatter: '{c}h',
        },
        emphasis: {
          itemStyle: {
            color: '#409EFF',
          },
        },
      },
      {
        name: '实际使用时长',
        type: 'bar',
        data: actual,
        itemStyle: {
          color: '#E6A23C',
          borderRadius: [0, 2, 2, 0],
        },
        label: {
          show: false,
          position: 'right',
          color: '#ffffff',
          fontSize: 10,
          formatter: '{c}h',
        },
        emphasis: {
          itemStyle: {
            color: '#E6A23C',
          },
        },
      },
    ],
  }
}

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

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

  await initChart()

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

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

// ==================== 暴露方法 ====================
// 暴露方法供外部调用
defineExpose({
  loadToolData,
})
</script>

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

.ldb2-chart {
  width: 100% !important;
  height: 100% !important;
  min-height: 120px;
}

.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: 'ToolUseTime',
}
</script>
