<script setup lang="ts" generic="T extends any, O extends any">
// import request from "~/request/request"

import { Plus, Minus } from '@element-plus/icons-vue'
import { ebookDialogVisible, requestEbookList, ebookSelectedList, ebookList } from '~/composables/ebook'
import { docDialogVisible, requestDocList, docList, docSelectedList } from '~/composables/doc'
import { workDialogVisible, requestWorkList, workList } from '~/composables/work'
import { discussList, requestDiscussList } from '~/composables/discuss'
import { practiceList, requestPracticeList, practiceDialogVisible, sendPractice } from '~/composables/practice'



// const router = useRouter()

const yj_id = 33952

// request({
//   url: '/ybk/hdd/index',
//   params: {
//     yj_id,
//     hdd_type: 2
//   }
// }).then(res => {
//   console.log('res : ', res)
// })

type TCollapseBar = typeof import('./src/components/collapse-bar.vue')['default']


const wrapperRef = shallowRef<HTMLElement | undefined>()
const boardRef = shallowRef<HTMLCanvasElement | undefined>()
const barRef = shallowRef<TCollapseBar | undefined>()


const PenDefaultConfig = {
  white: {
    color: '#000',
    lineWidth: 2,
  },
  black: {
    color: '#fff',
    lineWidth: 2,
  },
  green: {
    color: '#fff',
    lineWidth: 2,
  }
}
const currentBoard = ref('黑板')
const currentPen = ref<keyof typeof PenDefaultConfig>('black')

const PenConfig = reactive({
  color: PenDefaultConfig[currentPen.value].color,
  lineWidth: 2,
  eraserLineWidth: 20,
})

const CanvasData: ImageData[] = []

const useMode = ref(0)
let ctx: CanvasRenderingContext2D
onMounted(() => {
  const rect = wrapperRef.value?.getBoundingClientRect()!
  boardRef.value?.setAttribute('width', `${rect?.width}px`)
  boardRef.value?.setAttribute('height', `${rect?.height}px`)

  ctx = boardRef.value?.getContext('2d', { willReadFrequently: true })!

  CanvasData.push(ctx.getImageData(0, 0, rect?.width, rect?.height))

  let isDrawing = false
  boardRef.value?.addEventListener('mousedown', (e) => {
    if (useMode.value !== 0 && useMode.value !== 1) return
    isDrawing = true
    const x = e.clientX - rect?.left
    const y = e.clientY - rect?.top
    ctx?.beginPath()
    ctx?.moveTo(x, y)
    ctx.lineWidth = PenConfig.lineWidth
    ctx.strokeStyle = PenConfig.color

  })
  boardRef.value?.addEventListener('mousemove', (e) => {
    if (useMode.value !== 0 && useMode.value !== 1) return
    if (!isDrawing) return
    const x = e.clientX - rect?.left
    const y = e.clientY - rect?.top
    ctx?.lineTo(x, y)
    ctx?.stroke()
  })
  boardRef.value?.addEventListener('mouseup', () => {
    if (useMode.value !== 0 && useMode.value !== 1) return
    isDrawing = false
    CanvasData.push(ctx.getImageData(0, 0, rect?.width, rect?.height))
  })
})

async function handleBarSelect(idx: number) {
  console.log('handleBarSelect : ', idx)

  if (idx === useMode.value && idx === 1) {
    return
  }
  useMode.value = idx
  switch (idx) {
    case 0:
      ctx.globalCompositeOperation = 'source-over';
      PenConfig.lineWidth = PenDefaultConfig[currentPen.value].lineWidth
      PenConfig.color = PenDefaultConfig[currentPen.value].color
      break;
    case 1:
      ctx.globalCompositeOperation = 'destination-out';

      PenConfig.lineWidth = PenConfig.eraserLineWidth
      barRef.value?.setSubcollapsed()
      break;
    case 2:
      timerDialogVisible.value = true
      break;
    case 3:
      break;
    case 4:
      break;
    case 5:
      await requestDiscussList({ yj_id })
      barRef.value?.setSubcollapsed()
      break;
    case 6:
      await requestPracticeList({ yj_id })
      barRef.value?.setSubcollapsed()
      break;
    case 7:
      await requestWorkList()
      workDialogVisible.value = true
      break;
    default:
      break;
  }
}

