<script setup lang="tsx">
import { useI18n } from 'vue-i18n'
import { useTheme } from 'vuetify'
import { useCounterStore } from '@/renderer/store/counter'
import { storeToRefs } from 'pinia'
import axios from 'axios'
import { io } from 'socket.io-client'
import { onMounted, onUnmounted, onBeforeUnmount, ref, watch, Ref, watchEffect } from 'vue'
import { Chart, LineController, LinearScale, PointElement, LineElement } from 'chart.js'
import { el } from 'vuetify/lib/locale/index.mjs'

const httpServerPort = ref<number | null>(null)

onMounted(() => {
  window.mainApi.send('msgRequestGetServerPort')

  window.mainApi.receive('msgReceivedServerPort', (event, port) => {
    httpServerPort.value = port
    fetchOscData()
    getComPort()
  })
})

const oscURL = ref<string>('')
const oscPort = ref<string>('')
const oscServerError = ref<string | null>(null)

const getComPort = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/serial_device/port_list`
    )
    const parts = response.data.split(':')
    const valuesFromResponse = parts[1].trim().split(' ')
    optionsComPorts.value = [' '].concat(valuesFromResponse)
    selected1.value = optionsComPorts.value[0] || '' // 如果有选项，将第一个选项设置为选中
    selected2.value = optionsComPorts.value[0] || ''
  } catch (error) {
    console.error('An error occurred while fetching the data:', error)
  }
}

var oscGetSuccess: Boolean = false

const fetchOscData = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/instrument/digital_oscilloscope/keep_listening`
    )

    // Extract data from the response.
    // Assuming response is in the format: "keep_listening: [port] [url]"
    const responseData = response.data
    const [vPrefix, vPort, vURL] = responseData.split(' ')

    oscPort.value = vPort
    oscURL.value = vURL
    terminalPush(`Get osc url: ${vURL}`)
    oscGetSuccess = true
  } catch (err) {
    terminalPush(`Get osc url: err: ${err}`)
    if (err instanceof Error) {
      oscServerError.value = err.message
    } else {
      oscServerError.value = 'An error occurred while fetching data'
    }
  }
}

const { locale, availableLocales } = useI18n()
const { counterIncrease } = useCounterStore()
const { counter } = storeToRefs(useCounterStore())
const theme = useTheme()
const languages = ref(['en'])
const appVersion = ref('Unknown')

onMounted((): void => {
  languages.value = availableLocales

  // Get application version from package.json version string (Using IPC communication)
  window.mainApi.receive('msgReceivedVersion', (event: Event, version: string) => {
    appVersion.value = version
  })
  window.mainApi.send('msgRequestGetVersion')
})

const height = ref(200)
let initialY = 0 // 初始的鼠标Y坐标
let initialHeight = 0 // 开始调整时的元素高度

const isDragging = ref(false)

const startResize = (event: MouseEvent) => {
  initialY = event.clientY
  initialHeight = height.value
  isDragging.value = true // 设置为正在拖动

  document.addEventListener('mousemove', onResize)
  document.addEventListener('mouseup', stopResize)
}

const onResize = (event: MouseEvent) => {
  const deltaY = initialY - event.clientY // 计算鼠标的垂直移动距离
  height.value = initialHeight + deltaY // 调整元素的高度
}

const stopResize = () => {
  document.removeEventListener('mousemove', onResize)
  document.removeEventListener('mouseup', stopResize)
  isDragging.value = false // 设置为停止拖动
}

const startButtonActived = ref(false)
const startButtonTextList = ref(['开始测试', '暂停测试'])
const startButtonText = ref('开始测试')

const iconStartBlack = './iconlib/google/play_arrow_black.png'
const iconStartWhite = './iconlib/google/pause_white.png'
const iconStartList = ref([iconStartBlack, iconStartWhite])
const iconStart = ref(iconStartBlack)

const updateStartButton = (echo = true) => {
  startButtonActived.value = !startButtonActived.value
  const useIndex = startButtonActived.value ? 1 : 0
  startButtonText.value = startButtonTextList.value[useIndex]
  iconStart.value = iconStartList.value[useIndex]
  serviceWhenStartButtonUpdate(echo)
}

const iconStopBlack = './iconlib/google/stop_black.png'
const iconStopWhite = './iconlib/google/stop_white.png'
const iconStop = ref(iconStopBlack)

const iconStopUseBlack = () => {
  iconStop.value = iconStopBlack
}

const iconStopUseWhite = () => {
  iconStop.value = iconStopWhite
  btnStopMessagePush()
  // if (startButtonActived.value) {
  //   updateStartButton(false)
  // }
}

const iconExportBlack = './iconlib/google/upload_black.png'
const iconExportWhite = './iconlib/google/upload_white.png'
const iconExport = ref(iconExportBlack)

const iconExportUseBlack = () => {
  iconExport.value = iconExportBlack
}

const iconExportUseWhite = () => {
  iconExport.value = iconExportWhite
  btnExportMessagePush()
}

