<script setup lang="ts">
import homeWorkApi from '@/api/system/homeWork'
import globalApi from '@/api/global'
import { debounce, XMessage } from '@/hooks'
// import Question from './components/Question.vue'
import dayjs from 'dayjs'
import { useRoute, useRouter, onBeforeRouteLeave } from 'vue-router'
import { $XXL, getDurationText } from '@/utils'
import { loading } from '@/components/mj/mj-loading'
import { userStore } from '@/stores'
import type { IQuestion } from '@/types/question'
import { globalBack } from '@/router'
import { dialog } from '@/components/mj/mj-dialog'
defineOptions({
  name: 'HomeWorkDoWork',
})

type PaperInfo = {
  name: string
  costTime: number
  currentTitleId: string
}

const { token } = userStore()

const router = useRouter()
const route = useRoute()

const pageLoading = ref(true)
// 是否为答题页面  0 答题  1 查看作业结果
const reportFlag = ref(0)

// 题目列表
interface WorkQuestion extends IQuestion {
  /** 还未做过这道题 */
  unLook: boolean
  /** 上传中 */
  uploadLoading: boolean
}
const paperList = ref<WorkQuestion[]>([])
// 试卷信息
const paperInfo = ref<PaperInfo>({} as PaperInfo)
const isDeadline = ref(false)

// 当前所在题目
const activeIdx = ref(-1)
const indicatorRef = ref()

// 切换题目
async function switchQuestion(idx?: number) {
  if (idx === activeIdx.value) return
  // 最后一题的索引
  const lastIdx = paperList.value.length - 1
  // 是否为点击下一题
  let nextQuestion = false
  if (idx !== undefined) {
    activeIdx.value = idx
  } else if (activeIdx.value < lastIdx) {
    // 点击下一题
    activeIdx.value++
    nextQuestion = true
  } else if (activeIdx.value === lastIdx) {
    if (!reportFlag.value) {
      // 提交作业
      if (paperList.value.some(i => i.uploadLoading)) {
        return XMessage.error('上传中，请稍后～')
      }
      let tips = '请确认是否提交本次作业'
      if (paperList.value.some(i => !i.submitAnswer && !i.submitAnswerPic)) {
        tips = '还有题目未作答，确定要提交答案吗？'
      }
      dialog.show({
        content: tips,
        ok: handleSubmitPaper,
      })
    }
  }
  if (!reportFlag.value) {
    paperList.value[activeIdx.value].unLook = false

    // 因为服务器返回的题目顺序是打乱的，所以上报当前正在查看的题目已经米有意义
    // 每次切换题目调一次接口
    // const { id, jobStuId } = paperList.value[activeIdx.value]

    // submitCurrentTitleId({
    //     jobStuId,
    //     currentTitleId: id,
    //     costTime: paperInfo.value.costTime * 1000
    // })
  }

  // 点击下一题时下方往后滑动
  await nextTick()
  if (nextQuestion && indicatorRef.value) {
    indicatorRef.value.scrollLeft += 104
  }
}
const debounceChange = debounce(switchQuestion, 200)

function getResourceType() {
  return route.query.resource
}

// 上传前
function beforeUpload(rawFile: any) {
  const fileType = ['image/jpeg', 'image/png']
  if (!fileType.includes(rawFile.type)) {
    XMessage.error('上传格式不正确，只支持JPG/PNG')
    return false
  }
  if (rawFile.size / 1024 / 1024 > 5) {
    XMessage.error('图片过大')
    return false
  }
  return true
}
// 上传
async function uploadFile(options: anyObj) {
  const currentTitleId = paperList.value[activeIdx.value].jobStuTittleId
  paperList.value[activeIdx.value].uploadLoading = true

  try {
    let path = ''
    if (options.isAndroid) {
      if (options.submitAnswerPicOriginal) {
        const res = await $XXL.uploadFile({
          url: `${import.meta.env.VITE_SERVER_URL}/sysFileInfo/tenUploadAll`,
          header: {
            Authorization: token,
          },
          filePath: options.file,
          fileKey: 'file',
        })
        path = res.url
      }
    } else {
      const formData = new FormData()
      formData.append('file', options.file)
      const { data: res } = await globalApi.uploadFile(formData)
      path = res.data.filePath
    }
    if (options.submitAnswerPicOriginal) {
      handleSubmitSingle({
        submitAnswerPic: path,
        submitAnswerPicOriginal: options.submitAnswerPicOriginal,
        id: currentTitleId,
        isAndroid: options.isAndroid || 0,
      })
    } else {
      if (options.isAndroid) {
        handleSubmitSingle({
          submitAnswerPic: '',
          submitAnswerPicOriginal: '',
          id: currentTitleId,
          isAndroid: 1,
        })
      } else {
        handleSubmitSingle({ filePath: path, id: currentTitleId })
      }
    }
  } catch (error) {
    XMessage.error('网络异常，请检查网络～')
  }

  const currentIdx = paperList.value.findIndex(i => i.jobStuTittleId === currentTitleId)
  if (currentIdx !== -1) {
    paperList.value[currentIdx].uploadLoading = false
    paperList.value[currentIdx].isAndroid = options.isAndroid
  }
}

