<script setup lang="ts" generic="T extends any, O extends any">
import type { RouteLocationRaw } from 'vue-router'
import request from '~/utils/request'
// import { stepsMap } from '~/composables/steps'
import { user } from '~/store/index'

const props = defineProps<{
  id: string
}>()

const ykl_id = props.id

const server = (await request({
  url: '/yzy/kmksyjlc/detail',
  data: {
    ykl_id,
  },
})).data.one_info

const ykl_lc = Object.assign(JSON.parse(Object.assign(server.ykl_lc)), { ykl_id })
console.log('ykl_lc : ', ykl_lc)
sessionStorage.setItem('ykl_lc', JSON.stringify(ykl_lc))

const stepsReactiveMap = reactive<unknown[][][]>(ykl_lc.processList)

const steps = reactive(
  ykl_lc.ykj_yjlc === '1'
    ? [// 先上传后划块
        {
          title: '组卷考试',
          children: [
            {
              title: '出题组卷',
              children: [
                { title: '章节知识点出题', optional: true, description: '选择相应的章节知识点从题库中选取题目组成试卷' },
                { title: '智能出题', optional: true, description: '填写题型数量难易度等信息系统自动生成试卷' },
                { title: '附件出题', optional: true, description: '根据上传附件试卷进行考试' },
              ],
            },
            {
              title: '预划考号区域',
              children: [
                { title: '预划考号区域', optional: false, description: '根据试题内容格式制作相应的答题卡样式' },
                { title: '考场设置（可选）', optional: true, description: '根据学生考场分配情况上传' },
              ],
            },
            {
              title: '预划流程完成',
              children: [
                { title: '预划流程完成', optional: false, description: '试卷内容和答题卡已确认，可进行考试' },
              ],
            },
          ],
        },
        {
          title: '扫描',
          children: [
            {
              title: '答题卡扫描',
              children: [
                { title: '答题卡扫描', optional: false, description: '启动客户端扫描学生答题卡并进行识别与上传' },
              ],
            },
            {
              title: '平台接收试卷确认',
              children: [
                { title: '平台接收试卷确认', optional: false, description: '时间及试题均接收并识别入库完成' },
              ],
            },
            {
              title: '制作答题卡',
              children: [
                { title: '制作答题卡', optional: false, description: '根据试题内容格式制作相应的答题卡样式' },
              ],
            },
          ],
        },
        {
          title: '制作扫描处理',
          children: [
            {
              title: '答题卡二次扫描',
              children: [
                { title: '答题卡二次扫描', optional: false, description: '启动客户端二次扫描批阅试卷' },
              ],
            },
            {
              title: '平台接收试卷确认',
              children: [
                { title: '平台接收试卷确认', optional: false, description: '确认试卷已上传' },
              ],
            },
          ],
        },
        {
          title: '阅卷',
          children: [
            {
              title: '批阅任务分配',
              children: [
                { title: '批阅任务分配', optional: false, description: '对阅卷老师分配批阅任务' },
              ],
            },
            {
              title: '阅卷',
              children: [
                { title: '阅卷', optional: false, description: '查看批阅进度查看我的批阅任务' },
              ],
            },
          ],
        },
        {
          title: '成绩',
          children: [
            {
              title: '成绩发布',
              children: [
                { title: '成绩发布', optional: false, description: '成绩汇总发布到分析平台' },
              ],
            },
            {
              title: '修改成绩',
              children: [
                { title: '修改成绩', optional: false, description: '考试成绩发布后三天内可修改' },
              ],
            },
            {
              title: '考试关闭',
              children: [
                { title: '考试关闭', optional: false, description: '最后考试结束关闭考试' },
              ],
            },
          ],
        },
      ]
    : [// 先划块后上传
        {
          title: '组卷考试',
          children: [
            {
              title: '出题组卷',
              children: [
                { title: '章节知识点出题', optional: true, description: '选择相应的章节知识点从题库中选取题目组成试卷' },
                { title: '智能出题', optional: true, description: '填写题型数量难易度等信息系统自动生成试卷' },
                { title: '附件出题', optional: true, description: '根据上传附件试卷进行考试' },
              ],
            },
            {
              title: '制作答题卡',
              children: [
                { title: '制作答题卡', optional: false, description: '根据试题内容格式制作相应的答题卡样式' },
                { title: '考场设置（可选）', optional: true, description: '根据学生考场分配情况上传' },
              ],
            },
            {
              title: '组卷流程完成',
              children: [
                { title: '组卷流程完成', optional: false, description: '试卷内容和答题卡已确认，可进行考试' },
              ],
            },
          ],
        },
        {
          title: '扫描',
          children: [
            {
              title: '答题卡扫描',
              children: [
                { title: '连接扫描仪', optional: false, description: '启动客户端扫描学生答题卡并进行识别与上传' },
              ],
            },
            {
              title: '平台接收试卷确认',
              children: [
                { title: '平台接收试卷确认', optional: false, description: '时间及试题均接收并识别入库完成' },
              ],
            },

          ],
        },
        {
          title: '阅卷',
          children: [
            {
              title: '批阅任务分配',
              children: [
                { title: '批阅任务分配', optional: false, description: '对阅卷老师分配批阅任务' },
              ],
            },
            {
              title: '阅卷',
              children: [
                { title: '阅卷', optional: false, description: '查看批阅进度查看我的批阅任务' },
              ],
            },
          ],
        },
        {
          title: '成绩',
          children: [
            {
              title: '成绩发布',
              children: [
                { title: '成绩发布', optional: false, description: '成绩汇总发布到分析平台' },
              ],
            },
            {
              title: '修改成绩',
              children: [
                { title: '修改成绩', optional: false, description: '考试成绩发布后三天内可修改' },
              ],
            },
            {
              title: '考试关闭',
              children: [
                { title: '考试关闭', optional: false, description: '最后考试结束关闭考试' },
              ],
            },
          ],
        },
      ],
)

