<script setup lang="tsx">
import { useI18n } from 'vue-i18n'
import { useTheme } from 'vuetify'
import { openExternal } from '@/renderer/utils'
import { useCounterStore } from '@/renderer/store/counter'
import { storeToRefs } from 'pinia'
import { onMounted, ref, watch, onBeforeUnmount } from 'vue'
import axios from 'axios'

import Progress from '@/renderer/pages/ListNum/ColorfulProgress.vue'

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

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

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

let intervalId: number

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

let intervalId300ms: number

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

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] || '' // 如果有选项，将第一个选项设置为选中
  } catch (error) {
    console.error('An error occurred while fetching the data:', error)
  }
}

const percent = ref(15)
const progressWidth = ref(10)
const cncValue = ref(0.0)
const cncValueString = ref(percent.value.toFixed(2))

watch(cncValue, (newPercent) => {
  cncValueString.value = processCNCValueStringFormat(newPercent)
})

watch(percent, (newPercent) => {
  cncValue.value = processCNCValue(0.36 * newPercent)
})

function processCNCValue(rawValue: number): number {
  // 四舍五入到最近的0.05
  // rawValue / 0.05 通过除以0.05来“扩大”我们的精度
  // Math.round(...) 四舍五入到最近的整数
  // ... * 0.05 通过乘以0.05“缩小”我们的精度，将数字变回原来的范围
  const processedValue = Math.round(rawValue / 0.5) * 0.5

  // 将processedValue保留两位有效数字
  // +processedValue.toFixed(2) 将字符串转换为数字，以避免字符串结果
  return +processedValue.toFixed(2)
}

function processCNCValueStringFormat(num: number): string {
  // 获取整数和小数部分
  const integerPart = Math.floor(num)
  const decimalPart = num - integerPart

  // 将整数部分转换为至少两位数的字符串
  const integerString = integerPart < 10 ? '0' + integerPart : '' + integerPart

  // 转换并修剪/舍入小数部分，确保两位
  const decimalString = decimalPart.toFixed(2).slice(2) // slice(2) 删除“0.”前缀

  return integerString + '.' + decimalString
}

const progressMouseUp = () => {
  progressWidth.value = 10
}

const progressMouseOver = () => {
  progressWidth.value = 20
}

const progressMouseLeave = () => {
  progressWidth.value = 10
}

function progressOnIncrease(scale: number) {
  const res = percent.value + scale
  if (res > 100) {
    percent.value = 100
  } else {
    percent.value = res
  }
}

function progressOnDecline(scale: number) {
  const res = percent.value - scale
  if (res < 0) {
    percent.value = 0
  } else {
    percent.value = res
  }
}

const progressMouseDown = (event: MouseEvent) => {
  const adjustLine = event.currentTarget as HTMLElement
  const rect = adjustLine.getBoundingClientRect()
  const initialX = event.clientX

  const updatePercent = (e: MouseEvent) => {
    let x = e.clientX - rect.left
    const dragRange = 0.8 * rect.width // 80% of the line width
    const dragStart = 0.1 * rect.width // Start from 10% of the line width

    // Clamp x within the draggable range
    x = Math.max(Math.min(x, dragStart + dragRange), dragStart)

    // Calculate the percent within the 10% to 90% range
    percent.value = ((x - dragStart) / dragRange) * 100
  }

  const moveHandler = (e: MouseEvent) => {
    if (e.clientX > initialX) {
      progressOnIncrease(((e.clientX - initialX) / rect.width) * 100)
    } else {
      progressOnDecline(((initialX - e.clientX) / rect.width) * 100)
    }
    updatePercent(e) // Update the percent directly based on the cursor position
  }

  const upHandler = () => {
    document.removeEventListener('mousemove', moveHandler)
    document.removeEventListener('mouseup', upHandler)
  }

  document.addEventListener('mousemove', moveHandler)
  document.addEventListener('mouseup', upHandler)
  updatePercent(event)
}

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 terminalOutput = ref<string[]>([])

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

function doEvery500ms() {
  if (optionsComPorts.value.length < 2) {
    getComPort()
  } else {
    if (optionsComPorts.value[1] === '') {
      getComPort()
    }
  }
}

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

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

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

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

