<template>
  <div>
    <!-- <button @click="moveCanvas('left')">左边-左移</button>
       <button @click="moveCanvas('right')">左边-右移</button>-->
    <sb :-isfd="FD"/>
    <div class="container">
      <div id="canvas-container">
        <canvas ref="leftCanvas" id="leftCanvas" width="21" height="1140"></canvas>
        <canvas ref="bottomCanvas" id="bottomCanvas" width="1140" height="1140"></canvas>
        <canvas
          ref="topCanvas"
          id="topCanvas"
          width="1140"
          height="1140"
          @mousedown="handleMouseDown($event, 'L')"
        ></canvas>
      </div>

      <div id="canvas-container1">
        <canvas ref="rightCanvas" id="rightCanvas" width="21" height="1140"></canvas>
        <canvas ref="bottomCanvas1" id="bottomCanvas1" width="1140" height="1140"></canvas>
        <canvas
          ref="topCanvas1"
          id="topCanvas1"
          width="1140"
          height="1140"
          @mousedown="handleMouseDown($event, 'R')"
        ></canvas>
      </div>
    </div>
    <span class="myrtip"
      >{{ '&nbsp;走速：' + convert(suduratio, 0) + 'mm/s ' }}
      {{ '&nbsp;振幅：' + convert(lineratio, 1) + 'mm/mv ' }} {{ '&nbsp;报告模式：6X2' }}</span
    >
    <div @click="preventClick">
      <el-slider
        v-model="sliderValue"
        :min="0"
        :max="50"
        :step="1"
        @input="handleSliderChange"
        :show-tooltip="false"
      />
    </div>
 
  </div>
  <!--纠错功能-->
  <el-dialog v-model="isdialog" title="导联纠错" width="600" @close="close">
    <div>
      <el-checkbox-group v-model="transfer" :min="0" :max="2" class="mycheckbox-group">
        <el-checkbox
          v-for="city in transferleads"
          :key="city"
          :label="city"
          :value="city"
          class="mycheckbox-item"
          @change="checkboxchage"
        >
          {{ city }}
        </el-checkbox>
      </el-checkbox-group>
    </div>
    <div style="margin-top: 10px">
      <el-button type="primary" @click="clickdl" :disabled="checkes">交换导联</el-button>
      <el-button type="primary" @click="recovery()">恢复正常</el-button>
    </div>
  </el-dialog>
</template>

<script setup>
import { ref, reactive, onMounted } from 'vue'
import { number } from 'vue-types'
import Magnifier from './ECGFD.vue'
import sb from './ECGSB.vue'
import BB from './ECGBB.vue'

//读取出来的json
const text = ref()
const sliderValue = ref(0) // 初始化滑块值
//给父组件回传值
const emits = defineEmits(['update:value'])
const lineratio1 = ref(0.05) //画线的系数 振幅
const previousValue = ref(0) // 记录上一个滑块值
const swipeDirection = ref('') // 用于存储滑动方向
// 响应式引用
const leftCanvas = ref(null)
const rightCanvas = ref(null)
const bottomCanvas = ref(null)
const bottomCanvas1 = ref(null)
const topCanvas = ref(null)
const topCanvas1 = ref(null)
const url = ref()
/*鼠标绘制相关*/
const ctx = ref(null)
const isVertical = ref(false) // 控制线条类型，true 为竖直，false 为水平
const lastPoint = ref(null) // 用于存储上一个点的坐标
const isdialog = ref(false) //用于开启纠错
const transfer = ref() //纠错导联 值

const checkes = ref(true) //控制导联交换按钮是否可用

// 响应式数据
const beatArray1 = ref([])
const beatArray2 = ref([]) //备份数据
let offset = 0
const spacing = 20

const heightoff=ref(0)//心电图的偏移量 高度变化的时候
const FD=ref(false)