class TimerLast {
  startTime: number | null = null
  elapsedTime = ref(0)
  intervalId: any

  get formattedTime() {
    const hours = Math.floor(this.elapsedTime.value / 3600)
    const minutes = Math.floor((this.elapsedTime.value % 3600) / 60)
    const seconds = this.elapsedTime.value % 60
    return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${seconds
      .toString()
      .padStart(2, '0')}`
  }

  start() {
    if (!this.intervalId) {
      this.startTime = Date.now() - this.elapsedTime.value * 1000
      this.intervalId = setInterval(() => {
        this.elapsedTime.value = Math.floor((Date.now() - this.startTime!) / 1000)
      }, 1000)
    }
  }

  pause() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId as any)
      this.intervalId = null
    }
  }

  clear() {
    if (this.intervalId !== null) {
      clearInterval(this.intervalId as any)
      this.intervalId = null
    }
    this.elapsedTime.value = 0 // Reset the elapsed time.
  }

  destroy() {
    if (this.intervalId) {
      clearInterval(this.intervalId)
    }
  }
}

const lastTimer = new TimerLast()

Chart.register(LineController, LinearScale, PointElement, LineElement)

class DigitalMultimeterDataTracker {
  private chart: Chart | null = null
  private data1: number[] = [0]
  private labels: number[] = [0]
  private maxDataPoints: number = 300
  private canvasRef: Ref<HTMLCanvasElement | null>

  constructor(canvasRef: Ref<HTMLCanvasElement | null>) {
    this.canvasRef = canvasRef
  }

  async init() {
    await this.$nextTick()

    if (this.canvasRef.value) {
      const context = this.canvasRef.value.getContext('2d')
      if (context) {
        this.chart = new Chart(context, {
          type: 'line',
          data: {
            labels: this.labels,
            datasets: [
              {
                label: 'Voltage',
                data: this.data1,
                borderColor: '#2673e3',
                fill: false,
                borderWidth: 2
              }
            ]
          },
          options: {
            indexAxis: 'x',
            responsive: true,
            scales: {
              y: {
                beginAtZero: true,
                type: 'linear'
              },
              x: {
                type: 'linear',
                position: 'bottom'
              }
            }
          }
        })
      } else {
        console.error('Failed to get the 2D rendering context from the canvas.')
      }
    }
  }

  updateValue(newValue1?: number, newValue2?: number) {
    if (newValue1 === undefined) {
      newValue1 = this.data1[this.data1.length - 1] || 0
    }

    this.labels.push(this.labels.length ? this.labels[this.labels.length - 1] + 1 : 0)

    this.data1.push(newValue1)

    if (this.data1.length > this.maxDataPoints) {
      this.data1.shift()
      this.labels.shift()
    }

    this.chart?.update()
  }

  getCanvasRef() {
    return this.canvasRef
  }

  private async $nextTick() {
    return new Promise<void>((resolve) => {
      setTimeout(() => {
        resolve()
      }, 0)
    })
  }
}

const digitalMultimeterDataTableImage = ref(null)

const digitalMultimeterDataTracker = new DigitalMultimeterDataTracker(
  digitalMultimeterDataTableImage
)

onMounted(async () => {
  await digitalMultimeterDataTracker.init()
})

let intervalId: number

onMounted(() => {
  intervalId = setInterval(doEvery500ms, 500) as unknown as number
})

let intervalId300ms: number

onMounted(() => {
  intervalId300ms = setInterval(doEvery300ms, 300) as unknown as number
})

onBeforeUnmount(() => {
  clearInterval(intervalId300ms)
})

onBeforeUnmount(() => {
  clearInterval(intervalId)
  lastTimer.destroy()
})

const terminalOutput = ref<string[]>([])

// 定义一个方法，允许在组件内部推送内容到terminalOutput数组
const terminalPush = (content: string) => {
  terminalOutput.value.push(content)
}

const btnStartMessagePush = () => {
  const currentTime = new Date().toLocaleTimeString([], { hour12: false })
  terminalPush(`测试开始: 当前时间 ${currentTime}`)
  lastTimer.start()
}

const btnPauseMessagePush = (echo = true) => {
  if (echo) {
    terminalPush(`测试暂停`)
  }
  lastTimer.pause()
}

const btnStopMessagePush = () => {
  terminalPush(`重置误码统计`)
  clearSenderReceiver()
  lastTimer.pause()
  lastTimer.clear()
}

const btnExportMessagePush = () => {
  exportOscImage()
}

const exportOscImage = async () => {
  try {
    terminalPush(`正在导出示波器画面......`)
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/instrument/digital_oscilloscope/export_image`
    )
    const responseData = response.data
    if (responseData === 'None') {
      terminalPush(`导出失败！未检测到示波器连接`)
    } else {
      terminalPush(`导出成功！导出时刻：${responseData}`)
    }
  } catch (err) {
    digitalMultimeterError.value =
      err instanceof Error ? err.message : 'An error occurred while fetching data'
    terminalPush(
      `导出失败！原因：${
        err instanceof Error ? err.message : 'An error occurred while fetching data'
      }`
    )
  }
}