let gid = $ref<number>(0)
let pids = $ref<number[]>([])
// const cid = $ref(-1)
function getGid() {
  return stepsReactiveMap.findLastIndex(item => item.some(subItem => subItem.some(subSubItem => judgeStepCompleted(subSubItem))))
}

function getPids() {
  return stepsReactiveMap.map((item, idx) => (idx < gid ? 1 : 0) + item.findLastIndex(subItem => subItem.some(subSubItem => judgeStepCompleted(subSubItem))))
}
watch(() => stepsReactiveMap, (val) => {
  gid = getGid()
  pids = getPids()
}, {
  immediate: true,
  deep: true,
})

let currentStep = $ref<number>(gid)

const CardsRef = $shallowRef<Array<Array<typeof import('~/components/TheCard.vue')['default']>>>([])
const lineList: any[][][] = []

// onMounted(() => {
//   CardsRef.forEach((cards, idx) => {
//     if (idx === CardsRef.length - 1)
//       return
//     cards.forEach((card, idy) => {
//       const line = new LeaderLine(
//         card.getDom(),
//         CardsRef[idx + 1][0].getDom(),
//         {
//           path: 'grid',
//           endPlug: 'behind',
//           size: 6,
//           startSocket: 'right',
//           endSocket: 'left',
//           color: stepsReactiveMap[currentStep][idx][idy] ? '#003eee' : '#a3a3a3',
//         },
//       )
//       lineList.push(line)
//     })
//   })
// })

function handleSwitchGid(id: number) {
  currentStep = id
}