function handleMouseDown(event, type) {
  if (type === 'L') {
    ctx.value = topCanvas.value.getContext('2d')
  } else if (type === 'R') {
    ctx.value = topCanvas1.value.getContext('2d')
  }

  if (infoParams.Ismeasure !== 1) {
    return
  }
  const rect =
    type === 'L'
      ? topCanvas.value.getBoundingClientRect()
      : topCanvas1.value.getBoundingClientRect()
  const x = event.clientX - rect.left
  const y = event.clientY - rect.top

  if (lastPoint.value) {
    // 如果已经有一个点被记录，那么使用这个新点和上一个点绘制线条
    drawLineAndDistance(lastPoint.value, { x, y })
    lastPoint.value = null // 重置上一个点
  } else {
    // 记录这个点作为上一个点
    lastPoint.value = { x, y }
  }
}

function calculateDistance(x1, y1, x2, y2) {
  return Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2))
}

function drawLineAndDistance(point1, point2) {
  //ctx.value.clearRect(0, 0, topCanvas.value.width, topCanvas.value.height); // 清除画布

  //竖线
  if (Math.abs(point2.x - point1.x) <= 20) {
    point2.x = point1.x
    lineTo(point1.x, point1.y, point2.x, point2.y, 1)
  } else if (Math.abs(point2.y - point1.y) <= 20) {
    //横
    point2.y = point1.y
    lineTo(point1.x, point1.y, point2.x, point2.y, 0)
  } else {
    lastPoint.value = null
  }
}

function lineTo(x, y, x1, y1, type) {
  // 绘制两个点
  ctx.value.fillStyle = 'black'
  ctx.value.beginPath()
  ctx.value.arc(x, y, 1, 0, 2 * Math.PI)
  ctx.value.fill()
  ctx.value.beginPath()
  ctx.value.arc(x1, y1, 1, 0, 2 * Math.PI)
  ctx.value.fill()

  // 绘制直线
  ctx.value.beginPath()
  ctx.value.moveTo(x, y)
  ctx.value.lineTo(x1, y1)
  ctx.value.strokeStyle = 'black'
  ctx.value.lineWidth = 1
  ctx.value.stroke()

  // 计算并绘制距离文本
  const distance = calculateDistance(x, y, x1, y1)
  const ms = (25.4 / 96) * (25 / 1000) * distance
  ctx.value.font = '11px Arial'
  ctx.value.fillStyle = 'black'
  if (type === 1) {
    ctx.value.fillText(`距离: ${ms.toFixed(2)}ms`, x + 5, y + 30)
  } else {
    ctx.value.fillText(`距离: ${ms.toFixed(2)}ms`, x + 10, y - 10)
  }
}

/*鼠标绘制相关*/

const handleSliderChange = (value) => {
  // 计算当前值与上一次值之间的差值
  const difference = value - previousValue.value
  const swipeDifference = Math.abs(difference)
  console.log('滑动差值' + swipeDifference)
  if (value > previousValue.value) {
    swipeDirection.value = '右滑' // 向右滑动
    moveCanvas('left', swipeDifference)
  } else if (value < previousValue.value) {
    swipeDirection.value = '左滑' // 向左滑动
    moveCanvas('right', swipeDifference)
  } else {
    swipeDirection.value = '未滑动' // 没有滑动
  }
  previousValue.value = value // 更新上一个值
  console.log('滑块值改变为:', value)
}

//渲染组件后执行
onMounted(async () => {
  console.log('挂载完成')
  // topCanvas.value = document.getElementById('topCanvas');
})