// 提交每道题目
async function handleSubmitSingle(answer: any) {
  if (reportFlag.value) return
  const params: anyObj = {
    id: answer.id,
    isAndroid: answer.isAndroid,
  }
  if (answer.filePath) {
    // 添加图片
    const idx = paperList.value.findIndex(i => i.jobStuTittleId === answer.id)
    if (idx !== -1) {
      const safeUrl = String(answer.filePath || '')
        .replace(/[`]/g, '')
        .replace(/http:\/\//gi, 'https://')
        .trim()
      const q = paperList.value[idx]
      const isHandDrawn =
        q?.autoMarkFlag === 0 &&
        (q?.titleChannelTypeName === '填空题' ||
          (q?.subjectId === 3 && q?.titleChannelTypeName === '解答题'))
      const submitPic = isHandDrawn
        ? safeUrl
        : q.submitAnswerPic || ''
          ? `${q.submitAnswerPic},${safeUrl}`
          : safeUrl

      paperList.value[idx].submitAnswerPic = submitPic
      params.submitAnswerPic = submitPic
    }
  } else if (answer.submitAnswer) {
    paperList.value[activeIdx.value].submitAnswer = answer.submitAnswer
    params.submitAnswer = answer.submitAnswer
  } else if (answer.delUrl) {
    // 删除图片
    const picList = paperList.value[activeIdx.value].submitAnswerPic.split(',') || []
    const idx = picList.indexOf(answer.delUrl)
    picList.splice(idx, 1)
    params.submitAnswerPic = picList.join(',')
    paperList.value[activeIdx.value].submitAnswerPic = params.submitAnswerPic
  } else if (answer.submitAnswerPic) {
    // 替换图片
    const idx = paperList.value.findIndex(i => i.jobStuTittleId === answer.id)
    paperList.value[idx].submitAnswerPic = answer.submitAnswerPic
    paperList.value[idx].submitAnswerPicOriginal = answer.submitAnswerPicOriginal
    params.submitAnswerPic = answer.submitAnswerPic
    params.submitAnswerPicOriginal = answer.submitAnswerPicOriginal
  } else if (answer.submitAnswerPic === '' && answer.isAndroid) {
    // 清空图片
    const idx = paperList.value.findIndex(i => i.jobStuTittleId === answer.id)
    paperList.value[idx].submitAnswerPic = ''
    paperList.value[idx].submitAnswerPicOriginal = ''
    params.submitAnswerPic = ''
    params.submitAnswerPicOriginal = ''
  }

  // 单选题直接跳转下一题
  if (answer.toNext && activeIdx.value < paperList.value.length - 1) setTimeout(switchQuestion, 50)

  await homeWorkApi.submitAnswer(params)
}

let timeout: any
function startTime() {
  clearInterval(timeout)
  timeout = setInterval(() => {
    paperInfo.value.costTime++
  }, 1000)
}
const timeFilter = computed(() => getDurationText(paperInfo.value.costTime))

function handleTime(type: 0 | 1) {
  if (type) {
    startTime()
  } else {
    clearInterval(timeout)
  }
}

async function handleSubmitPaper() {
  clearInterval(timeout)
  const { jobId, jobStuId } = paperList.value[activeIdx.value]

  loading.show('正在提交中...')
  try {
    await homeWorkApi.submitPaper({
      id: jobStuId,
      jobId,
      costTime: paperInfo.value.costTime * 1000,
    })
    // 标记为可以离开
    leave.value = true
    // 成功后跳转
    router.replace('/system/homeWork/reports/' + jobId)
  } finally {
    loading.hide()
  }
}

// 题目是否有提交过答案
function hasSubmitAnswer(question: WorkQuestion) {
  return question.submitAnswer || question.submitAnswerPic || question.submitAnswerPicOriginal
}

// 获取试卷信息
async function getPaper(options: any) {
  // 请求试卷数据
  const { data } = await homeWorkApi.getJobTittle(options)
  paperInfo.value = {
    name: data.paperName,
    costTime: data.costTime / 1000,
    currentTitleId: data.currentTitleId,
  }
  const oldQuestions = data.tjobStuVoList
  // 是否到了作业的截止时间
  isDeadline.value = dayjs().isAfter(data.submitEndTime)
  if (!reportFlag.value) {
    // 将已经答过的题目放在前面
    const answeredQuestions: WorkQuestion[] = []
    const unansweredQuestions: WorkQuestion[] = []
    let idx = 0
    for (const question of oldQuestions) {
      if (hasSubmitAnswer(question)) {
        answeredQuestions.push(question)
        idx += 1
      } else {
        question.unLook = true
        unansweredQuestions.push(question)
      }
    }

    paperList.value = [...answeredQuestions, ...unansweredQuestions]
    return Math.min(idx, paperList.value.length - 1)
  } else {
    paperList.value = oldQuestions
    return 0
  }
}

const leave = ref(true)
onBeforeRouteLeave((to, _from, next) => {
  if (leave.value || to.path === '/login' || reportFlag.value) {
    return next()
  }
  next(false)

  dialog.show({
    content: '还没有提交作业，是否确认退出？',
    ok: () => {
      leave.value = true
      globalBack()
    },
  })
})

onMounted(async () => {
  const options: anyObj = route.query || {}
  if (!options?.id) {
    // 没有试卷的id
    globalBack()
    return
  }

  // 是否为报告
  reportFlag.value = Number(options.reportFlag)

  // 请求数据
  pageLoading.value = true
  const currentIdx = await getPaper(options)
  pageLoading.value = false

  // 数据记载完毕后，就不准直接离开
  leave.value = false

  // 切换题目
  switchQuestion(options?.idx ? Number(options?.idx) : currentIdx)

  if (!reportFlag.value) {
    startTime()
  }

  await nextTick()
  if (indicatorRef.value) {
    indicatorRef.value.scrollLeft = ((options?.idx ? Number(options?.idx) : currentIdx) - 1) * 104
  }

  // 设置屏幕常亮
  $XXL.setScreenOn(1)
})

onUnmounted(() => {
  paperInfo.value.costTime = 0
  activeIdx.value = 0
  paperList.value = []
  paperInfo.value = {} as PaperInfo

  // showQuesImgDia.value = false;
  // quesImg.value = '';
  // showDia.value = false
  // leaveFlag = false;
  clearInterval(timeout)
})
</script>
<template>
  <div class="dowork g-main-bg">
    <div class="title-box">
      <div class="title" :data-content="paperInfo.name">
        {{ paperInfo.name }}
      </div>
    </div>
    <div class="top">
      <BackBar />

      <div v-if="!pageLoading" class="top-timeout">
        <Icon name="clock" width="48"></Icon>
        {{ timeFilter }}
      </div>
    </div>
    <div v-if="!pageLoading" class="main">
      <div class="main-box">
        <div class="book-box">
          <div class="book">
            <Question
              :data="paperList[activeIdx]"
              :idx="activeIdx + 1"
              :is-homework="true"
              :total="paperList.length"
              :reportFlag="reportFlag"
              :isDeadline="isDeadline"
              :resource-type="getResourceType()"
              :uploadFile="uploadFile"
              :beforeUpload="beforeUpload"
              @submit="handleSubmitSingle"
              @handleTime="handleTime"
            ></Question>
          </div>
        </div>
        <div class="bottom">
          <div ref="indicatorRef" :class="{ indicator: true, hidden_scroll: true }">
            <div
              v-for="(i, idx) in paperList"
              v-show="!i.unLook"
              :key="i.id"
              :class="{
                'indicator-item': true,
                pointer: true,
                active: activeIdx === idx,
                success: isDeadline && reportFlag && i.markFlag,
                error: isDeadline && reportFlag && !i.markFlag && i.titleStatus === 3,
                empty: !i.submitAnswer && !i.submitAnswerPic,
              }"
              @click="switchQuestion(idx)"
            >
              {{ idx + 1 }}
            </div>
          </div>
          <Btn
            v-if="!reportFlag"
            class="btn"
            type="success"
            width="192"
            height="80"
            size="32"
            @click="debounceChange()"
          >
            {{ activeIdx < paperList.length - 1 ? '下一题' : '提交' }}
          </Btn>
        </div>
      </div>
    </div>
    <mj-loading v-else v-model="pageLoading" :fullscreen="true" text="正在加载试卷中..." />
  </div>
</template>
<style scoped lang="scss">
$filter: brightness(0) saturate(0) invert(0) sepia(0) hue-rotate(30deg);
.dowork {
  position: relative;
  height: 100vh;
  overflow: hidden;
  box-sizing: border-box;

  .title-box {
    position: absolute;
    left: 0;
    right: 0;
    top: 2.92vh;
    .title {
      color: #fff;
      text-shadow: 0 0.17vh 0.17vh rgba(0, 0, 0, 0.25);
      font-family: $font-special;
      font-size: 4vh;
      font-style: normal;
      font-weight: 400;
      line-height: 6vh; /* 150% */
      text-align: center;
      letter-spacing: 10px;
      @include font-stroke($font-color, 6px);
    }
  }

  .top {
    padding: 2.67vh 64px 0;
    position: relative;
    z-index: 1;
    display: flex;
    justify-content: space-between;
    align-items: center;

    &-timeout {
      color: $font-color;
      text-align: center;
      text-shadow: 0 0.17vh 0.17vh rgba(0, 0, 0, 0.25);
      font-family: $font-special;
      font-size: 2.67vh;
      height: 4vh;
      line-height: 4vh;
      display: flex;
      .x-icon {
        margin-right: 10px;
        filter: $filter;
      }
    }
  }
  .main {
    box-sizing: border-box;
    padding: 0 32px;
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    &-box {
      position: relative;
      top: 10.5vh;
    }
    .book-box {
      position: relative;
      height: 80vh;
      padding-top: 1.25vh;
    }
    .book {
      box-sizing: border-box;
      position: relative;
      z-index: auto;
      height: 80vh;
      flex-shrink: 0;
      border-radius: 3.33vh;
      padding-bottom: 5.83vh;
    }
  }
  .bottom {
    display: flex;
    align-items: center;
    width: 100%;
    padding: 0 32px;
    .indicator {
      flex: 1;
      display: flex;
      overflow-x: auto;
      padding: 0.83vh 0;

      &-item {
        box-sizing: border-box;
        width: 80px;
        height: 6.67vh;
        background: #bed5fe;
        // border: 4px solid #fff;
        border-radius: 50%;
        margin-right: 24px;
        color: $font-color;
        text-align: center;
        font-family: $font-special;
        font-size: 3.33vh;
        font-style: normal;
        font-weight: 400;
        line-height: 6.67vh; /* 150% */
        text-align: center;
        flex-shrink: 0;
        box-shadow: 0 0.33vh 0.33vh 0 rgba(0, 0, 0, 0.25);
        &:last-child {
          margin-right: 0;
        }
        &.error {
          background: #febebf;
          border-color: #f00809;
          color: #f00809;
        }
        &.success {
          background: #ddff8c;
          border-color: #8ecc00;
          color: #8ecc00;
        }
        &.empty {
          background: #cccccc;
          color: #ffffff;
          border-color: #aaa;
        }
        &.active {
          background: #ebf1fd;
          border: 0.33vh solid #7eacfe;
          line-height: 6vh;

          &.empty {
            color: #7eacfe;
          }
        }
      }
    }
    .btn {
      margin-left: 62px;
    }
  }
}
</style>