function getCurrentTime() {
  const now = new Date()
  return now.toLocaleTimeString('en-US', { hour12: false })
}

function serviceWhenStartButtonUpdate(echo) {
  if (startButtonActived.value) {
    serviceWhenStart()
  } else {
    serviceWhenPause(echo)
  }
}

function serviceWhenStart() {
  stdReferenceComSpeedKbitSSetToZero = false
  btnStartMessagePush()
  messageStringFromServerInitialize()
  errorRateStart()
}

function serviceWhenPause(echo) {
  stdReferenceComSpeedKbitSSetToZero = true
  btnPauseMessagePush(echo)
  errorRatePause()
}

const sendNum = ref(0)
const receiveNum = ref(0)
const errorRate = ref(0)

const digitalMultimeterValue = ref(0.0)
const digitalMultimeterError = ref<string | null>(null)

const getDigitalMultimeterValue = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/instrument/digital_multimeter/get_value`
    )
    const responseData = response.data
    const [_prefix, valueStr] = responseData.split(': ')
    const value = parseFloat(valueStr)
    if (isNaN(value)) {
      throw new Error('Received value is not a valid number')
    }
    digitalMultimeterValue.value = value
    digitalMultimeterError.value = null
  } catch (err) {
    digitalMultimeterError.value =
      err instanceof Error ? err.message : 'An error occurred while fetching data'
  }
  if (digitalMultimeterValue.value) {
    digitalMultimeterDataTracker.updateValue(digitalMultimeterValue.value)
  }
}

onUnmounted(() => {
  clearInterval(intervalId) // 清除定时器以防止内存泄漏
})

const showVoltageImageContainer = ref<HTMLElement | null>(null)
const containerHeight = ref(0)
const canvasDimension = ref(0) // 新增一个ref来存储canvas的宽度和高度

const updateDimensions = () => {
  const rawDimension = showVoltageImageContainer.value
    ? showVoltageImageContainer.value.clientWidth - 20
    : 0

  containerHeight.value = rawDimension
  canvasDimension.value = Math.floor(rawDimension / 10) * 10 // 取最接近的整十数
}

// 监听窗口大小变化，并动态更新尺寸
onMounted(() => {
  const handleResize = () => {
    updateDimensions()
  }

  updateDimensions() // 初始化的时候调用一次来设置初始尺寸

  window.addEventListener('resize', handleResize)

  // 在组件卸载前移除事件监听器
  watchEffect((onInvalidate) => {
    onInvalidate(() => {
      window.removeEventListener('resize', handleResize)
    })
  })
})

const msgErrorRate = ref('')

const socket = io('http://localhost:8900/test')

socket.on('new_string', (data) => {
  msgErrorRate.value = data.data
  terminalPush(data.data)
})

const messageStringFromServerInitialize = () => {
  // Send initialization command to the server
  fetch('http://localhost:8900/initialize', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({ message: 'start' })
  })
}

onMounted(() => {
  socket.connect()
})

onUnmounted(() => {
  socket.disconnect()
})

function doEvery500ms() {
  stdReferenceComSpeedKbitSUpdate()
  if (startButtonActived.value) {
    getDigitalMultimeterValue()
  }
  if (optionsComPorts.value.length < 2) {
    getComPort()
  } else {
    if (optionsComPorts.value[1] === '') {
      getComPort()
    }
  }
  if (oscGetSuccess === false) {
    fetchOscData()
  }
}

function doEvery300ms() {
  getRealtimePerformance()
}

// 定义接口来表述选项
interface Option {
  label: string
  value: string
}

const optionsComPorts = ref<string[]>([])

// 下拉框1的选项和选中值
const selected1 = ref(optionsComPorts.value[0])

// 下拉框2的选项和选中值
const selected2 = ref(optionsComPorts.value[0])

// 下拉框3的选项和选中值
const selected3 = ref(optionsComPorts.value[0])

// 监听下拉框值的变化
watch(
  [selected1, selected2, selected3],
  ([newVal1, newVal2, newVal3], [oldVal1, oldVal2, oldVal3]) => {
    submitComDataIsCompleted = false
    updateSelectAreaTipWord([newVal1, newVal2, newVal3])
  }
)

const updateSelectAreaTipWord = ([newVal1, newVal2, newVal3]) => {
  if (submitComDataIsProcessing.value === true) {
    updateSelectAreaTipWordIfSubmitIsProcessing()
  } else {
    if (submitComDataIsCompleted === true) {
      updateSelectAreaTipWordIfSubmitIsCompleted()
    } else {
      if (newVal1 !== ' ' && newVal2 !== ' ') {
        if (newVal1 === newVal2 || newVal1 === newVal3 || newVal2 === newVal3) {
          selectComAreaTipWord.value = tipWordSameValueExpection
          selectComAreaTipWordColor.value = selectComAreaTipWordColorRed
          selectComAreaIsCorrect = false
        } else {
          selectComAreaTipWord.value = tipWordRememberToClickOK
          selectComAreaTipWordColor.value = selectComAreaTipWordColorBlack
          selectComAreaIsCorrect = true
        }
      } else {
        selectComAreaTipWord.value = tipWordEmptyValueExpection
        selectComAreaTipWordColor.value = selectComAreaTipWordColorRed
        selectComAreaIsCorrect = false
      }
    }
  }
}

const updateSelectAreaTipWordIfSubmitIsProcessing = () => {
  selectComAreaTipWord.value = tipWordProgramIsSubmiting
}

const updateSelectAreaTipWordIfSubmitIsCompleted = () => {
  if (submitComDataIfSuccess === false) {
    selectComAreaTipWord.value = tipWordSubmitFailed
    selectComAreaTipWordColor.value = selectComAreaTipWordColorRed
  } else {
    selectComAreaTipWord.value = tipWordSubmitSuccess
    selectComAreaTipWordColor.value = selectComAreaTipWordColorBlack
  }
}

var selectComAreaIsCorrect: Boolean = true

const tipWordSubmitFailed = '配置失败！'
const tipWordSubmitSuccess = '配置成功！'
const tipWordProgramIsSubmiting = '正在配置中......'
const tipWordRememberToClickOK = '务必点击确定！'
const tipWordSameValueExpection = '发送端和接收端均不能相同！'
const tipWordEmptyValueExpection = '发送端和接收端均不能为空！'
const selectComAreaTipWord = ref(tipWordRememberToClickOK)

const selectComAreaTipWordColorBlack = 'black'
const selectComAreaTipWordColorRed = 'red'
const selectComAreaTipWordColor = ref(selectComAreaTipWordColorBlack)

const oscilloscopeImageLoadTipWord = ref('')

const oscilloscopeImageError = () => {
  oscilloscopeImageLoadTipWord.value = '示波器连接性错误！'
}

const oscilloscopeImageLoad = () => {
  oscilloscopeImageLoadTipWord.value = ''
}

const comSenderReceiverSubmit = () => {
  if (selectComAreaIsCorrect === true) {
    doSubmitComConfigData()
  }
}

const doSubmitComConfigData = () => {
  updateSelectAreaTipWordIfSubmitIsProcessing()
  submitComDataIsProcessing.value = true
  submitComDataIsCompleted = false
  submitComDataIfSuccess = false
  ifSenderSuccess = false
  ifReceiverSuccess = false
  ifSenderCompleted = false
  ifReceiverCompleted = false
  submitConfigSender(selected1.value)
  submitConfigReceiver(selected2.value, 1)
  submitConfigReceiver(selected3.value, 2)
}

// 创建一个响应式的引用
const submitComDataIsProcessing = ref<boolean>(false)

// 用来存放计时器的变量
let timer: number | null = null

// 观察变量的变化
watch(submitComDataIsProcessing, (newVal, oldVal) => {
  if (newVal === true) {
    // 当变量变为 true，启动一个计时器
    timer = window.setTimeout(() => {
      ifSenderCompleted = true
      ifReceiverCompleted = true
      ifSenderSuccess = false
      ifReceiverSuccess = false
      submitIsAllCompleted()
      terminalPush('[发送端] [接收端] 配置失败：后台服务响应超时，建议重启程序')
    }, 6000) // 5000毫秒 = 5秒
  } else if (newVal === false && timer !== null) {
    // 当变量变为 false，清除计时器
    window.clearTimeout(timer)
    timer = null
  }
})

// 确保在组件卸载时清除计时器，防止内存泄漏
onBeforeUnmount(() => {
  if (timer !== null) {
    window.clearTimeout(timer)
  }
})

var submitComDataIsCompleted: Boolean = false
var submitComDataIfSuccess: Boolean = false
var ifSenderSuccess: Boolean = false
var ifReceiverSuccess: Boolean = false
var ifSenderCompleted: Boolean = false
var ifReceiverCompleted: Boolean = false

const submitIsAllCompleted = () => {
  if (ifSenderCompleted === true && ifReceiverCompleted === true) {
    submitComDataIsProcessing.value = false
    submitComDataIsCompleted = true
    if (ifSenderSuccess === true && ifReceiverSuccess === true) {
      submitComDataIfSuccess = true
    } else {
      submitComDataIfSuccess = false
    }
    updateSelectAreaTipWordIfSubmitIsCompleted()
  }
}

const submitConfigSender = async (name: string) => {
  try {
    terminalPush(`[发送端] 尝试将端口配置为 [${name}]`)
    const params = {
      port_name: name,
      plc_com_role: 'sender'
    }
    const url = `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/config_connection`
    const response = await axios.get(url, { params })
    console.log('Response:', response.data)
    if (response.data.if_success) {
      ifSenderSuccess = true
      terminalPush(`[发送端] 配置成功：配置为 [${response.data.new_config.sender_port}]`)
    } else {
      ifSenderSuccess = false
      terminalPush(
        `[发送端] 配置失败：尝试配置 [${response.data.received_config.role}] [${response.data.received_config.port}] 时出现错误`
      )
      terminalPush(`[发送端] 配置失败：目标端口发送错误或无响应`)
    }
  } catch (error) {
    console.error('An error occurred while fetching the data:', error)
    ifSenderSuccess = false
    terminalPush(`[发送端] 配置失败：发生未知错误`)
    terminalPush(`[发送端] 错误信息：${error}`)
  } finally {
    ifSenderCompleted = true
    submitIsAllCompleted()
  }
}

const submitConfigReceiver = async (name: string, receiverNumber: number) => {
  try {
    terminalPush(`[接收端] 尝试将端口配置为 [${name}]`)
    var params
    if (receiverNumber === 2) {
      params = {
        port_name: name,
        plc_com_role: 'receiver2'
      }
    } else {
      params = {
        port_name: name,
        plc_com_role: 'receiver'
      }
    }
    const url = `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/config_connection`
    const response = await axios.get(url, { params })
    console.log('Response:', response.data)
    if (response.data.if_success) {
      ifReceiverSuccess = true
      terminalPush(`[接收端] 配置成功：配置为 [${response.data.new_config.receiver_port}]`)
    } else {
      ifReceiverSuccess = false
      terminalPush(`[接收端] 配置失败：目标端口发送错误或无响应`)
    }
  } catch (error) {
    console.error('An error occurred while fetching the data:', error)
    ifReceiverSuccess = false
    terminalPush(`[接收端] 配置失败：发生未知错误`)
    terminalPush(`[接收端] 错误信息：${error}`)
  } finally {
    ifReceiverCompleted = true
    submitIsAllCompleted()
  }
}

// Refs to hold the API response and error (if any)
const sender = ref<{ port: string; url: string } | null>(null)
const receiver = ref<{ port: string; url: string } | null>(null)
const startSenderReceiverError = ref<string | null>(null)

const startSenderReceiver = async () => {
  try {
    var packageConfigData = ''
    if (selectedComSendPackageType.value === '单包16kbit') {
      packageConfigData = '单包16kbit'
    } else if (selectedComSendPackageType.value === '单包1kbit') {
      packageConfigData = '单包1kbit'
    } else {
      packageConfigData = inputComSendPackageContent.value
    }
    const params = {
      package_config: packageConfigData
    }
    const url = `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/start`
    const response = await axios.get(url, { params })
    sender.value = response.data.sender
    receiver.value = response.data.receiver
    startSenderReceiverError.value = null // clear any previous error
  } catch (err) {
    startSenderReceiverError.value =
      (err as { message?: string }).message || 'An error occurred while fetching the data'
  }
}

const pauseSenderReceiver = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/pause`
    )
    startSenderReceiverError.value = null // clear any previous error
  } catch (err) {
    startSenderReceiverError.value =
      (err as { message?: string }).message || 'An error occurred while fetching the data'
  }
}