onMounted(() => {
  watch(() => currentStep, (val, old) => {
    if (old !== undefined)
      lineList[old].forEach(lines => lines.forEach(line => line?.hide('none')))
    if (lineList[val]?.length) {
      lineList[val].forEach(lines => lines.forEach(line => line?.show('none')))
    }
    else {
      nextTick(() => {
        CardsRef.forEach((cards, idx) => {
          if (idx === CardsRef.length - 1)
            return
          cards.forEach((card, idy) => {
            if (card === null || CardsRef[idx + 1][0] === null)
              return
            const line = new LeaderLine(
              card.getDom(),
              CardsRef[idx + 1][0].getDom(),
              {
                path: 'grid',
                endPlug: 'behind',
                size: 6,
                startSocket: 'right',
                endSocket: 'left',
                color: stepsReactiveMap[currentStep][idx][idy] ? '#003eee' : '#a3a3a3',
              },
            )
            line?.position()
            if (stepsReactiveMap[currentStep][idx][idy])
              document.querySelectorAll('.leader-line')[line._id as number - 1]?.classList.add('z10')

            lineList[val] = lineList[val] || []
            lineList[val][idx] = lineList[val][idx] || []
            lineList[val][idx][idy] = line
          })
        })
      })
    }
  }, {
    immediate: true,
  })
})

const router = useRouter()

function routerPush(path: RouteLocationRaw) {
  router.push(path)
}
function windowPushState(path: string) {
  window.open(`${location.origin}/${path}`, '_self')
}

function handleValidTask(currentStep: number, idx: number, idy: number) {
  let lastIdx = idx
  let lastStep = currentStep
  const lastTasks = idx > 0 ? stepsReactiveMap[currentStep][lastIdx = idx - 1] : currentStep > 0 ? stepsReactiveMap[lastStep = currentStep - 1][lastIdx = stepsReactiveMap[currentStep - 1].length - 1] : []

  if (lastTasks.every((item, idz) => {
    if (steps[lastStep].children[lastIdx].children[idz].optional)
      return true
    else
      return !!item
  })) {
    sessionStorage.setItem('StepId', JSON.stringify({ gid: currentStep, pid: idx, cid: idy }))
    return true
  }
  else {
    ElMessage({
      message: '请先完成之前的任务',
      type: 'warning',
      grouping: true,
    })
    return false
  }
}

function beforeClickTask(gid: number, pid: number, idy: number) {
  const continueDoTask = true
  if (!continueDoTask) {
    ElMessage({
      message: '无权操作',
      type: 'warning',
      grouping: true,
    })
  }
  else {
    return handleValidTask(gid, pid, idy)
  }
  return continueDoTask
}

function judgeTaskCanClick(gid: number, pid: number, idy: number) {
  const continueDoTask = true
  if (!continueDoTask) {
    return false
  }
  else {
    let lastIdx = pid
    let lastStep = currentStep
    const lastTasks = pid > 0 ? stepsReactiveMap[currentStep][lastIdx = pid - 1] : currentStep > 0 ? stepsReactiveMap[lastStep = currentStep - 1][lastIdx = stepsReactiveMap[currentStep - 1].length - 1] : []

    if (lastTasks.every((item, idz) => {
      if (steps[lastStep].children[lastIdx].children[idz].optional)
        return true
      else
        return !!item
    }))
      return true
    else
      return false
  }
}

function judgeStepCompleted(val: unknown) {
  return (!!val) || (typeof val === 'object' && !!(val?.value))
}

function handleCompleteTask(gid: number, pid: number, cid: number, val?: unknown) {
  const _ykl_lc_ = JSON.parse(sessionStorage.getItem('ykl_lc')!)
  _ykl_lc_.processList[gid][pid][cid] = val || 1
  request({
    url: '/yzy/kmksyjlc/save',
    data: {
      ykl_id,
      yk: {
        ykl_lc: JSON.stringify(_ykl_lc_),
      },
    },
  }).then((res) => {
    if (res.code === '1') {
      ElMessage({
        message: '操作成功',
        type: 'success',
        grouping: true,
      })
      sessionStorage.setItem('ykl_lc', JSON.stringify(_ykl_lc_))

      stepsReactiveMap[gid][pid][cid] = val || 1
    }
  }).catch(() => {
    ElMessage({
      message: '操作失败',
      type: 'error',
      grouping: true,
    })
  })
}