function undo() {
  if (CanvasData.length > 1) {
    CanvasData.pop()
    ctx.putImageData(CanvasData[CanvasData.length - 1], 0, 0)
  } else {
    reset()
  }
}

function reset() {
  const rect = wrapperRef.value?.getBoundingClientRect()!
  ctx.clearRect(0, 0, rect?.width, rect?.height)

  CanvasData.splice(0)
}

const timer = ref<null | NodeJS.Timeout>(null)
const timerDialogVisible = ref(false)
const timerList = ref<number[]>([0, 0, 0, 0])

function handleTimePlus(i: number) {
  if (i === 3 && timerList.value[2] >= 5) {
    return
  }
  timerList.value[i - 1] < 9 && timerList.value[i - 1]++
}

function handleTimeMinus(i: number) {
  timerList.value[i - 1] > 0 && timerList.value[i - 1]--
}

function startTimer() {
  timer.value = setInterval(() => {
    if (timerList.value[3] === 0) {
      if (timerList.value[2] === 0) {
        if (timerList.value[1] === 0) {
          if (timerList.value[0] === 0) {
            clearInterval(timer.value as NodeJS.Timeout)
            timer.value = null
            return
          }
          timerList.value[0]--
          timerList.value[1] = 10
        }
        timerList.value[1]--
        timerList.value[2] = 6
      }
      timerList.value[2]--
      timerList.value[3] = 10
    }
    timerList.value[3]--
  }, 1000)
}

function pauseTimer() {
  clearInterval(timer.value as NodeJS.Timeout)
  timer.value = null
}


function handleNavSelect(idx: number) {
  console.log('handleNavSelect : ', idx)
  switch (idx) {
    case 0:
      boardDialogVisible.value = true
      break;
    case 1:
      requestEbookList()
      ebookDialogVisible.value = true
      break;
    case 2:
      requestDocList({ yj_id })
      docDialogVisible.value = true
      break;
    default:
      break;
  }
}


const boardDialogVisible = ref(false)

function updateBoardConfig() {
  const currentBoardConfig = BoardMap[currentBoard.value]
  currentPen.value = currentBoardConfig.color
  const rect = wrapperRef.value?.getBoundingClientRect()!

  CanvasData.splice(0)
  PenConfig.color = PenDefaultConfig[currentPen.value].color

  ctx.clearRect(0, 0, rect?.width, rect?.height)

}


type T_title = string
const BoardMap: Record<T_title, {
  color: keyof typeof PenDefaultConfig,
  title: T_title,
  image?: string
}> = {
  '黑板': {
    color: 'black',
    title: '黑板',
  },
  '白板': {
    color: 'white',
    title: '白板'
  },
  '绿板': {
    color: 'green',
    title: '绿板'
  },
  '米字格': {
    color: 'white',
    title: '米字格',
    image: '/mipmap/sc_board_mzg.png'
  },
  '拼音田字格': {
    color: 'white',
    title: '拼音田字格',
    image: '/mipmap/sc_board_pytzg.png'
  },
  '四线格': {
    color: 'white',
    title: '四线格',
    image: '/mipmap/sc_board_sxg.png'
  },
  '田字格': {
    color: 'white',
    title: '田字格',
    image: '/mipmap/sc_board_tzg.png'
  },
  '五线谱': {
    color: 'white',
    title: '五线谱',
    image: '/mipmap/sc_board_wxp.png'
  },
  '坐标系': {
    color: 'white',
    title: '坐标系',
    image: '/mipmap/sc_board_zbx.png'
  },
  '足球场': {
    color: 'white',
    title: '足球场',
    image: '/mipmap/sc_board_zqc.png'
  },
  '篮球场': {
    color: 'white',
    title: '篮球场',
    image: '/mipmap/sc_board_lqc.png'
  }
}


</script>

