<template>
  <div class="debug_container">
    <div class="left_oper_container">
      <div class="bread_wrap">
        <t-breadcrumb>
          <t-breadcrumbItem>首页</t-breadcrumbItem>
          <t-breadcrumbItem>相机调试</t-breadcrumbItem>
        </t-breadcrumb>
      </div>
      <div class="operation_proposed">
        <div class="top_btns">
          <div class="two_btns">
            <div
              :class="isCameraOpen ? 'default_btn' : 'active_btn'"
              @click="handleStartCpature"
            >
              打开相机
            </div>
            <div
              :class="isCameraOpen ? 'active_btn' : 'default_btn'"
              @click="handleStopCpature"
            >
              关闭相机
            </div>
          </div>
          <div class="two_btns">
            <div
              :class="flashStatus ? 'default_btn' : 'active_btn'"
              @click="handleOpenFlashLight"
            >
              打开闪光灯
            </div>
            <div
              :class="flashStatus ? 'active_btn' : 'default_btn'"
              @click="handleCloseFlashLight"
            >
              关闭闪光灯
            </div>
          </div>
          <div class="active_btn" @click="handleGetMechanicalArmState">
            获取机械臂坐标
          </div>
        </div>
        <div class="camera_param">
          <div class="slider_wrap mb50">
            <p class="title">模拟通道亮度</p>
            <t-slider
              v-model="simulation_brightness"
              :min="0"
              :max="65535"
              @change="handleSimulationBrightness"
            />
            <p class="number">{{ simulation_brightness }}</p>
          </div>
          <div class="slider_wrap">
            <p class="title">曝光时间</p>
            <t-slider
              v-model="exposure"
              :min="0"
              :max="100000"
              @change="handleExposureTime"
            />
            <p class="number">{{ exposure }}</p>
          </div>
        </div>
        <div class="camera_image">
          <div class="active_btn" @click="handleTakePhoto">拍照</div>
          <div class="active_btn" @click="handleGetCharacterRecognitionResult">
            识别
          </div>
        </div>
        <div class="identify_results">
          <div class="result_wrap">
            <p class="title">结果</p>
            <div class="result">{{ recognitionResult }}</div>
          </div>
          <div class="save_form">
            <t-select
              v-model="station_core_id"
              class="demo-select-base"
              clearable
              filterable
              placeholder="请选择堆芯"
            >
              <t-option
                v-for="item in coreList"
                :value="item.id"
                :label="item.name"
                :key="item.id"
              >
                {{ item.name }}
              </t-option>
            </t-select>
            <t-button class="save_btn" @click="onSubmit">保存</t-button>
          </div>
        </div>
      </div>
    </div>
    <div class="right_camera_container">
      <p class="time_photo">实时照片</p>
      <div class="default_photo" v-if="!isCameraOpen">
        <svg
          xmlns="http://www.w3.org/2000/svg"
          xmlns:xlink="http://www.w3.org/1999/xlink"
          fill="none"
          version="1.1"
          width="85.90400695800781"
          height="76.7254638671875"
          viewBox="0 0 85.90400695800781 76.7254638671875"
        >
          <g>
            <path
              d="M6.91322,0L78.9908,0C82.8088,0,85.904,3.2252,85.904,7.20367L85.904,69.6923C85.8151,73.6041,82.7458,76.7266,78.9908,76.7255L6.91322,76.7255C3.15816,76.7266,0.0888908,73.6041,0,69.6923L0,7.20367C0,3.22519,3.09515,0,6.91322,0ZM63.5689,38.8742C64.784,37.9363,66.4446,37.9363,67.6596,38.8742L78.9908,43.7761L78.9908,7.20367L6.91322,7.20367L6.91322,38.107L22.3351,21.7815C23.6974,20.2285,26.0451,20.2285,27.4074,21.7815L48.6381,49.3601L63.5689,38.8742ZM51.0912,24.6798C51.0912,19.1005,55.4317,14.5776,60.7861,14.5776C66.1404,14.5777,70.4809,19.1005,70.481,24.6798C70.481,30.2591,66.1404,34.7821,60.7861,34.7821C55.4317,34.7821,51.0912,30.2591,51.0912,24.6798ZM58.0045,24.4667C58.0045,26.0675,59.2498,27.3652,60.7861,27.3652L60.7861,27.5357C62.3886,27.5387,63.6621,26.1337,63.5678,24.4667C63.5678,22.8658,62.3224,21.5681,60.7862,21.5681C59.2499,21.5681,58.0045,22.8658,58.0045,24.4667Z"
              fill-rule="evenodd"
              fill="#5E5C5C"
              fill-opacity="1"
            />
          </g>
        </svg>
      </div>
      <img :src="photoUrl" class="photo" v-else />
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
import {
  startCapture,
  stopCapture,
  getCameraState,
  takeAndSavePhoto,
  startCharacterRecognition,
  getCharacterRecognitionResult,
  stopCharacterRecognition,
  getFlashBrightnessAnalog,
  getMechanicalArmState,
  openFlashLight,
  closeFlashLight,
  setFlashBrightnessAnalog,
  setExposureTimeRaw,
  getCameraParametersInteger,
} from '@/command'
import { coreListApi } from '@/api/info'
import { MessagePlugin } from 'tdesign-vue-next'
import { addCameraConfig } from '@/api/camera'