nextTick(() => {
  /* 计算宽度和高度*/
  var canvasContainer = document.getElementById('canvas-container')
  var canvasContainer1 = document.getElementById('canvas-container1')

  var leftCanvas = document.getElementById('leftCanvas')
  // 获取元素的计算后的样式
  var style = window.getComputedStyle(canvasContainer)
  // 获取元素的计算后的样式
  var leftCanvasstyle = window.getComputedStyle(leftCanvas)

  // 获取宽度
  var widthPercentage = style.width

  //获取高度
  var heightPercentage = style.height

  var widthInPixels = canvasContainer.offsetWidth
  var heightInPixels = canvasContainer.offsetHeight

  // 宽度除以 20 并取整
  var adjustedWidth = widthInPixels / 20
  var adjustedheight = heightInPixels / 20
  // 判断 adjustedWidth 是否为整数
  if (Number.isInteger(adjustedWidth)) {
    canvasContainer.style.width = widthInPixels + 'px'
  } else {
    const integer = Math.round(adjustedWidth)
    const awidth = integer * 20
    canvasContainer.style.width = awidth - 20 + 'px'
    canvasContainer1.style.width = awidth - 20 + 'px'
    console.log('adjustedWidth 不是整数')
  }
  if (Number.isInteger(adjustedheight)) {
    canvasContainer.style.height = heightInPixels + 'px'
    leftCanvas.height = heightInPixels + 'px'
  } else {
    const integer = Math.round(adjustedheight)
    const ahe = integer * 20
    canvasContainer.style.height = ahe - 118 + 'px'
    canvasContainer1.style.height = ahe - 118 + 'px'
    leftCanvas.height = ahe - 118
    heightoff.value=(ahe -118)/6
  }
  fetchData()
})

// 定义异步方法
const fetchData = async () => {
  try {
    text.value = await fetchFileContent(infoParams.jsonurl)
    handleFileChange()
    Bottom()
    // console.log('获取到的数据:', text.value);
  } catch (error) {
    console.error('获取数据时出错:', error)
  }
}

const inputSlider = (value) => {
  setScrollTop(value)
}
const formatTooltip = (value) => {
  return `${value} px`
}
async function fetchFileContent(url) {
  try {
    const response = await fetch(url)
    if (!response.ok) {
      throw new Error('网络响应不是 ok')
    }
    return await response.text() // 返回文本内容
  } catch (error) {
    console.error('获取文件内容时出错:', error)
    throw error // 抛出错误以便调用者可以处理
  }
}
///接受参数
const infoParams = defineProps({
  jsonurl: String,
  examId: String,
  Isgrid: Number,
  Ismeasure: Number,
  Isfd: Boolean,
  lineratio: Number,
  suduratio: Number,
  isrefresh: Boolean,
  iscorrect: Boolean
})

// 监听多个值的变化
watch(
  [
    () => infoParams.Isgrid,
    () => infoParams.Ismeasure,
    () => infoParams.lineratio,
    () => infoParams.suduratio,
    () => infoParams.isrefresh,
    () => infoParams.iscorrect,
    ()=>infoParams.Isfd
  ],
  (
    [newIsGridValue, newAnotherValue, newlineratio, newsuduratio, newisrefresh, newiniscorrect,newfd],
    [oldIsGridView, oldAnotherValue, oldlineratio, oldsuduratio, oldisrefresh, oldiscorrect,oldds]
  ) => {
    // 检查 isGrid 是否发生变化
    if (newIsGridValue !== oldIsGridView) {
      // 值发送变化的时候 重新绘制 先清除画布
      Repaint()
    }
    // 检查 anotherValue 是否发生变化
    if (newAnotherValue !== oldAnotherValue) {
      // 是否开启测量
    }
    //振幅
    if (newlineratio !== oldlineratio) {
      Repaint()
    }
    //走速
    if (newsuduratio !== oldsuduratio) {
      Repaint()
    }
    //刷新
    if (newisrefresh !== oldisrefresh) {
      console.log(newisrefresh)
      Repaint()
    }
    //
    if (newiniscorrect !== oldiscorrect) {
      isdialog.value = newiniscorrect
    }
    if(newfd!==oldds)
    {
      FD.value=newfd
      console.log(FD.value)
    }
  }
)
//恢复导联
function recovery() {
  transfer.value = []
  beatArray1.value = beatArray2.value.slice()
  Repaint()
}

//交换导联按钮
function checkboxchage() {
  checkes.value = transfer.value.length === 2 ? false : true
}
//交换导联
function clickdl() {
  const one = transfer.value[0]
  const two = transfer.value[1]
  const oneindex = transferleads.indexOf(one)
  const twoindex = transferleads.indexOf(two)
  swapElements(oneindex, twoindex)
  Repaint()
}

