<!--
  Description: Quill富文本编辑区
  Author: BaiQi
  Created Date: 2025-1-8
-->
<template>
  <div class="editor-container" @keydown="handleKeydown" @keyup="handleKeyup">
    <Editor/>
    <!--<el-button @click="download">导出</el-button>-->
  </div>
</template>

<script setup lang="ts">
  import "./QuillEditor.scss"
  import Editor from './Editor.vue';
  import { onUnmounted, reactive, ref, watch } from 'vue';
  import emitter from '@/utils/emitter';
  import dayjs from "dayjs";
  import * as XLSX from 'xlsx'
  import useApis from "@/apis";
  import {useRoute} from "vue-router";
  import {ElMessage} from "element-plus";

  const apis = useApis()
  // 获取当前路由对象
  const route = useRoute();
  // 从路由对象中提取 id 参数
  const assignmentId = Number(route.params.assignmentId);

  // 新增：用于存储每个按键的down事件信息
  let keyEventMap = reactive({})
  let keyEventRecordList = reactive([])
  // 行为记录
  let changeRecordList = reactive([])

  // 作文内容发生变化时，触发
  emitter.on('change-record', (value) => {
    changeRecordList.push(value)
  })

  // 点击暂存按钮时，触发行为记录保存
  emitter.on('click-stage', () => {
    if(changeRecordList.length > 0){
      download()
      changeRecordList.length = 0
    }
  })

  // 向AI发送问题后触发
  emitter.on("click-ai-send-button", (event: any) => {
    changeRecordList.push(event)
  });

const normalizeKey = (event: KeyboardEvent) => {
  let key = event.key

  // Shift + 数字 → 符号（包含 0 -> )）
  const shiftNumMap: Record<string, string> = {
    '1': '!', '2': '@', '3': '#', '4': '$', '5': '%',
    '6': '^', '7': '&', '8': '*', '9': '(', '0': ')'
  }
  if (event.shiftKey && shiftNumMap[key]) {
    return shiftNumMap[key]
  }

  // Shift + 字母 → 大写
  if (event.shiftKey && /^[a-z]$/i.test(key)) {
    return key.toUpperCase()
  }

  return key
}

  const handleKeydown = (event: KeyboardEvent) => {
    // 增加对Shift组合键的识别
    // 在handleKeyup中增加对组合键的识别
    let key = normalizeKey(event)
    // if (event.shiftKey && /^[0-9]$/.test(key)) {
    //   key = "!@#$%^&*()"[parseInt(key) - 1]; // 映射Shift+数字到符号
    // } else if(event.shiftKey && /^[a-z]$/i.test(event.key) ){
    //   key = event.key.toUpperCase()
    // }

    // 存储down事件信息到keyEventMap中
    if (!keyEventMap[key]) {
      keyEventMap[key] = [];
    }

    // 将每次down事件信息存入数组
    keyEventMap[key].push({
      downKey: event.key,
      startStamp: event.timeStamp,
      startTime: dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss.SSS")
    });

  }

  function formatMilliseconds(milliseconds) {
    // 把毫秒数转换为秒
    const totalSeconds = Math.floor(milliseconds / 1000);
    // 计算小时数
    const hours = Math.floor(totalSeconds / 3600);
    // 计算剩余的秒数
    const remainingSecondsAfterHours = totalSeconds % 3600;
    // 计算分钟数
    const minutes = Math.floor(remainingSecondsAfterHours / 60);
    // 计算最终的秒数
    const seconds = remainingSecondsAfterHours % 60;

    // 格式化小时、分钟和秒，不足两位前面补 0
    const formattedHours = String(hours).padStart(2, '0');
    const formattedMinutes = String(minutes).padStart(2, '0');
    const formattedSeconds = String(seconds).padStart(2, '0');

    // 返回格式化后的字符串
    return `${formattedHours}:${formattedMinutes}:${formattedSeconds}`;
  }

  const getPause = (i: number) => {
    let result = 0
    for(let k = i-1; k >= 0; k--){
      if('startStamp' in changeRecordList[k]){
        result = changeRecordList[k].startStamp
        break
      }
    }
    return result
  }