const photoUrl = ref('')
const recognitionResult = ref('')
const station_core_id = ref('')

const coreList = ref([])

onMounted(async () => {
  const res = await coreListApi()
  if (res?.code == 200) {
    coreList.value = res?.data?.list
  }
})

const onSubmit = async () => {
  if (!station_core_id.value) {
    MessagePlugin('error', { content: '请选择堆芯' })
    return
  }
  // 保存当前相机参数到相应的堆芯
  const data = {
    station_core_id: station_core_id.value,
    simulation_brightness: simulation_brightness.value,
    exposure: exposure.value,
  }
  const res = await addCameraConfig(data)
  console.log(res)
  if (res?.code == 200) {
    MessagePlugin('success', { content: '保存成功' })
  }
}

setInterval(
  () => {
    photoUrl.value = `${
      import.meta.env.VITE_HOST_URL
    }app/core/realtime_photo/now.png?${Math.random()}`
  },
  500,
  500,
)

const simulation_brightness = ref(0)
const exposure = ref(0)
const flashStatus = ref(false)

// 相机参数
const isCameraOpen = ref(false)

const handleStartCpature = () => {
  if (!isCameraOpen.value) {
    websocketsend(startCapture)
  }
}
const handleStopCpature = () => {
  if (isCameraOpen.value) {
    websocketsend(stopCapture)
  }
}
const handleGetCameraState = () => {
  websocketsend(getCameraState)
}
const handleTakePhoto = () => {
  if (isCameraOpen.value) {
    // 如果相机打开则发送拍照，如果相机关闭 则提醒用户
    websocketsend(takeAndSavePhoto)
  } else {
    MessagePlugin('error', { content: '请先开启相机' })
  }
}

const handleStartCharacterRecognition = () => {
  websocketsend(startCharacterRecognition)
}
const handleStopCharacterRecognition = () => {
  websocketsend(stopCharacterRecognition)
}
const handleGetCharacterRecognitionResult = () => {
  if (isCameraOpen.value) {
    // 如果相机打开则发送拍照，如果相机关闭 则提醒用户
    websocketsend(getCharacterRecognitionResult)
  } else {
    MessagePlugin('error', { content: '请先开启相机' })
  }
}
const handleGetMechanicalArmState = () => {
  websocketsend(getMechanicalArmState)
}

const handleOpenFlashLight = () => {
  if (!flashStatus.value) {
    websocketsend(openFlashLight)
  }
}
const handleCloseFlashLight = flag => {
  if (flashStatus.value) {
    websocketsend(closeFlashLight)
  }
}

const isOpenCamera = () => {
  if (!isCameraOpen.value) {
    MessagePlugin('error', { content: '请先打开相机' })
    return false
  }
  return true
}

// 是否真正建立连接
const lockReconnect = ref(false)
// 断开 重连倒计时
const timeoutnum = ref(null)

const websock = ref(null)

const reconnect = () => {
  //重新连接
  if (lockReconnect.value) {
    return
  }
  lockReconnect.value = true
  //没连接上会一直重连，设置延迟避免请求过多
  timeoutnum.value && clearTimeout(timeoutnum.value)
  timeoutnum.value = setTimeout(function () {
    //新连接
    initWebSocket()
    lockReconnect.value = false
  }, 5000)
}

// 接收到消息后改变状态
const websocketonmessage = e => {
  // 相机启动停止后接收到回执 而后发送获取相机状态指令 实时改变页面状态
  const data = JSON.parse(e.data)
  const { messageId, success } = data
  if (success) {
    switch (messageId) {
      case 'startCapture':
        MessagePlugin('success', { content: '开启相机成功' })
        handleGetCameraState()
        break
      case 'stopCapture':
        MessagePlugin('success', { content: '关闭相机成功' })
        handleGetCameraState()
        break
      case 'getCameraState':
        const { cameraState } = data
        const { isOpen } = cameraState
        isCameraOpen.value = isOpen
        break
      case 'getMechanicalArmState':
        const { state } = data
        const { x, y } = state || {}
        recognitionResult.value = `机械臂坐标x：${x}, y: ${y}`
        break
      case 'takeAndSavePhoto':
        const { photoInfo } = data
        const { path } = photoInfo
        recognitionResult.value = `图片保存路径为${path}`
        break
      case 'getCameraParametersInteger':
        const { value } = data
        exposure.value = value
        break
      case 'openFlashLight':
        flashStatus.value = true
        break
      case 'CloseFlashLight':
        flashStatus.value = false
        break
      case 'getFlashBrightnessAnalog':
        const { brightness } = data
        simulation_brightness.value = brightness
        break
      case 'getCharacterRecognitionResult':
        const { result } = data
        const { result: str, srcImagePath } = result || {}
        recognitionResult.value = `识别结果为${
          str ? str : '空结果'
        }, 图片保存路径为${srcImagePath}`
        break
      default:
        break
    }
  } else {
    // MessagePlugin('error', { content: 'ws发送指令执行错误' })
  }
}