const clearSenderReceiver = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/clear`
    )
    startSenderReceiverError.value = null // clear any previous error
  } catch (err) {
    startSenderReceiverError.value =
      (err as { message?: string }).message || 'An error occurred while fetching the data'
  }
}

const countAll = ref(0.0)
const countError = ref(0.0)
const getRealtimePerformanceError = ref<string | null>(null)
const getRealtimePerformanceSpeedError = ref<string | null>(null)

const errorRatePercentPLC1 = ref(0.0)
const errorRatePercentPLC2 = ref(0.0)

const getRealtimePerformance = () => {
  // if (errorRateServiceIsRunning === true) {
  // timeMsB = new Date().getTime() - timeMsA
  // timeSecTotal += timeMsB / 1000
  // doGetRealtimePerformanceTemp1()
  // doGetRealtimePerformanceTemp2()
  // }
  doGetRealtimePerformance()
  doGetRealtimePerformanceSpeed()
}

const comSpeedKBitS1 = ref(0.0)
const comSpeedKBitS2 = ref(0.0)

// const doGetRealtimePerformanceTemp1 = async () => {
//   try {
//     const response = await axios.get(`http://localhost:8393/Sender`)
//     countAll.value = response.data.value
//     if (countAll.value !== 0) {
//       errorRatePLC.value = (100 * countError.value) / countAll.value
//       comSpeedKBitS.value = ((countAll.value - countError.value) * 8) / (timeSecTotal * 1000)
//     } else {
//       errorRatePLC.value = 0
//       comSpeedKBitS.value = 0
//     }
//     terminalPush(`总发送: ${countAll.value} 总错误: ${countError.value}`)
//     startSenderReceiverError.value = null // clear any previous error
//   } catch (err) {
//     startSenderReceiverError.value =
//       (err as { message?: string }).message || 'An error occurred while fetching the data'
//   }
// }

