<script setup lang="ts">
import type { CourseType, ExperimentRecord } from '../types'
import { HomeFilled } from '@element-plus/icons-vue'
import { ElMessageBox, ElMessage } from 'element-plus'
import { useGetCourseList } from '../composables/useGetCourseList'
import { upload } from '@/utils/upload'
import { getExperimentRecord, uploadExperimentPicture, submitExperimentRecord } from '../api'
import dayjs from 'dayjs'

const Book = defineAsyncComponent(() => import('../components/Book.vue'))
const Video = defineAsyncComponent(() => import('../components/Video.vue'))
const Discuss = defineAsyncComponent(() => import('../components/Discuss.vue'))
const Result = defineAsyncComponent(() => import('../components/Result.vue'))
const ReportDialog = defineAsyncComponent(() => import('../components/ReportDialog.vue'))

const route = useRoute()

// 左侧
const leftPanelVisible = $ref<boolean>(true)
const form = reactive<{ course_id: string; experiment_id: string }>({
  course_id: (route.query.course_id as string) || '',
  experiment_id: (route.query.experiment_id as string) || ''
})
// 课程列表
const { courses } = useGetCourseList()
// 实验列表
const experimentList = $computed(() => {
  const course = courses.value.find((item: CourseType) => item.id === form.course_id)
  return course?.experiments || []
})

watchEffect(() => {
  if (!form.course_id && courses.value.length) {
    const [first] = courses.value
    form.course_id = first.id
  }
  if (!form.experiment_id && experimentList.length) {
    const [first] = experimentList
    form.experiment_id = first.id
  }
})
// 课程改变
function handleCourseChange(value: string) {
  ElMessageBox.confirm('切换实验，将会导致当前操作内容变化，请确认当前操作无误并确认切换实验。', '提示').then(() => {
    form.course_id = value
  })
}
// 实验改变
function handleExperimentChange(value: string) {
  ElMessageBox.confirm('切换实验，将会导致当前操作内容变化，请确认当前操作无误并确认切换实验。', '提示').then(() => {
    form.experiment_id = value
  })
}

let detail = $ref<ExperimentRecord>()
provide('detail', $$(detail))

function fetchInfo() {
  if (!form.experiment_id) return
  getExperimentRecord({ experiment_id: form.experiment_id }).then(res => {
    detail = Array.isArray(res.data.data) ? undefined : res.data.data
  })
}
watchEffect(() => {
  fetchInfo()
})

// 右侧
const LAB_URL = import.meta.env.VITE_LAB_URL
let iframeKey = $ref(Date.now())
// 返回首页
function handleBackHome() {
  ElMessageBox.confirm('此操作将会强制返回到实验室首页，您当前的操作内容有可能丢失，确定返回首页吗？', '提示').then(
    () => {
      iframeKey = Date.now()
    }
  )
}

const reportDialogVisible = $ref(false)
// 是否已经提交
const submitted = $computed(() => {
  return detail ? detail.status !== 0 : false
})
// 是否禁用
const disabled = $computed(() => {
  return submitted || !form.experiment_id
})
const iframeRef = $ref<HTMLIFrameElement>()

let screenshotLoading = $ref(false)
let screenshotTimestamp = $ref(0)
// 截图
function handleCapture() {
  const pictures = detail?.pictures || []
  if (pictures.length >= 20) {
    ElMessage.error('已达到单个实验最大截图数量，无法截图，请在过程与结果功能中删除多余截图之后再进行操作。')
    return
  }
  const iframeWindow = iframeRef?.contentWindow
  if (!iframeWindow) return
  screenshotTimestamp = Date.now()
  screenshotLoading = true
  // 发送截图消息
  iframeWindow?.postMessage({ action: 'screenshot', timestamp: screenshotTimestamp }, '*')
}
// 截图之后
function handleCaptureCallback(event: MessageEvent) {
  const { data } = event
  if (data.action === 'screenshot' && data.timestamp === screenshotTimestamp) {
    upload(data.blob).then(url => {
      uploadPicture(url)
    })
  }
}
onMounted(() => {
  window.addEventListener('message', handleCaptureCallback, false)
})
onUnmounted(() => {
  window.removeEventListener('message', handleCaptureCallback, false)
})

// 上传截图
function uploadPicture(url: string) {
  const pictures = detail?.pictures || []
  pictures.unshift({ url, name: Date.now() + '.png', upload_time: dayjs().format('YYYY-MM-DD HH:mm:ss') })
  uploadExperimentPicture({ experiment_id: form.experiment_id, pictures: JSON.stringify(pictures) }).then(() => {
    fetchInfo()
    screenshotLoading = false
  })
}
// 提交实验
function handleSubmit() {
  ElMessageBox.confirm('此操作将会提交该实验，状态会变为已提交，您将不能再操作该实验，确定提交实验吗？', '提示').then(
    () => {
      submitExperimentRecord({ experiment_id: form.experiment_id }).then(() => {
        ElMessage({ message: '提交成功', type: 'success' })
        fetchInfo()
      })
    }
  )
}
</script>