<template>
  <div ref="wrapperRef" class="relative h-full w-full flex justify-center items-center overflow-hidden select-none">
    <div class="absolute z-0 w-full h-full flex justify-center items-center"
      :style="{ background: BoardMap[currentBoard].color }">
      <img v-if="BoardMap[currentBoard].image" :src="BoardMap[currentBoard].image" class="w-full object-cover" />
    </div>
    <canvas ref="boardRef" class="absolute z-10"></canvas>
    <collapse-nav @select="handleNavSelect"></collapse-nav>
    <collapse-bar ref="barRef" @select="handleBarSelect">
      <div flex v-show="useMode === 1">
        <div class=" flex flex-col items-center justify-around  h-72px b-r b-r-dark-50 pr-12px mr-4px">
          <div class="h-26px w-120px">
            <el-slider v-model="PenConfig.eraserLineWidth" :step="1" :min="1" :max="40" />
          </div>
          <div class="text-xs tracking-wider">板擦大小</div>
        </div>
        <collapse-item title="撤销" icon="/mipmap/sc_erase_undo.png" @click="undo" />
        <collapse-item title="清空" icon="/mipmap/sc_erase_clear.png" @click="reset" />
      </div>
      <div flex v-show="useMode === 5">
        <collapse-item v-for="({ yhd_name }) in discussList" :title="yhd_name" icon="/mipmap/sc_bottom_discuss.png" />
      </div>
      <div flex v-show="useMode === 6">
        <collapse-item v-for="({ yhd_name, hdd_content }) in practiceList" :title="yhd_name"
          icon="/mipmap/sc_bottom_practice.png" @click="handleClickPractice(hdd_content)" />
      </div>

      <el-dialog v-model="practiceDialogVisible" title="随堂小练" fullscreen>
        <div class="h-92vh flex flex-col">
          <div class="flex-auto overflow-y-auto">
            <div class="mb-20px flex html_block" v-for="({ hq_content }, idx) in practiceDialogList">
              <span mr-2>{{ idx + 1 }}.</span>
              <div v-html="hq_content"></div>
            </div>
          </div>
          <div class="px-16 pt-10 flex justify-end items-end">
            <el-button type="primary" @click="sendPractice" size="large">发送</el-button>
          </div>
        </div>
      </el-dialog>

    </collapse-bar>
  </div>

  <el-dialog v-model="timerDialogVisible" title="计时器">
    <div class="flex space-x-4 items-center justify-center h-200px">
      <div v-for="i in 4" :style="{ order: i * 2 }">
        <el-button v-if="!timer" :icon="Plus" @click="handleTimePlus(i)"></el-button>
        <div class="text-center w-46px text-50px font-bold h-100px lh-100px">{{ timerList[i - 1] }}</div>
        <el-button v-if="!timer" :icon="Minus" @click="handleTimeMinus(i)"></el-button>
      </div>
      <div class="text-center w-46px text-50px font-bold h-100px  lh-100px order-5">:</div>
    </div>
    <div class="flex space-x-4 items-center justify-center mt-20px">
      <el-button @click="startTimer">开始</el-button>
      <el-button @click="pauseTimer">暂停</el-button>
    </div>
  </el-dialog>

  <el-dialog v-model="workDialogVisible" fullscreen>
    <div class="grid! grid-cols-4 gap-8 mt-2vh h-90vh overflow-y-auto pr-4">
      <div v-for="({ zhkt_zpzs_files: { zzf_id, zzf_name, zzf_datetime, zzf_ext, zzf_file } }) in workList"
        :value="zzf_id">
        <div class="shadow-lg h-260px flex flex-col justify-center items-center rounded-16px overflow-hidden">
          <div h-180px w-full @click="downloadFile(zzf_file, zzf_name)">
            <img v-if="getFileType(zzf_ext) === 'image'" :src="zzf_file" class="w-full h-full object-cover" />
            <img v-else-if="getFileType(zzf_ext) === 'music'" src="/mipmap/icon_workshow_music.png"
              class="w-full h-full object-cover" />
            <img v-if="getFileType(zzf_ext) === 'video'" src="/mipmap/icon_workshow_video.png"
              class="w-full h-full object-cover" />
          </div>
          <div class="h-80px space-y-2 flex flex-col justify-evenly">
            <div class="font-bold">{{ zzf_name }}</div>
            <div class="text-dark-200">{{ zzf_datetime }}</div>
          </div>
        </div>
      </div>
    </div>
  </el-dialog>

  <el-dialog v-model="boardDialogVisible" fullscreen>
    <el-radio-group v-model="currentBoard" @change="updateBoardConfig" class="grid! grid-cols-4 gap-8">
      <el-radio v-for="({ color, image, title }) in Object.values(BoardMap)" :value="title">
        <div class="radio_content border-1 min-h-160px flex justify-center items-center"
          :style="{ background: color, color: PenDefaultConfig[color].color }">
          <img v-if="image" :src="image" class="w-full h-full object-cover" />
        </div>
      </el-radio>
    </el-radio-group>
  </el-dialog>

  <el-dialog v-model="ebookDialogVisible" fullscreen>
    <div class="flex flex-col h-92vh">
      <el-checkbox-group v-model="ebookSelectedList"
        class="flex-auto overflow-y-scroll grid! grid-cols-3 xl:grid-cols-4 gap-10">
        <el-checkbox v-for="({ zem_id, zem_name, zem_img, zem_filesize, zem_file }) in ebookList" :key="zem_id"
          :value="zem_id">
          <div class="h-full flex flex-col justify-between h-210px">
            <div class="flex justify-center space-x-2 h-full">
              <img :src="zem_img" class="w-1/2 h-full" loading="lazy" />
              <div class="flex flex-col justify-between">
                <div class="text-wrap text-lg font-700">{{ zem_name }}</div>
                <div class="text-end">
                  <div>
                    课本： {{ (parseFloat(zem_filesize) / 1024 / 1024).toFixed(1) }}MB
                  </div>
                  <el-button class="mt-2" @click="downloadFile(zem_file, zem_name)">下载课本</el-button>
                </div>
              </div>
            </div>
          </div>
        </el-checkbox>
      </el-checkbox-group>
      <div class="px-16 pt-10 flex justify-end items-end">
        <el-button type="danger" @click="deleteEbook" size="large">删除</el-button>
      </div>
    </div>
  </el-dialog>

  <el-dialog v-model="docDialogVisible" fullscreen>
    <div class="flex flex-col h-92vh">
      <el-checkbox-group v-model="docSelectedList"
        class="flex-auto overflow-y-scroll grid! grid-cols-3 xl:grid-cols-4 gap-10 items-start content-start">
        <el-checkbox v-for="({ ykz_id, ykz_title, ykz_ext, yzk_bddz_preview }) in docList" :key="ykz_id"
          :value="ykz_id">
          <div class="flex flex-col justify-between ">
            <div class="flex justify-center space-x-2 h-full">
              <img :src="`/mipmap/file_${getFileType(ykz_ext)}.png`" class="w-1/2 h-full" loading="lazy" />
              <div class="flex flex-col justify-between">
                <div class="text-wrap text-lg font-700">{{ ykz_title }}</div>
                <div class="text-end">
                  <el-button class="mt-2" @click="downloadFile(yzk_bddz_preview, ykz_title)">下载</el-button>
                </div>
              </div>
            </div>
          </div>
        </el-checkbox>
      </el-checkbox-group>
      <div class="px-16 pt-10 flex justify-end items-end">
        <el-button type="primary" @click="sendDoc" size="large">发送</el-button>
      </div>
    </div>
  </el-dialog>

</template>

<style>
.html_block img {
  display: inline-block !important;
}
</style>

<style scoped>
:deep(.el-radio) {
  height: auto
}

:deep(.el-radio .el-radio__input) {
  visibility: hidden
}

:deep(.el-radio .el-radio__label) {
  width: 100%;
  height: 100%;
}

:deep(.el-radio) .radio_content {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}

:deep(.el-radio.is-checked) .radio_content {
  box-shadow: 10px 10px 20px #444444;
}

:deep(.el-checkbox) {
  height: auto;
  align-items: start;
}

:deep(.el-checkbox .el-checkbox__label) {
  width: 100%;
  height: 100%;
  box-sizing: border-box;
}
</style>