// 定义一个方法来交换数组中的两个元素
const swapElements = (index1, index2) => {
  // 检查索引是否有效
  if (
    index1 < 0 ||
    index2 < 0 ||
    index1 >= beatArray1.value.length ||
    index2 >= beatArray1.value.length
  ) {
    console.log('索引超出数组范围')
    return
  }
  // 交换元素
  const temp = beatArray1.value[index1]
  beatArray1.value[index1] = beatArray1.value[index2]
  beatArray1.value[index2] = temp
}

//纠错
function close() {
  isdialog.value = false
  transfer.value = []
  emits('update:value', isdialog.value)
}

// 定义一个对象来存储命令值和对应的比例文本
const lineratioMap = {
  0.012: '2.5',
  0.025: '5',
  0.05: '10',
  0.1: '20',
  0.2: '40'
}
const suduratioMap = {
  0.2: '5',
  0.4: '10',
  0.5: '12.5',
  1: '25',
  2: '50'
}
function convert(command, type) {
  if (type === 0) {
    return suduratioMap[command] || null
  } else {
    return lineratioMap[command] || null
  }
}

// 刷新 重绘
function Repaint() {
  eliminate(leftCanvas.value)
  eliminate(rightCanvas.value)
  eliminate(bottomCanvas.value)
  eliminate(bottomCanvas1.value)
  eliminate(topCanvas.value)
  eliminate(topCanvas1.value)
  Bottom()
}

// 定义要处理的键
const leads = [
  'LEAD_I',
  'LEAD_II',
  'LEAD_III',
  'LEAD_AVR',
  'LEAD_AVL',
  'LEAD_AVF',
  'LEAD_V1',
  'LEAD_V2',
  'LEAD_V3',
  'LEAD_V4',
  'LEAD_V5',
  'LEAD_V6'
]

const transferleads = ['I', 'II', 'III', 'avR', 'avL', 'avF', 'V1', 'V2', 'V3', 'V4', 'V5', 'V6']
// 每个心电波形名称数组
const lead_name = ['I', 'II', 'III', 'aVR', 'aVL', 'aVF']

const rlead_name = ['V1', 'V2', 'V3', 'V4', 'V5', 'V6']

//将读取到的文件转换成数组
function handleFileChange() {
  const json = JSON.parse(text.value)

  leads.forEach((lead, index) => {
    const value = json[lead].trim()
    const commaSeparatedValue = value.replace(/\s+/g, ',')
    const numberArray = commaSeparatedValue.split(',').map(Number)
    beatArray1.value.push(numberArray)
  })
  beatArray2.value = beatArray1.value.slice()
}

// 定义移动画布的函数
function moveCanvas(direction, count) {
  const xoffset = count === 1 ? 1 : count

  if (direction === 'left') {
    if (offset !== -20 * 60) offset -= spacing * xoffset
  } else if (direction === 'right') {
    if (offset !== 0) offset += spacing * xoffset
  }

  // if (direction === 'left') {
  //    offset -= spacing
  // } else if (direction === 'right') {
  //    offset += spacing
  // }
  topCanvas.value.style.left = offset + 'px'
  topCanvas1.value.style.left = offset + 'px'
}

//清除画布内容
function eliminate(c_canvas) {
  const ctx = c_canvas.getContext('2d')
  ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
}
function Bottom() {
  drawBottomCanvas()
  drawTopCanvas()
}
// 绘制底层画布的内容
function drawBottomCanvas() {
  if (infoParams.Isgrid === 1) {
    lbackcanvas(leftCanvas.value)
    rbackcanvas(rightCanvas.value)
    drawMultipleLines(bottomCanvas.value, beatArray1.value)
    drawMultipleLines(bottomCanvas1.value, beatArray1.value)
  }
  begin(leftCanvas.value, beatArray1.value)
  beginr(rightCanvas.value, beatArray1.value)
}

// 绘制顶层画布的内容
function drawTopCanvas() {
  drawMultipleLinesl(topCanvas.value, beatArray1.value)
  drawMultipleLinesr(topCanvas1.value, beatArray1.value)
}
//定标电压的画布
function lbackcanvas(c_canvas) {
  drawBigBG(c_canvas)
  drawSmallGrid(c_canvas)
  drawMediumGrid(c_canvas)
}
function rbackcanvas(c_canvas) {
  drawBigBG(c_canvas)
  drawSmallGrid(c_canvas)
  drawMediumGrid(c_canvas)
}