function handleJumpTask(gid: number, pid: number, idy: number) {
  // todo: 验证任务是否完成
  if (judgeStepCompleted(stepsReactiveMap[gid][pid][idy])) {
    return ElMessage({
      message: '该任务已完成',
      type: 'warning',
      grouping: true,
    })
  }
  // stepsReactiveMap[gid][pid][idy] = 1
  handleCompleteTask(gid, pid, idy)
  if (pid === stepsReactiveMap[gid].length - 1)
    return
  const line = lineList[gid][pid][idy]
  line.setOptions({ color: '#003eee' })
  document.querySelectorAll('.leader-line')[line._id - 1]?.classList.add('z10')
}

onBeforeRouteLeave(() => {
  lineList.forEach(lines => lines.forEach(line => line.forEach(l => l?.hide('none'))))
})

function handleCompleteTaskAuto() {
  const { gid, pid, cid } = JSON.parse(sessionStorage.getItem('StepId')!)
  handleJumpTask(gid, pid, cid)
}

const TaskEventMap: { [key: string]: () => void } = {
  '附件出题': () => {
    routerPush({ name: 'process-fjct-ze_id-zs_id', params: { ze_id: ykl_lc.ze_id, zs_id: ykl_lc.zs_id } })
  },
  '预划考号区域': () => {
    windowPushState(`${window.GLOBAL_CONFIG.base}/liankao/dtk/index.html`)
  },
  '制作答题卡': () => {
    windowPushState(`${window.GLOBAL_CONFIG.base}/liankao/dtk/index.html`)
  },
  '考场设置（可选）': () => {
    windowPushState(`${window.GLOBAL_CONFIG.base}/exam-room-set.html?id=${ykl_lc.ze_id}`)
  },
  // 先上传后划块
  '答题卡扫描': () => {
    window.open(`BozeduYuejuan://${user.value.token},${ykl_lc.ze_id},${window.GLOBAL_CONFIG.yzy},upload_papers`, '_blank')
    handleCompleteTaskAuto()
  },
  '答题卡二次扫描': () => {
    window.open(`BozeduYuejuan://${user.value.token},${ykl_lc.ze_id},${window.GLOBAL_CONFIG.yzy},review_papers`, '_blank')
    handleCompleteTaskAuto()
  },
  // 先划块后上传 老流程
  '启动客户端': () => {
    window.open(`BozeduYuejuan://${user.value.token},${ykl_lc.ze_id},${window.GLOBAL_CONFIG.yzy}`, '_blank')
    handleCompleteTaskAuto()
  },
  '平台接收试卷确认': () => {
    handleCompleteTaskAuto()
  },
  '批阅任务分配': () => {
  },
  '阅卷': () => {
  },
  '成绩发布': () => {
    ElMessageBox.confirm('选择实时发布时需等待浏览器处理结束；正常发布则无需等待', '选择发布成绩的方式', {
      confirmButtonText: '实时发布',
      cancelButtonText: '正常发布',
      type: 'info',
    }).then(() => {
      request({
        url: '/yzy/kmksyjlc/save',
        data: {
          ykl_id,
          yk: {
            ykl_lc: JSON.stringify({
              ...ykl_lc,
              ykl_lc_cjfb: 1,
            }),
          },
        },
      }).then((res) => {
        if (res.code === '1') {
          ElMessage({
            message: '操作成功',
            type: 'success',
            grouping: true,
          })
          ykl_lc.ykl_lc_cjfb = 1
        }
      }).catch(() => {
        ElMessage({
          message: '操作失败',
          type: 'error',
          grouping: true,
        })
      })
    })
  },
  '考试关闭': () => {
    ElMessageBox({
      title: '提示',
      message: '确定要关闭考试吗？',
      type: 'warning',
      showCancelButton: true,
      confirmButtonText: '确定',
      cancelButtonText: '取消',
    }).then(() => {
      const { gid, pid, cid } = JSON.parse(sessionStorage.getItem('StepId')!)
      handleJumpTask(gid, pid, cid)
    })
  },
}
</script>