<template>
  <section class="lab">
    <div class="lab-left" :class="{ 'is-hidden': !leftPanelVisible }">
      <div class="lab-left__inner">
        <el-form :model="form" label-suffix=":" hide-required-asterisk>
          <el-form-item label="请选择课程">
            <el-select :model-value="form.course_id" @change="handleCourseChange" style="width: 100%">
              <el-option v-for="item in courses" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="请选择实验" prop="experiment_id">
            <el-select :model-value="form.experiment_id" @change="handleExperimentChange" style="width: 100%">
              <el-option v-for="item in experimentList" :key="item.id" :label="item.name" :value="item.id"></el-option>
            </el-select>
          </el-form-item>
        </el-form>
        <el-tabs type="border-card" stretch>
          <el-tab-pane label="实训指导" lazy>
            <Book :course_id="form.course_id" :experiment_id="form.experiment_id"></Book>
          </el-tab-pane>
          <el-tab-pane label="操作视频" lazy>
            <Video :course_id="form.course_id" :experiment_id="form.experiment_id"></Video>
          </el-tab-pane>
          <el-tab-pane label="讨论交流" lazy>
            <Discuss :experiment_id="form.experiment_id"></Discuss>
          </el-tab-pane>
          <el-tab-pane label="过程与结果" lazy>
            <Result :experiment_id="form.experiment_id" @update="fetchInfo"></Result>
          </el-tab-pane>
        </el-tabs>
      </div>
      <div class="panel-icon" @click="leftPanelVisible = !leftPanelVisible">
        <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 86" aria-hidden="true" width="16" height="86">
          <g fill="none" fill-rule="evenodd">
            <path
              class="path-wapper"
              d="M0 0l14.12 8.825A4 4 0 0116 12.217v61.566a4 4 0 01-1.88 3.392L0 86V0z"
              fill="#e1e4eb"
            ></path>
            <path
              class="path-arrow"
              d="M10.758 48.766a.778.778 0 000-1.127L6.996 43l3.762-4.639a.778.778 0 000-1.127.85.85 0 00-1.172 0l-4.344 5.202a.78.78 0 000 1.128l4.344 5.202a.85.85 0 001.172 0z"
              fill="#8D9EA7"
              fill-rule="nonzero"
            ></path>
          </g>
        </svg>
      </div>
    </div>
    <div class="lab-right">
      <AppCard>
        <el-row justify="space-between">
          <el-button type="primary" :icon="HomeFilled" :disabled="submitted" @click="handleBackHome"
            >返回首页</el-button
          >
          <div>
            <el-button type="primary" :disabled="disabled" @click="handleSubmit">提交</el-button>
            <el-button type="primary" :disabled="disabled" @click="reportDialogVisible = true">上传报告</el-button>
            <el-button type="primary" :disabled="disabled" :loading="screenshotLoading" @click="handleCapture"
              >截图</el-button
            >
          </div>
        </el-row>
      </AppCard>
      <div class="lab-box">
        <el-empty description="您已经提交该实验，不能再进行操作，切换其他实验再做操作吧。" v-if="submitted" />
        <iframe :src="LAB_URL" :key="iframeKey" frameborder="0" class="iframe" ref="iframeRef" v-else></iframe>
      </div>
    </div>
  </section>
  <!-- 上传报告 -->
  <ReportDialog
    v-model="reportDialogVisible"
    :experiment_id="form.experiment_id"
    @update="fetchInfo"
    v-if="reportDialogVisible && form.experiment_id"
  ></ReportDialog>
</template>

<style lang="scss" scoped>
.lab {
  display: flex;
  height: calc(100vh - 110px);
}
.lab-left {
  position: relative;
  width: 400px;
  padding: 20px;
  background-color: #e1e4eb;
  border-radius: 6px;
  box-sizing: border-box;
  transition: all 0.1s;
  &.is-hidden {
    width: 0;
    padding: 0;
    .panel-icon {
      left: -20px;
      right: 0;
    }
    .path-arrow {
      transform-origin: center center;
      transform: rotate(180deg);
    }
  }
  .lab-left__inner {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    overflow: hidden;
  }
  .el-tabs {
    flex: 1;
    border: 0;
    overflow: hidden;
  }
  :deep(.el-tabs__header) {
    background-color: #e1e4eb;
  }
  :deep(.el-tabs__item) {
    padding: 0 14px !important;
    border: 0;
    border-radius: 6px 6px 0px 0px;
  }
  :deep(.el-tabs__content) {
    height: calc(100% - 40px);
    box-sizing: border-box;
  }
  :deep(.el-tab-pane) {
    height: 100%;
    overflow-y: auto;
  }
}
.panel-icon {
  position: absolute;
  top: 50%;
  right: -16px;
  width: 16px;
  height: 86px;
  transform: translateY(-50%);
  z-index: 100;
  cursor: pointer;
}
.lab-right {
  margin-left: 20px;
  flex: 1;
  display: flex;
  flex-direction: column;
  height: 100%;
}
.lab-box {
  flex: 1;
  width: 100%;
  margin-top: 20px;
}
.iframe {
  width: 100%;
  height: 100%;
}
</style>