// const doGetRealtimePerformanceTemp2 = async () => {
//   try {
//     const response = await axios.get(`http://localhost:8353/Receiver`)
//     countError.value = response.data.value
//     startSenderReceiverError.value = null // clear any previous error
//   } catch (err) {
//     startSenderReceiverError.value =
//       (err as { message?: string }).message || 'An error occurred while fetching the data'
//   }
// }

const doGetRealtimePerformanceSpeed = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/realtime_performance_speed`
    )
    const performanceData = response.data
    getRealtimePerformanceSpeedError.value = null
    const [_prefix, valueStr] = performanceData.split(': ')
    const [DataValue1, DataValue2] = valueStr.split(' ')
    const [DataName1, Value1] = DataValue1.split('=')
    const [DataName2, Value2] = DataValue2.split('=')
    if (valueStr) {
      comSpeedKBitS1.value = Value1
      comSpeedKBitS2.value = Value2
    }
  } catch (err) {
    getRealtimePerformanceSpeedError.value =
      (err as { message?: string }).message || 'An error occurred while fetching the data'
  }
}

const doGetRealtimePerformance = async () => {
  try {
    const response = await axios.get(
      `http://127.0.0.1:${httpServerPort.value}/serial_device/plc/realtime_performance`
    )
    const performanceData = response.data
    getRealtimePerformanceError.value = null
    const [_prefix, valueStr] = performanceData.split(': ')
    const [DataValue1, DataValue2] = valueStr.split(' ')
    const [DataName1, Value1] = DataValue1.split('=')
    const [DataName2, Value2] = DataValue2.split('=')
    if (valueStr) {
      errorRatePercentPLC1.value = Value1
      errorRatePercentPLC2.value = Value2
    }
  } catch (err) {
    getRealtimePerformanceError.value =
      (err as { message?: string }).message || 'An error occurred while fetching the data'
  }
}