<template>
  <div class="w-full min-h-screen flex flex-col bg-white">
    <NavHeader />
    <bread-crumb />
    <div class="flex-auto w-1200px m-auto">
      <div class="flex flex-auto justify-start divide-x-4 divide-blue-700">
        <div class="h-full w-220px">
          <el-steps direction="vertical" :active="gid">
            <el-step
              v-for="({ title, children }, idx) in steps" :key="title" class="cursor-pointer hover:bg-light-600"
              :class="idx === currentStep && 'bg-light-400'" @click="handleSwitchGid(idx)"
            >
              <template #title>
                <div class="mb-4 font-normal">
                  {{ title }}
                </div>
              </template>
              <template #description>
                <el-steps direction="vertical" :space="40" :active="pids[idx]">
                  <el-step v-for="({ title }) in children" :key="title">
                    <template #title>
                      <div class="font-normal">
                        {{ title }}
                      </div>
                    </template>
                  </el-step>
                </el-steps>
              </template>
            </el-step>
          </el-steps>
        </div>
        <div class="flex-auto p-4">
          <div class="h-full flex justify-between">
            <div
              v-for="(step, idx) in steps[currentStep].children " :key="idx"
              class="h-full flex flex-col justify-evenly"
            >
              <the-card
                v-for="(task, idy) in step.children " :key="idy"
                :ref="el => { CardsRef[idx] = CardsRef[idx] || []; CardsRef[idx][idy] = el as any }" :title="task.title"
                :description="task.description" :completed="judgeStepCompleted(stepsReactiveMap[currentStep][idx][idy])"
              >
                <template #operate>
                  <template v-if="task.title === '预划考号区域'">
                    <div
                      class="min-w-60px cursor-pointer rounded bg-light-50 py-3px text-center text-xs"
                      @click="beforeClickTask(currentStep, idx, idy) && TaskEventMap[task.title]()"
                    >
                      {{ judgeStepCompleted(stepsReactiveMap[currentStep][idx][idy]) ? '已经完成' : '立即开始' }}
                    </div>
                    <div
                      class="min-w-60px cursor-pointer rounded bg-light-50 py-3px text-center text-xs"
                      @click="beforeClickTask(currentStep, idx, idy) && handleJumpTask(currentStep, idx, idy)"
                    >
                      {{ '跳过' }}
                    </div>
                  </template>
                  <template v-else>
                    <div
                      class="min-w-60px cursor-pointer rounded bg-light-50 py-3px text-center text-xs"
                      @click="beforeClickTask(currentStep, idx, idy) && (TaskEventMap[task.title] ? TaskEventMap[task.title]() : handleCompleteTaskAuto())"
                    >
                      {{ judgeStepCompleted(stepsReactiveMap[currentStep][idx][idy]) ? '已经完成' : '立即开始' }}
                    </div>
                  </template>
                </template>

                <template #tip>
                  <template v-if="task.title === '成绩发布'">
                    <div class="mt-2 flex flex-col items-start px-1 text-xs space-y-1" style="--el-font-size-base:10px">
                      <xgstda :disabled="!judgeTaskCanClick(currentStep, idx, idy)" />
                      <szcjckqx :disabled="!judgeTaskCanClick(currentStep, idx, idy)" />
                      <bjqk :disabled="!judgeTaskCanClick(currentStep, idx, idy)" />
                    </div>
                  </template>
                </template>
              </the-card>
            </div>
          </div>
        </div>
      </div>
    </div>
    <commonFooter />
  </div>
</template>

<style scoped>
:deep(.el-step:last-of-type .el-step__line) {
  display: block;
}

:deep(.el-step__description .el-step:last-of-type .el-step__line) {
  display: none;
}
</style>