const isCtrlOrMeta = (event: KeyboardEvent) => event.ctrlKey === true || event.metaKey === true


  const handleKeyup = (event: KeyboardEvent) => {
    const realTime = dayjs(new Date()).format("YYYY-MM-DD HH:mm:ss.SSS")
    const key = normalizeKey(event);
    // 处理所有与该按键key有关的keydown行为
    while (keyEventMap[key] && keyEventMap[key].length > 0) {
      // 取得keydown事件信息
      const downEvent = keyEventMap[key].pop();
      // 将keydown信息与keyup整合
      const combinedEvent = {
        timeKey: key,
        startStamp: downEvent.startStamp | 0,
        startClock: formatMilliseconds(downEvent.startStamp | 0),
        startTime: downEvent.startTime,
        endStamp: event.timeStamp | 0,
        endClock: formatMilliseconds(event.timeStamp | 0),
        endTime: realTime,
        actionTime: (event.timeStamp | 0) - (downEvent.startStamp | 0)
      };
      // 将得到的key事件的完整信息保存
      keyEventRecordList.push(combinedEvent);

      // 根据key的信息对行为进行分析记录
      // 包括
      // 1.单个字母的键入
      // 2.删除按键
      // 3.复制
      // 4.粘贴
      // 5.换行

      for (let i = changeRecordList.length - 1; i >= 0; i--) {
        // 删除按键的记录
        if (key === 'Backspace') {
          if (changeRecordList[i].type === 'delete') {
            changeRecordList[i] = {
              ...changeRecordList[i],
              ...combinedEvent,
              pauseTime: combinedEvent.startStamp - getPause(i)
            }
            break
          } else {
            continue
          }

        }
        // 复制
        else if ((key === 'c' || key === 'C') && isCtrlOrMeta(event)) {
          changeRecordList[i] = {
            ...changeRecordList[i],
            ...combinedEvent,
            pauseTime: combinedEvent.startStamp - getPause(i),
            type: 'paste'
          }
          break
        }
        // 粘贴
        else if ((key === 'v' || key === 'V') && isCtrlOrMeta(event)) {
          changeRecordList[i] = {
            ...changeRecordList[i],
            ...combinedEvent,
            pauseTime: combinedEvent.startStamp - getPause(i),
            type: 'copy'
          }
          break
        }
        // 换行
        else if (key === 'Enter') {
          changeRecordList[i] = {
            ...changeRecordList[i],
            ...combinedEvent,
            pauseTime: combinedEvent.startStamp - getPause(i),
          }
          break
        }
        // 字母的键入
        else if ('key' in changeRecordList[i] && changeRecordList[i].key === combinedEvent.timeKey) {
          changeRecordList[i] = {
            ...changeRecordList[i],
            ...combinedEvent,
            pauseTime: combinedEvent.startStamp - getPause(i)
          }
          break
        }
        // TODO: 处理输入法键入
      }

      // 所有key相关信息处理完毕，删除map
      if (keyEventMap[key].length === 0) {
        delete keyEventMap[key];
      }
    }

    // TODO:测试片段，需删除
    emitter.emit('record-test', changeRecordList)
  }

  const download = () => {
    // 将changeRecordList转换为JSON字符串
    const jsonData = JSON.stringify(changeRecordList)

    // 创建包含JSON数据的Blob对象
    const blob = new Blob([jsonData], {
      type: 'application/json'
    })

    const filename = `行为记录.json`
    const file = new File([blob], filename, { type: blob.type })
    if(assignmentId != null){
      apis.addBehaviorRecord(assignmentId, file)
          .then(res => {
            // console.log(res.data.data)
          })
          .catch(err => {
            ElMessage.error("行为记录异常，请联系老师处理！")
            console.log(err)
          })
    }
  }

  onUnmounted(() => {
    emitter.off("change-record")
    emitter.off("click-stage")
    emitter.off("click-ai-send-button")
    if(changeRecordList.length > 0){
      download()
    }
  })

</script>

<script lang="ts">
export default {
  name: "QuillEditor"
}
</script>