// 绘制函数
function drawBigBG(c_canvas) {
  const context = c_canvas.getContext('2d')
  context.globalAlpha = 1
  context.fillStyle = 'rgba(0,0,0,0)'
  context.fillRect(0, 0, c_canvas.width + 21, c_canvas.height + 21)
}
//画小格子
function drawSmallGrid(c_canvas) {
  const context = c_canvas.getContext('2d')
  context.globalAlpha = 1
  context.fillStyle = '#ff6b64'
  const dotMarginX = 20 / 5,
    dotMarginY = 20 / 5
  for (let i = dotMarginX; i < c_canvas.width; i += dotMarginX) {
    if (i % 20 !== 0) {
      for (let j = dotMarginY; j < c_canvas.height; j += dotMarginY) {
        if (j % 20 !== 0) {
          context.rect(i, j, 1, 0.5)
        }
      }
    }
  }
  context.fill()
}
//中格子
function drawMediumGrid(c_canvas) {
  const context = c_canvas.getContext('2d')
  context.globalAlpha = 1
  context.strokeStyle = '#ff6b64'
  context.strokeWidth = 1.5
  context.beginPath()
  for (let x = 0.5; x < c_canvas.width; x += 20) {
    context.moveTo(x, 0)
    context.lineTo(x, c_canvas.height)
  }
  for (let y = 0.5; y < c_canvas.height; y += 20) {
    context.moveTo(0, y)
    context.lineTo(c_canvas.width, y)
  }
  context.stroke()
  context.closePath()
}

function begin(c_canvas, beatArray) {
  const ctx = c_canvas.getContext('2d')
  ctx.globalAlpha = 1
  ctx.strokeStyle = '#000000'
  let offset = -50
  const spacing = heightoff.value
  beatArray.forEach((dataArray, index) => {
    if (index <= 6) {
      const x = 0
      const y = offset - dataArray[index - 1] * 0.025
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineTo(x + 5, y)
      ctx.moveTo(x + 5, y - 40)
      ctx.lineTo(x + 15, y - 40)
      ctx.moveTo(x + 5, y - 40)
      ctx.lineTo(x + 5, y)
      ctx.moveTo(x + 15, y - 40)
      ctx.lineTo(x + 15, y)
      ctx.moveTo(x + 15, y)
      ctx.lineTo(x + 20, y)
      ctx.stroke()
      ctx.closePath()
      if (index > 0 && index < 4) {
        ctx.font = '15px Arial'
        ctx.fillStyle = 'black'
        ctx.fillText(lead_name[index - 1], x + 4, y + 14)
      } else {
        ctx.font = '10px Arial'
        ctx.fillStyle = 'black'
        ctx.fillText(lead_name[index - 1], x + 1, y + 12)
      }
      offset += spacing
    }
  })
  ctx.strokeStyle = '#000000'
}

function beginr(c_canvas, beatArray) {
  const ctx = c_canvas.getContext('2d')
  ctx.globalAlpha = 1
  ctx.strokeStyle = '#000000'
  let offset = -50
  const spacing = heightoff.value
  beatArray.forEach((dataArray, index) => {
    if (index <= 6) {
      const x = 0
      const y = offset - dataArray[index - 1] * 0.025
      ctx.beginPath()
      ctx.moveTo(x, y)
      ctx.lineTo(x + 5, y)
      ctx.moveTo(x + 5, y - 40)
      ctx.lineTo(x + 15, y - 40)
      ctx.moveTo(x + 5, y - 40)
      ctx.lineTo(x + 5, y)
      ctx.moveTo(x + 15, y - 40)
      ctx.lineTo(x + 15, y)
      ctx.moveTo(x + 15, y)
      ctx.lineTo(x + 20, y)
      ctx.stroke()
      ctx.closePath()
      ctx.font = '11px Arial'
      ctx.fillStyle = 'black'
      ctx.fillText(rlead_name[index - 1], x + 2, y + 12)
      offset += spacing
    }
  })
  ctx.strokeStyle = '#000000'
}