var errorRateServiceIsRunning = false

var timeMsA = 0
var timeMsB = 0
var timeSecTotal = 0

const errorRateStart = () => {
  timeMsA = new Date().getTime()
  errorRateServiceIsRunning = true
  startSenderReceiver()
}

const errorRatePause = () => {
  errorRateServiceIsRunning = false
  pauseSenderReceiver()
}

const stdReferenceComSpeedKbitS = ref('')
var stdReferenceComSpeedKbitSUpdateFlag: Boolean = false
var stdReferenceComSpeedKbitSSetToZero = true

const stdReferenceComSpeedKbitSUpdate = () => {
  if (stdReferenceComSpeedKbitSSetToZero) {
    stdReferenceComSpeedKbitS.value = '0.0'
  } else {
    if (stdReferenceComSpeedKbitSUpdateFlag) {
      stdReferenceComSpeedKbitS.value = (115.0 + 1.5 * Math.random()).toFixed(6)
    }
    stdReferenceComSpeedKbitSUpdateFlag = !stdReferenceComSpeedKbitSUpdateFlag
  }
}

const optionsComSendPackageType = ref(['单包16kbit', '单包1kbit', '自定义包内容'])
const selectedComSendPackageType = ref(optionsComPorts.value[0])

// 创建一个响应式引用来存储输入框的值
const inputComSendPackageContent = ref('')

const handleInputComPackageContent = () => {}
</script>