const updateSelectAreaTipWord = ([newVal1]) => {
  if (submitComDataIsProcessing.value === true) {
    updateSelectAreaTipWordIfSubmitIsProcessing()
  } else {
    if (submitComDataIsCompleted === true) {
      updateSelectAreaTipWordIfSubmitIsCompleted()
    } else {
      if (newVal1 !== ' ') {
        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
  }
}

let selectComAreaIsCorrect: Boolean = true

const tipWordSubmitFailed = '配置失败！'
const tipWordSubmitSuccess = '配置成功！'
const tipWordProgramIsSubmiting = '正在配置中......'
const tipWordRememberToClickOK = '务必点击确定！'
const tipWordEmptyValueExpection = '端口配置不能为空！'
const selectComAreaTipWord = ref(tipWordRememberToClickOK)

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

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

const doSubmitComConfigData = () => {
  updateSelectAreaTipWordIfSubmitIsProcessing()
  submitComDataIsProcessing.value = true
  submitComDataIsCompleted = false
  submitComDataIfSuccess = false
  submitConfigCNC(selected1.value)
}

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

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

// 观察变量的变化
watch(submitComDataIsProcessing, (newVal, oldVal) => {
  if (newVal === true) {
    // 当变量变为 true，启动一个计时器
    timer = window.setTimeout(() => {
      submitComDataIsCompleted = true
      submitComDataIfSuccess = 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)
  }
})

let submitComDataIsCompleted: Boolean = false
let submitComDataIfSuccess: Boolean = false

const submitIsAllCompleted = () => {
  if (submitComDataIsCompleted === true) {
    submitComDataIsProcessing.value = false
    updateSelectAreaTipWordIfSubmitIsCompleted()
  }
}

const setCNCValue = async (targetValueCNC: string) => {
  try {
    terminalPush(`[衰减器] 尝试将衰减设置为 ${targetValueCNC} dB`)
    const params = {
      value: targetValueCNC
    }
    const url = `http://127.0.0.1:${httpServerPort.value}/serial_device/cnc/set`
    const response = await axios.get(url, { params })
    const ifSetSuccess = response.data
    if (ifSetSuccess === 'True' || ifSetSuccess === 'true') {
      terminalPush(`[衰减器] 衰减成功调整为 ${targetValueCNC} dB`)
    } else {
      terminalPush(`[衰减器] 衰减调整失败`)
    }
  } catch (error) {
    terminalPush(`[衰减器] 衰减调整失败：${error}`)
  }
}

const submitConfigCNC = async (name: string) => {
  try {
    terminalPush(`[衰减器] 尝试将端口配置为 [${name}]`)
    const params = {
      port_name: name
    }
    const url = `http://127.0.0.1:${httpServerPort.value}/serial_device/cnc/config_connection`
    const response = await axios.get(url, { params })
    const ifSuccess = response.data
    if (ifSuccess === 'True' || ifSuccess === 'true') {
      submitComDataIfSuccess = true
      terminalPush(`[衰减器] 配置成功：配置为 [${name}]`)
    } else {
      submitComDataIfSuccess = false
      terminalPush(`[衰减器] 配置失败：尝试配置 [${name}] 时出现错误`)
      terminalPush(`[衰减器] 配置失败：目标端口发送错误或无响应`)
    }
  } catch (error) {
    console.error('An error occurred while fetching the data:', error)
    submitComDataIfSuccess = false
    terminalPush(`[衰减器] 配置失败：发生未知错误`)
    terminalPush(`[衰减器] 错误信息：${error}`)
  } finally {
    submitComDataIsCompleted = true
    submitIsAllCompleted()
  }
}
</script>

<template>
  <div class="list-page-2">
    <div class="page">
      <div class="page-up">
        <div class="control-zone">
          <div class="title">
            <div class="text">衰减器: {{ cncValueString }} dB</div>
          </div>
          <div class="config-zone">
            <div
              class="adjust-line"
              @mouseup="progressMouseUp"
              @mousedown="progressMouseDown"
              @mouseover="progressMouseOver"
              @mouseleave="progressMouseLeave"
            >
              <Progress
                :width="'80%'"
                :percent="percent"
                :stroke-width="progressWidth"
                :stroke-color="{
                  '0%': '#108ee9',
                  '100%': '#87d068',
                  direction: 'right'
                }"
                :show-info="false"
              />
            </div>
            <div class="btn-zone">
              <div @click="setCNCValue(cncValueString)" class="btn">
                <div class="text">应用配置</div>
              </div>
            </div>
          </div>
        </div>
      </div>
      <div class="page-down">
        <div class="top-bar">
          <div class="resizer" :class="{ dragging: isDragging }" @mousedown="startResize">
            <div class="flag-bar">
              <div class="text">测试输出终端</div>
            </div>
            <div class="middle"></div>
            <div class="last-time">
              <div class="text"></div>
            </div>
          </div>
        </div>
        <div :style="{ height: height + 'px' }" class="content">
          <div class="terminal-zone">
            <div class="terminal-left">
              <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">
                <button @click="comSenderReceiverSubmit" class="button">确定</button>
                <div :style="{ color: selectComAreaTipWordColor }" class="tip">{{
                  selectComAreaTipWord
                }}</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-2 {
  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;
    background-color: white;
    padding: 0;
  }

  .page-up {
    width: 100%;
    height: 100%;
    flex: 1;
    overflow-x: hidden;
    overflow-y: auto;
    display: flex;
    flex-direction: row;
    justify-content: flex-start;
    align-items: flex-start;

    .control-zone {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
      margin-top: 15vh;
    }

    .title {
      font-size: 35px;
      font-weight: 500;
      margin-bottom: 0;
    }

    .config-zone {
      width: 100%;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
    }

    .adjust-line {
      width: 100%;
      height: auto;
      padding-top: 6vh;
      padding-bottom: 6vh;
      padding-left: 0;
      padding-right: 0;
      display: flex;
      flex-direction: column;
      justify-content: flex-start;
      align-items: center;
    }

    .btn-zone {
      display: flex;
      flex-direction: row;
      justify-content: flex-start;
      align-items: center;

      .btn {
        width: 105px;
        height: 35px;
        overflow: hidden;
        border: 1px solid #dfdfdf;
        border-radius: 5px;
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
        color: black;
        position: relative;
        cursor: pointer;
        transition: all 0.1s cubic-bezier(0.78, 0.14, 0.15, 0.86);
      }

      .btn::after {
        content: '';
        position: absolute;
        width: 100%;
        height: 100%;
        background-color: rgba(255, 255, 255, 1);
        z-index: 3;
        transition: all 0.1s cubic-bezier(0.78, 0.14, 0.15, 0.86);
      }

      .btn:hover {
        background: linear-gradient(to right, #108ee9 0%, #87d068 100%);
        background-color: white;
        color: white;
      }

      .btn:hover::after {
        content: '';
        position: absolute;
        width: 100%;
        height: 100%;
        background-color: rgba(255, 255, 255, 0);
        z-index: 3;
      }

      .text {
        font-size: 20px;
        font-weight: 400;
        z-index: 5;
      }
    }
  }

  .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;
      padding-top: 40px;

      .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;
        }
      }

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

        .text {
          font-size: 20px;
          font-weight: 500;
        }

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

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

        .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>