//背景
function drawMultipleLines(c_canvas, beatArrays) {
  const ctx = c_canvas.getContext('2d')
  ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
  drawBigBG(c_canvas)
  drawSmallGrid(c_canvas)
  drawMediumGrid(c_canvas)
}
//左边心电图
function drawMultipleLinesl(c_canvas, beatArrays) {
  const ctx = c_canvas.getContext('2d')
  ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
  let offset = 0
  const spacing = heightoff.value
  beatArrays.forEach((dataArray, index) => {
    if (index <= 5) {
      drawLine1(c_canvas, dataArray, offset, index)
      offset += spacing
    }
  })
}
//右边心电图
function drawMultipleLinesr(c_canvas, beatArrays) {
  const ctx = c_canvas.getContext('2d')
  ctx.clearRect(0, 0, c_canvas.width, c_canvas.height)
  let offset = 0
  const spacing = heightoff.value
  beatArrays.forEach((dataArray, index) => {
    if (index > 5) {
      drawLine1(c_canvas, dataArray, offset, index)
      offset += spacing
    }
  })
}
//画心电图线
function drawLine1(c_canvas, beatArray, offset, index) {
  const ctx = c_canvas.getContext('2d')
  ctx.strokeStyle = '#030101'
  ctx.lineWidth = 1
  ctx.beginPath()
  if (index <= 5) {
    if (beatArray.length > 0) {
      const firstX = 0
      const firstY = (heightoff.value-50) - beatArray[0] * infoParams.lineratio + offset
      ctx.moveTo(firstX, firstY)
      for (let i = 0; i < beatArray.length - 1; i++) {
        const x2 = (0 + (i + 1) / 10) * infoParams.suduratio
        const y2 = (heightoff.value-50) - beatArray[i + 1] * infoParams.lineratio + offset
        ctx.lineTo(x2, y2)
      }
      ctx.stroke()
      ctx.closePath()
    }
  }
  if (index > 5) {
    if (beatArray.length > 0) {
      const firstX = 0
      const firstY = (heightoff.value-50) - beatArray[0] * infoParams.lineratio + offset
      ctx.moveTo(firstX, firstY)
      for (let i = 0; i < beatArray.length - 1; i++) {
        const x2 = (0 + (i + 1) / 10) * infoParams.suduratio
        const y2 = (heightoff.value-50) - beatArray[i + 1] * infoParams.lineratio + offset
        ctx.lineTo(x2, y2)
      }
      ctx.stroke()
      ctx.closePath()
    }
  }
}
</script>

<style scoped>
.container {
  display: flex;
  justify-content: center;
  align-items: flex-start;
  width: 100%;
  overflow-x: auto;
  overflow-y: hidden;
  height: 100%;
  max-width: 3920px;
  max-height: 3920px;
}
#canvas-container,
#canvas-container1 {
  overflow-x: hidden;
  overflow-y: hidden;
  position: relative;
  width: 50%;
  height: 77vh;
  margin-right: 0;
}
#bottomCanvas,
#bottomCanvas1 {
  position: absolute;
  /* width: 1140; */
  /* height: 75vh; */
  z-index: 0;
  margin-left: 20px;
}
#leftCanvas,
#rightCanvas {
  position: absolute;
  width: 21;
  /* height: 600px; */
  z-index: 99;
  background-color: rgb(255, 255, 255);
}
#topCanvas,
#topCanvas1 {
  position: absolute;
  width: 1140px;
  /* height: 600px; */
  z-index: 1;
  background: transparent;
  margin-left: 20px;
}
canvas {
  position: absolute;
}
.myrtip {
  display: flex;
  flex-direction: row-reverse;
  margin-right: 30px;
}
.mycheckbox-group {
  display: flex;
  flex-wrap: wrap;
}
.mycheckbox-item {
  margin-left: 5px;
  margin-right: 30px; /* 根据需要调整间距 */
  margin-bottom: 10px; /* 根据需要调整间距 */
  width: 30px;
}
/* 添加其他样式 */
</style>