<template>
  <div class="list-page-4">
    <div class="page">
      <div class="page-up">
        <div class="page-left">
          <div class="button-bar">
            <button
              class="button-lock"
              :class="{ active: startButtonActived }"
              @click="updateStartButton()"
            >
              <img :src="iconStart" class="icon" />
              <div class="text">{{ startButtonText }}</div>
            </button>
            <button class="button-unlock" @mousedown="iconStopUseWhite" @mouseup="iconStopUseBlack">
              <img :src="iconStop" class="icon" />
              <div class="text">重置误码统计</div>
            </button>
            <button
              class="button-unlock"
              @mousedown="iconExportUseWhite"
              @mouseup="iconExportUseBlack"
              @mouseleave="iconExportUseBlack"
            >
              <img :src="iconExport" class="icon" />
              <div class="text">导出示波器画面</div>
            </button>
          </div>
          <div class="card">
            <div class="title">示波器</div>
            <div class="output-img">
              <img
                :src="oscURL"
                @error="oscilloscopeImageError"
                @load="oscilloscopeImageLoad"
                id="oscilloscope"
                alt="Oscilloscope Image"
              />
            </div>
            <div class="osc-error-text">{{ oscilloscopeImageLoadTipWord }}</div>
          </div>
        </div>
        <div class="page-right">
          <div class="card">
            <div class="text">万用表</div>
            <div
              class="output-img"
              :style="{ height: containerHeight + 'px' }"
              ref="showVoltageImageContainer"
            >
              <canvas
                ref="digitalMultimeterDataTableImage"
                :width="canvasDimension"
                :height="canvasDimension"
              ></canvas>
            </div>
          </div>
          <div class="card">
            <div class="select-area">
              <div class="text">发送端</div>
              <div class="select-box">
                <select v-model="selected1" class="select-button">
                  <option v-for="option in optionsComPorts" :key="option" :value="option">
                    {{ option }}
                  </option>
                </select>
              </div>
            </div>
            <div class="select-area">
              <div class="text">接收端</div>
              <div class="select-box">
                <select v-model="selected2" class="select-button">
                  <option v-for="option in optionsComPorts" :key="option" :value="option">
                    {{ option }}
                  </option>
                </select>
              </div>
            </div>
            <div class="select-area">
              <div class="text">接收端</div>
              <div class="select-box">
                <select v-model="selected3" class="select-button">
                  <option v-for="option in optionsComPorts" :key="option" :value="option">
                    {{ option }}
                  </option>
                </select>
              </div>
            </div>
            <div class="select-area">
              <div class="text">发包方案</div>
              <div class="select-box">
                <select v-model="selectedComSendPackageType" class="select-button-wide">
                  <option v-for="option in optionsComSendPackageType" :key="option" :value="option">
                    {{ option }}
                  </option>
                </select>
              </div>
            </div>
            <div class="select-area">
              <div class="text">自定义包</div>
              <div class="select-box">
                <input
                  class="select-button-wide"
                  v-model="inputComSendPackageContent"
                  @input="handleInputComPackageContent"
                  placeholder="输入自定义内容......"
                />
              </div>
            </div>
            <div class="select-area">
              <button @click="comSenderReceiverSubmit" class="button">确定</button>
              <div :style="{ color: selectComAreaTipWordColor }" class="tip">{{
                selectComAreaTipWord
              }}</div>
            </div>
          </div>
        </div>
      </div>
      <div class="page-down">
        <div class="top-bar">
          <div @mousedown="startResize" class="resizer" :class="{ dragging: isDragging }">
            <div class="flag-bar">
              <div class="text">测试输出终端</div>
            </div>
            <div class="middle"></div>
            <div class="last-time">
              <div class="text">测试持续时间: {{ lastTimer.formattedTime }}</div>
            </div>
          </div>
        </div>
        <div :style="{ height: height + 'px' }" class="content">
          <div class="terminal-zone">
            <div class="terminal-left">
              <div class="title">测试结果统计</div>
              <div class="line">
                <div class="item">传输速率-1: {{ comSpeedKBitS1 }} kbit/s</div>
                <div class="item">传输速率-2: {{ comSpeedKBitS2 }} kbit/s</div>
                <div class="item">误码率-1: {{ errorRatePercentPLC1 }} %</div>
                <div class="item">误码率-2: {{ errorRatePercentPLC2 }} %</div>
                <div class="item">电平: {{ digitalMultimeterValue }} V</div>
                <!-- <div class="item">msg: {{ messageStringFromServer }}</div> -->
              </div>
            </div>
            <div class="terminal-dividing"></div>
            <div class="terminal-right">
              <div class="terminal-output">
                <div class="text" v-for="(text, index) in terminalOutput" :key="index">
                  {{ text }}
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss">
.list-page-4 {
  width: 100%;
  height: 100%;
  overflow-x: hidden;
  overflow-y: hidden;

  .page {
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    overflow-y: hidden;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: flex-start;
  }

  .icon {
    width: 30px;
    height: 30px;
    margin: 0px;
    margin-left: -5px;
    padding: 0px;
  }

  .page-up {
    width: 100%;
    flex: 1;
    overflow-y: hidden;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: flex-start;
    margin: 20px;
    margin-bottom: 0px;
  }

  .page-down {
    width: 100%;
    // height: 200px;
    background-color: white;
    border-top: 1px solid #dfdfdf;
    position: relative;

    .content {
      width: 100%;
      height: 100%;
      overflow: hidden;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .top-bar {
      height: auto;
      overflow-y: hidden;

      .resizer {
        cursor: ns-resize; // 调整为垂直调整的鼠标样式
        background-color: white;
        height: 22px; // 调整为较小的高度
        width: 100%; // 确保宽度与父 div 一致
        position: absolute;
        top: 0;
        border-top: 1px solid #dfdfdf;
        border-bottom: 1px solid #dfdfdf;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        overflow-y: hidden;
      }

      .text {
        color: black;
        font-size: 15px;
      }

      .flag-bar {
        background-color: #2673e3;
        width: 125px;
        height: 32px;
        padding-left: 10px;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        clip-path: polygon(0% 0%, 100% 0%, 90% 100%, 0% 100%);

        .text {
          color: white;
        }
      }

      .middle {
        flex: 1;
        background-color: red;
      }

      .last-time {
        width: auto;
        height: 100%;
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: flex-start;
        padding-right: 15px;
        font-weight: 500;
      }

      .dragging {
        border-top: 6px solid #2673e3;
        height: 34px;
      }
    }
  }

  .terminal-zone {
    width: 100%;
    height: 100%;
    overflow-x: hidden;
    overflow-y: hidden;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: flex-start;

    .terminal-right {
      flex: 5;
      height: 100%;
      overflow-x: hidden;
      overflow-y: hidden;
    }

    .terminal-output {
      height: 100%;
      overflow-x: auto;
      overflow-y: scroll;
      background-color: white;
      padding: 25px;
      padding-top: 35px;
    }

    .terminal-dividing {
      width: 0px;
      height: 100%;
      border: 0;
      border-right: 1px solid #dfdfdf;
    }

    .terminal-left {
      flex: 3;
      height: 100%;
      background-color: white;
      overflow-y: auto;
      overflow-x: auto;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: flex-start;
      padding: 25px;

      .text {
        color: black;
      }

      .title {
        font-size: 20px;
        font-weight: 500;
        margin-top: 15px;
        margin-bottom: 10px;
      }

      .line {
        width: 100%;
        height: auto;
        display: flex;
        flex-direction: column;
        justify-content: flex-start;
        align-items: flex-start;
        margin-bottom: 6px;

        .item {
          font-size: 18px;
          font-weight: 500;
          flex: 1;
          margin-bottom: 10px;
        }
      }
    }
  }

  .page-left {
    flex: 5;
    // width: 100%;
    height: 100%;
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    justify-content: flex-start;
    align-items: center;
    padding-right: 10px;

    #oscilloscope {
      width: 100%;
    }
  }

  .page-right {
    flex: 3;
    height: 100%;
    overflow-x: hidden;
    overflow-y: auto;
    margin-left: 10px;
    margin-right: 25px;
    padding-right: 10px;

    .text {
      font-size: 18px;
    }

    .card {
      width: 100%;
      overflow-x: hidden;
    }

    .output-img {
      width: 100%;
      border: 1px solid #dfdfdf;
      overflow-y: auto;
      overflow-x: auto;
      display: flex;
      flex-direction: row;
      justify-content: center;
      align-items: center;
      margin-top: 15px;
      margin-bottom: 25px;
      // background-color: #dfdfdf;
    }

    .output-value-group {
      width: 100%;
      height: auto;
      margin-bottom: 25px;
    }

    .output-value {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;
      margin-top: 15px;

      .text,
      .text-value {
        display: flex;
        flex-direction: row;
        justify-content: flex-start;
        align-items: center;
        font-size: 16px;
        width: 55px;
        padding-left: 5px;
        padding-right: 5px;
      }

      .subtitle {
        white-space: nowrap;
      }

      .text-value {
        padding-right: 0;
        margin-right: 0;
        padding-left: 5px;
        white-space: nowrap;
      }

      .value {
        height: 85px;
        width: 100%;
        border: 1px solid #dfdfdf;
        overflow-y: auto;
        overflow-x: auto;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        background-color: #dfdfdf;
      }

      #current-img {
        margin-top: 10px;
      }
    }
  }

  .button-bar {
    width: 100%;
    height: 50px;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
    margin-bottom: 20px;
  }

  .button-bar .button-lock,
  .button-bar .button-unlock {
    width: auto;
    height: 42px;
    padding-left: 12px;
    padding-right: 12px;
    border-radius: 5px;
    background-color: white;
    margin-right: 15px;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: center;
  }

  .button-bar .button-lock:hover,
  .button-bar .button-unlock:hover {
    font-weight: 500;
  }

  .button-bar .button-lock.active,
  .button-bar .button-unlock:active {
    color: white;
    background-color: #2673e3;
    font-weight: 500;
  }

  .card {
    margin-bottom: 20px;
    width: 100%;
    height: auto;
    background-color: white;
    padding: 35px;
    border-radius: 5px;
    color: black;
    font-size: 16px;
    font-size: 18px;

    .title {
      font-size: 20px;
      font-weight: 500;
      margin-bottom: 15px;
    }

    .select-area {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;

      .select-box {
        margin-top: 6px;
        margin-bottom: 6px;

        .select-button,
        .select-button-wide {
          width: 100px;
          padding: 3px;
          padding-left: 9px;
          border: 1px solid rgba(0, 0, 0, 0.35);
          border-radius: 5px;
          margin-left: 10px;
          margin-right: 20px;
        }

        .select-button-wide {
          width: 160px;
          font-size: 16px;
        }
      }
    }

    .osc-error-text {
      color: red;
      font-size: 18px;
      font-weight: 500;
    }

    .button {
      margin-top: 12px;
      font-size: 18px;
      border: 1px solid rgba(0, 0, 0, 0.35);
      border-radius: 5px;
      padding: 3px;
      padding-left: 8px;
      padding-right: 8px;
    }

    .button:hover {
      background-color: #2673e3;
      color: white;
      border: 1px solid rgba($color: #2673e3, $alpha: 1);
    }

    .button:active {
      background-color: rgba($color: #2673e3, $alpha: 0.5);
      border: 1px solid rgba($color: #2673e3, $alpha: 0.5);
      color: white;
    }

    .tip {
      margin-top: 12px;
      font-size: 18px;
      margin-left: 16px;
      font-weight: 500;
    }
  }
}
</style>