const websocketonopen = () => {
  console.log('客户端链接成功！！！')
  handleGetCameraState()
  setTimeout(() => {
    websocketsend(getCameraParametersInteger)
    // 无法获取当前闪光灯是开是关。建议上层代码，初始化时候关闭闪光灯，然后在本地保存一个当前状态
    handleCloseFlashLight(false)
    websocketsend(getFlashBrightnessAnalog)
  }, 1000)
}

const websocketonerror = () => {
  reconnect()
}

// 发送消息
const websocketsend = data => {
  websock.value.send(data)
}

const websocketclose = () => {
  reconnect()
}

const initWebSocket = () => {
  //初始化weosocket
  const wsuri = import.meta.env.VITE_WEBSOCKET_CAMERA_URL
  websock.value = new WebSocket(wsuri)
  // 客户端接收服务端数据时触发
  websock.value.onmessage = websocketonmessage
  // 连接建立时触发
  websock.value.onopen = websocketonopen
  // 通信发生错误时触发
  websock.value.onerror = websocketonerror
  // 连接关闭时触发
  websock.value.onclose = websocketclose
}

initWebSocket()

// 业务处理
const handleExposureTime = value => {
  websocketsend(setExposureTimeRaw(value))
}

const handleSimulationBrightness = value => {
  websocketsend(setFlashBrightnessAnalog(value))
}

onUnmounted(() => {
  websock.value.close()
})
</script>

<style lang="scss" scoped>
.debug_container {
  width: 100%;
  height: 100%;
  background: #fff;
  border-radius: 6px;
  padding-bottom: 30px;
  padding-right: 30px;
  box-sizing: border-box;
  display: flex;
  align-items: center;
  .left_oper_container {
    flex: 1;
    height: 100%;
    padding-left: 28px;
    box-sizing: border-box;
    .bread_wrap {
      padding: 20px 0;
      box-sizing: border-box;
      border-bottom: 1px solid #d8d8d8;
    }
    .operation_proposed {
      padding: 36px 36px 0 0;
      box-sizing: border-box;
      .top_btns {
        display: flex;
        align-items: center;
        justify-content: space-between;
        .two_btns {
          display: flex;
          align-items: center;
          .default_btn {
            display: flex;
            align-items: center;
            justify-content: center;
            border-radius: 6px;
            margin-right: 10px;
            padding: 7px 16px;
            font-size: 16px;
            font-weight: normal;
            letter-spacing: 0.07em;
            color: #ffffff;
            background: #ebebeb;
          }
        }
        .active_btn {
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 7px 16px;
          font-size: 16px;
          font-weight: normal;
          letter-spacing: 0.07em;
          color: #ffffff;
          background: #0052d9;
          border-radius: 6px;
          margin-right: 10px;
          cursor: pointer;
        }
      }
      .camera_param {
        padding: 53px 0;
        .slider_wrap {
          display: flex;
          align-items: center;
          .title {
            font-size: 20px;
            font-weight: 500;
            letter-spacing: 0.07em;
            color: #191919;
            margin-right: 32px;
            white-space: nowrap;
          }
          .number {
            margin-left: 20px;
            width: 30px;
          }
        }
        .mb50 {
          margin-bottom: 50px;
        }
      }
      .camera_image {
        padding: 48px 0;
        border-top: solid 1px #d8d8d8;
        border-bottom: solid 1px #d8d8d8;
        display: flex;
        align-items: center;
        .active_btn {
          display: flex;
          align-items: center;
          justify-content: center;
          padding: 7px 23px;
          font-size: 16px;
          font-weight: normal;
          letter-spacing: 0.07em;
          color: #ffffff;
          background: #0052d9;
          border-radius: 6px;
          margin-right: 30px;
          cursor: pointer;
        }
      }
      .identify_results {
        padding-top: 44px;
        display: flex;
        .result_wrap {
          flex: 1;
          .title {
            font-size: 20px;
            font-weight: 500;
            letter-spacing: 0.07em;
            color: #191919;
          }
          .result {
            padding: 10px 0;
          }
        }
        .save_form {
          flex: 1;
          .save_btn {
            margin-top: 14px;
          }
        }
      }
    }
  }
  .right_camera_container {
    flex: 1;
    height: 100%;
    padding-left: 30px;
    box-sizing: border-box;
    display: flex;
    flex-direction: column;
    .time_photo {
      padding: 20px 0;
      font-size: 20px;
      box-sizing: border-box;
      font-weight: normal;
      letter-spacing: 0.07em;
      color: #191919;
    }
    .default_photo {
      flex: 1;
      width: 100%;
      border-radius: 6px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #ebebeb;
    }
    .photo {
      flex: 1;
      width: 100%;
      border-radius: 6px;
    }
  }
}
</style>
