"use client"

import {
  useCallback,
  useEffect,
  useMemo,
  useReducer,
  useRef,
  useState,
} from "react"
import ScaleComponent from "./components/ScaleComponent"

import { Box, Flex, LoadingOverlay, Stack } from "@mantine/core"
import { showNotification } from "@mantine/notifications"
import { getName } from "@tauri-apps/api/app"
import { getCurrentWindow } from "@tauri-apps/api/window"
import { getLabelResult } from "./api/label"
import { Comment, WorkLoad } from "./api/label/typing"
import { getProjectDetail } from "./api/project"
import { Project } from "./api/project/typing"
import { getTaskList, getTaskWorkFlow } from "./api/task"
import { Task } from "./api/task/typing"
import BottomTools from "./components/BottomTools"
import ConfirmModal from "./components/ConfirmModal"
import { splitWord } from "./components/EditorContainer"
import PaperContainer from "./components/PaperContainer"
import RightDescTools from "./components/RightDescTools"
import RightGroupTools from "./components/RightGroupTools"
import RightObjectTools from "./components/RightObjectTools"
import RightQATools from "./components/RightQATools"
import RightTaskTools from "./components/RightTaskTools"
import ScaleToolContainer from "./components/ScaleToolContainer"
import TopTools from "./components/TopTools"
import { useKeyEventStore, useLabelStore, useObjectStore } from "./store"
import { usePermissionStore } from "./store/auth"
import { useBottomToolsStore } from "./useBottomToolsStore"
import { useDescToolsStore } from "./useDescToolsStore"
import { useKeyboardStore } from "./useKeyBoardStore"
import { usePaperStore } from "./usePaperStore"
import { useRightToolsStore } from "./useRightToolsStore"
import { useIntervalStore, useTimerStore } from "./useTimerStore"
import { useTopToolsStore } from "./useTopToolsStore"
import { findGroupKey } from "./util"
import { labelTypeMap } from "./utils/constants"

// Splitter component - will need custom implementation or alternative

// 定义状态的类型
export type LabelState = Map<string, string[]>

// 定义操作的类型
type Action =
  | {
      type: "INIT_IMAGES"
      imageIds: string[]
      objectOperations: Project.LabelSchemaList[]
    }
  | { type: "REMOVE_IMAGE"; imageId: string }

// 定义初始状态
const initialState: LabelState = new Map()

const operationTypeList = [101, 102, 103, 104]

// utils
const getRectPoints = ([sx, sy, w, h]: number[]) => {
  return [
    [sx, sy + h],
    [sx, sy],
    [sx + w, sy],
    [sx + w, sy + h],
  ]
}

const getSegmentPoints = (arr: Array<number[]>) => {
  return arr.map((item) => [item[0], item[1]])
}

interface LabelProps {
  headerHeight: number
  leftWidth: number
  project_id: number
  task_id: number
}

const LabelPage = ({
  headerHeight = 0,
  leftWidth = 0,
  project_id = -1,
  task_id = -1,
}: LabelProps) => {
  const projectId = useMemo(() => {
    return project_id
  }, [project_id])
  const taskId = useMemo(() => {
    return task_id
  }, [task_id])
  //   const searchParams = useSearchParams()
  //   const id1 = searchParams.get("project_id")
  //   const projectId =
  //     typeof id1 === "string" && !isNaN(Number(id1)) ? Number(id1) : 1
  //   const id2 = searchParams.get("task_id")
  //   const taskId =
  //     typeof id2 === "string" && !isNaN(Number(id2)) ? Number(id2) : 2

  const user_id = usePermissionStore.getState().user_id
  const [projectDetail, setProjectDetail] = useState<Project.DetailResponse>()
  const [taskDetail, setTaskDetail] = useState<Task.DataProps>()
  const [oldWorkLoad, setOldWorkLoad] = useState<WorkLoad | null>(null)
  // const [objectOperations, setObjectOperations] = useState<
  //   Project.LabelSchemaList[]
  // >([]);
  const topRef = useRef<any>(null)
  const paperContainerRef = useRef<any>(null)
  const qaToolContainerRef = useRef<any>(null)
  const [isConfirmSave, setIsConfirmSave] = useState(false)
  const [loading, setLoading] = useState(false)
  const [sizes, setSizes] = useState<number[]>([])

  const {
    label: labelData,
    setLabel,
    setStateStack,
    setLabelTime,
  } = useLabelStore()
  const { isAutoSave, autoSaveGap } = useIntervalStore()

  const {
    editMode,
    setEditMode,
    setPressA,
    activeOperation,
    setActiveOperation,
    showObjectList,
    showGroupList,
    showTaskList,
    showDescList,
    showMultiFrame,
    setShowMultiFrame,
    isView,
    setIsView,
    scale,
    setScale,
    objectOperations,
    setObjectOperations,
  } = useTopToolsStore()
  const { activeImage } = useBottomToolsStore()
  const {
    setDescOperations,
    metaOperation,
    setMetaOperation,
    setQaOperations,
    setQaData,
    resetData,
  } = useDescToolsStore()

  const asyncGetProjectDetail = useCallback(async () => {
    if (projectId) {
      try {
        const res = await getProjectDetail(projectId)
        setProjectDetail(res)
        let operations: Project.LabelSchemaList[] = []
        let textOperations: Project.LabelSchemaList[] = []
        let metaOperation: Project.LabelSchemaList | null = null
        res.label_schema_list?.forEach((schema) => {
          if (operationTypeList.includes(schema.label_type)) {
            operations.push(schema)
          } else if ([201].includes(schema.label_type)) {
            if (schema.label_class === "元操作序列") metaOperation = schema
            else textOperations.push(schema)
          }
        })
        setObjectOperations(operations)
        if (res.label_type === 5) {
          setDescOperations(textOperations)
          if (metaOperation) setMetaOperation(metaOperation)
        } else {
          setDescOperations([])
          setMetaOperation(null)
        }
        if (res.label_type === 6) {
          let obj: any = {}
          textOperations.forEach((item) => {
            let arr = item.sub_attributes_describe.map((sub) => {
              return {
                [sub.chinese_name]: {
                  value: "",
                  id: sub.round_id,
                  is_pre: true,
                  tag: 0,
                  uid: 0,
                  create_timestamp: 0,
                  modify_uid: 0,
                  modify_timestamp: 0,
                  comment: "",
                  flag: 0,
                },
              }
            })
            obj[item.label_class] = arr
          })
          let map = new Map()
          map.set("init", obj)
          console.log(map)
          setQaData(map)
          setQaOperations(textOperations)
        } else {
          setQaOperations([])
        }
        resetData()
      } catch {}
    }
  }, [
    projectId,
    resetData,
    setDescOperations,
    setMetaOperation,
    setObjectOperations,
    setQaData,
    setQaOperations,
  ])

  const asyncGetTaskDetail = useCallback(async () => {
    if (taskId) {
      try {
        usePaperStore.getState().setLoadingData(true)
        // 获取当前任务全量数据
        const res = await getTaskList({
          id: [taskId],
          get_data: true,
          page_number: 1,
          page_size: 1,
        })
        let detail = res.task_list[0]
        setTaskDetail(detail)
        // 帧列表
        useBottomToolsStore
          .getState()
          .setAllItems(detail.data_name.map((item) => item.name[0] || ""))
        // 获取当前任务流转记录
        let flowCommentArr: Comment[] = []
        let turn1time = 1
        let turn2time = 1
        const flowRes = await getTaskWorkFlow(taskId)
        flowRes.forEach((item) => {
          if (item.task_status_src !== 4 && item.task_status_dst === 4) {
            flowCommentArr.push({
              uid: item.new_uid,
              turn: 1,
              times: turn1time,
              check_box_comments: [],
              text_comments: [],
              comment_type: 0,
              date: 0,
              scene_info: {
                type: 0,
              },
            })
            turn1time++
          } else if (item.task_status_src !== 6 && item.task_status_dst === 6) {
            flowCommentArr.push({
              uid: item.new_uid,
              turn: 2,
              times: turn2time,
              check_box_comments: [],
              text_comments: [],
              comment_type: 0,
              date: 0,
              scene_info: {
                type: 0,
              },
            })
            turn2time++
          }
        })
        console.log(flowCommentArr)
        useLabelStore.getState().setLabelDefaultComments(flowCommentArr)
        const { work_time, label_status } = detail
        setLabelTime({
          label: work_time.label_work_time,
          review1: work_time.first_review_work_time,
          review2: work_time.second_review_work_time,
        })
        // 获取并处理当前任务标注结果数据
        const dataRes = await getLabelResult(taskId)
        const { results } = dataRes

        let currentWorkTime = 0
        if (label_status === 2) {
          currentWorkTime = work_time.label_work_time
        } else if (label_status === 4) {
          currentWorkTime = work_time.first_review_work_time
        } else if (label_status === 6) {
          currentWorkTime = work_time.second_review_work_time
        }

        // 生成当前workload
        const workLoad: WorkLoad = {
          object_size: {},
          prelabel_modify_size: {},
          review_size: 0,
          comment_size: 0,
          work_time: currentWorkTime,
          dynamic_size: {},
          static_size: {},
          review_dynamic_size: {},
          review_static_size: {},
          review_question_size: {},
          key_frame_size: {},
          review_key_frame_size: {},
          question_size: {},
        }
        results.forEach((item) => {
          const { image_objects } = item
          if (image_objects) {
            const { annotations, images, key_frame, desc } = image_objects
            usePaperStore
              .getState()
              .setRasterSize(images.file_name, [images.width, images.height])
            annotations.forEach((annotation) => {
              let reviewed = false
              const { comment, prelabel, uid } = annotation
              if (prelabel)
                workLoad.prelabel_modify_size[uid]
                  ? workLoad.prelabel_modify_size[uid]++
                  : (workLoad.prelabel_modify_size[uid] = 1)
              else
                workLoad.object_size[uid]
                  ? workLoad.object_size[uid]++
                  : (workLoad.object_size[uid] = 1)
              if (comment) {
                comment.forEach((c) => {
                  if (c.comment_type > 0 && c.uid === user_id) reviewed = true
                  if (c.comment_type === 2 && c.uid === user_id)
                    workLoad.comment_size++
                })
              }
              if (reviewed) workLoad.review_size++
            })
            if (key_frame) {
              if (label_status === 2) {
                let id = image_objects.label1_uid!
                if (id)
                  workLoad.key_frame_size[id]
                    ? workLoad.key_frame_size[id]++
                    : (workLoad.key_frame_size[id] = 1)
              } else if (label_status === 4) {
                let id = image_objects.review1_uid!
                if (id)
                  workLoad.review_key_frame_size[id]
                    ? workLoad.review_key_frame_size[id]++
                    : (workLoad.review_key_frame_size[id] = 1)
              } else if (label_status === 6) {
                let id = image_objects.review2_uid!
                if (id)
                  workLoad.review_key_frame_size[id]
                    ? workLoad.review_key_frame_size[id]++
                    : (workLoad.review_key_frame_size[id] = 1)
              }
            }
            if (useDescToolsStore.getState().qaOperations.length) {
              if (desc) {
                const { other_desc } = desc
                const descData = other_desc ? JSON.parse(other_desc) : {}
                Object.values(descData).forEach((questionArr: any) => {
                  questionArr.forEach((q: any) => {
                    const v: any = Object.values(q)[0]
                    if (v.uid) {
                      workLoad.question_size[v.uid]
                        ? workLoad.question_size[v.uid]++
                        : (workLoad.question_size[v.uid] = 1)
                    }
                    if (v.tag) {
                      const uid = usePermissionStore.getState().user_id
                      workLoad.review_question_size[uid]
                        ? workLoad.review_question_size[uid]++
                        : (workLoad.review_question_size[uid] = 1)
                    }
                  })
                })
              }
            }
          }
        })
        console.log("获取时计算的工作量统计", workLoad)
        setOldWorkLoad(workLoad)
        const taskLabelData = new Map()
        const pathGroupData = new Map()
        // 重置 PathIds
        useRightToolsStore.getState().setPathIds([])
        // 重置 PathGroupIds
        useRightToolsStore.getState().setPathGroupIds([])
        // 生成标注结果
        results.forEach((item) => {
          const { data_name, image_objects } = item
          if (image_objects) {
            const categoryMap = new Map()
            const { annotations, image_groups, desc } = image_objects
            // 赋值用过的 id
            annotations.map((annotation) => {
              useRightToolsStore.getState().pushPathId(annotation.id)
            })
            // 赋值用过的 groupId
            image_groups &&
              Object.keys(image_groups)?.map((groupId) => {
                useRightToolsStore.getState().pushPathGroupId(+groupId)
              })
            annotations.forEach((annotation) => {
              const { id, category_id, comment } = annotation
              let current_comment: Comment[] = []
              if (comment) {
                current_comment = flowCommentArr.map((c) => {
                  const { turn, times } = c
                  let modified_comment = null
                  comment.forEach((item) => {
                    if (item.turn === turn && item.times === times)
                      modified_comment = item
                  })
                  return modified_comment ? modified_comment : c
                })
              } else {
                current_comment = [...flowCommentArr]
              }
              let detail: any = {
                ...annotation,
                comment: current_comment,
              }
              // group info
              if (image_groups) {
                const key = findGroupKey(image_groups as any, id)
                if (key !== -1) detail.parentGroupId = key
              }
              const categoryKey = `${category_id}`
              let arr = categoryMap.has(categoryKey)
                ? categoryMap.get(categoryKey)
                : []
              if (annotation.rect) {
                // arr.push([id, getRectPoints(annotation.rect), detail, []]);
                arr.push([id, [getRectPoints(annotation.rect)], detail, []])
              }

              if (annotation.line_segment) {
                arr.push([
                  id,
                  annotation.line_segment.map((item) => getSegmentPoints(item)),
                  detail,
                  [],
                ])
              }

              if (annotation.segmentation) {
                arr.push([
                  id,
                  // getSegmentPoints(annotation.segmentation[0]),
                  annotation.segmentation.map((item) => getSegmentPoints(item)),
                  detail,
                  annotation.hollow_segmentation?.map((item) =>
                    getSegmentPoints(item)
                  ) || [],
                ])
              }
              if (annotation.key_points) {
                arr.push([
                  id,
                  // getSegmentPoints(annotation.segmentation[0]),
                  [
                    getSegmentPoints(
                      annotation.key_points.map((item) => item.point)
                    ),
                  ],
                  Object.assign(detail, {
                    circles: annotation.key_points,
                  }),
                  [],
                ])
              }

              categoryMap.set(categoryKey, arr)
            })
            const key = data_name
            taskLabelData.set(key, categoryMap)
            // 关键帧信息
            const keyFrame = {
              key_frame: image_objects.key_frame || false,
              label1_ts: image_objects.label1_ts || 0,
              label1_uid: image_objects.label1_uid || 0,
              review1_ts: image_objects.review1_ts || 0,
              review1_uid: image_objects.review1_uid || 0,
              review2_ts: image_objects.review2_ts || 0,
              review2_uid: image_objects.review2_uid || 0,
            }
            useBottomToolsStore.getState().setKeyFrameData(key, keyFrame)
            // 大语言模型 两种数据情况
            if (useDescToolsStore.getState().qaOperations.length) {
              if (desc) {
                const { other_desc } = desc
                let current_data: any = {}
                const descData = other_desc ? JSON.parse(other_desc) : {}
                Object.entries(descData).forEach(
                  ([label_class, questionArr]: any) => {
                    let arr = questionArr.map((question: any) => {
                      let [name, val]: any = Object.entries(question)[0]
                      return {
                        [name]: {
                          ...val,
                          value: val.value
                            ? `${val.value}${splitWord}${val.value}`
                            : undefined,
                          comment: val.comment
                            ? `${val.comment}${splitWord}${val.comment}`
                            : undefined,
                        },
                      }
                    })
                    current_data[label_class] = arr
                  }
                )
                const qaData = useDescToolsStore.getState().qaData
                // 无文本描述时 赋予预设值
                if (JSON.stringify(current_data) === "{}") {
                  current_data = qaData.get("init")
                }
                const qaMap = structuredClone(qaData)
                qaMap.set(key, current_data)
                useDescToolsStore.getState().setQaData(qaMap)
              }
            } else if (useDescToolsStore.getState().descOperations.length) {
              if (desc) {
                const { meta_operation, other_desc } = desc
                const currentMetaMap = structuredClone(
                  useDescToolsStore.getState().metaData
                )
                currentMetaMap.set(key, meta_operation || [])
                useDescToolsStore.getState().setMetaData(currentMetaMap)
                const currentDescMap = structuredClone(
                  useDescToolsStore.getState().descData
                )
                let descMap = new Map()
                const descData = other_desc ? JSON.parse(other_desc) : {}
                console.log(descData)
                Object.entries(descData).forEach(
                  ([label_class, { value, is_correct, comment }]: any) => {
                    descMap.set(label_class, {
                      value:
                        (typeof value === "string"
                          ? `${value}${splitWord}${value}`
                          : value) || undefined,
                      is_correct: is_correct || undefined,
                      comment: comment || undefined,
                    })
                  }
                )
                currentDescMap.set(key, descMap)
                useDescToolsStore.getState().setDescData(currentDescMap)
              }
            }
            image_groups &&
              pathGroupData.set(
                key,
                new Map(
                  Object.entries(image_groups).map(([key, value]: any) => [
                    key * 1,
                    value,
                  ])
                )
              )
          }
        })
        setLabel(taskLabelData)
        // 获取任务详情时设置状态栈初始值
        setStateStack([taskLabelData])
        useDescToolsStore.getState().updateFlag(true)
        useRightToolsStore.getState().setPathGroupMap(pathGroupData)
      } catch (err) {
        console.log(err)
        setOldWorkLoad(null)
        setLabel(new Map())
        setStateStack([])
        useRightToolsStore.getState().setPathGroupMap(new Map())
      } finally {
        usePaperStore.getState().setLoadingData(false)
      }
    }
  }, [setLabel, setLabelTime, setStateStack, taskId, user_id])

  // 保存时更新当前workload
  const updateOldWorkLoad = (data: WorkLoad) => {
    setOldWorkLoad(data)
  }

  useEffect(() => {
    asyncGetProjectDetail()
    asyncGetTaskDetail()
  }, [asyncGetProjectDetail, asyncGetTaskDetail])

  // 定义 reducer 函数
  const reducer = useCallback(
    (state: LabelState, action: Action): LabelState => {
      switch (action.type) {
        case "INIT_IMAGES":
          const newState = new Map() // 创建状态的副本
          action.imageIds.forEach((imageId) => {
            newState.set(
              imageId,
              action.objectOperations.map((item) => item.category_id.toString())
            ) // 将操作列表添加到新状态中
          })
          return newState

        case "REMOVE_IMAGE":
          const stateAfterRemoval = new Map(state)
          if (stateAfterRemoval.has(action.imageId)) {
            stateAfterRemoval.delete(action.imageId) // 删除该图片的条目
          }
          return stateAfterRemoval

        default:
          return state // 返回当前状态
      }
    },
    []
  )

  const [labelState, dispatch] = useReducer(reducer, initialState)

  const initImages = (
    imageIds: string[],
    objectOperations: Project.LabelSchemaList[]
  ) => {
    dispatch({
      type: "INIT_IMAGES",
      imageIds,
      objectOperations,
    })
  }

  const [isLabelTask, setIsLabelTask] = useState<boolean>(false)

  useEffect(() => {
    if (!taskDetail || !projectDetail) {
      setIsLabelTask(false)
      setIsView(true)
      setEditMode(false)
      return
    }
    if (taskDetail) {
      if (
        ![201, 202, 203, 500].includes(projectDetail!.status) ||
        ![2, 4, 6].includes(taskDetail.label_status) ||
        taskDetail.current_uid !== user_id
      ) {
        // 如果不是能标注的任务
        setIsLabelTask(false)
        setIsView(true)
        setEditMode(false)
      } else {
        setIsLabelTask(true)
        setIsView(false)
      }

      initImages(
        taskDetail.data_name.map((item) => item.name?.[0]),
        objectOperations
      )

      if (taskDetail.data_name?.length) setShowMultiFrame(true)
    }
  }, [
    objectOperations,
    setIsView,
    setShowMultiFrame,
    user_id,
    taskDetail,
    projectDetail,
    setEditMode,
  ])

  const { setPaperMode, setToolOption, setGroupScale } = usePaperStore()

  // @ts-expect-error  to_do
  const forceUpdate = useReducer((bool) => !bool)[1]

  const getOperationSchema = useCallback(
    (operationId: string) => {
      return (
        projectDetail?.label_schema_list?.find(
          (item) => item.category_id === +operationId && item.label_type !== 201
        ) || null
      )
    },
    [projectDetail?.label_schema_list]
  )

  const setDrawType = useCallback(() => {
    if (isView) {
      setPaperMode("pan")
    } else {
      let operationSchema = getOperationSchema(activeOperation)
      if (operationSchema) {
        let strokeColor = `rgb(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]})`
        let fillColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.3)`
        let blankColor = `rgba(${operationSchema.color[0]},${operationSchema.color[1]},${operationSchema.color[2]},0.01)`

        if (editMode) {
          switch (
            operationSchema &&
            labelTypeMap.get(operationSchema.label_type)
          ) {
            case "多边形":
              setToolOption({
                strokeColor: strokeColor,
                strokeWidth: 2,
                fillColor: fillColor,
                blankColor: blankColor,
              })
              setPaperMode("polygon")
              return
            case "关键点":
              setToolOption({
                strokeColor: strokeColor,
                strokeWidth: 2,
                fillColor: fillColor,
                blankColor: blankColor,
              })
              setPaperMode("point")
              return
            case "多线段":
              setToolOption({
                strokeColor: strokeColor,
                strokeWidth: 2,
                fillColor: fillColor,
                blankColor: blankColor,
              })
              setPaperMode("brush")
              return
            case "2D框":
              setToolOption({
                strokeColor: strokeColor,
                strokeWidth: 2,
                fillColor: fillColor,
                blankColor: blankColor,
              })
              setPaperMode("rectangle")
              return
            default:
              setPaperMode("polygon")
              return
          }
        } else {
          setPaperMode("pan")
        }
      }
    }
  }, [
    activeOperation,
    editMode,
    getOperationSchema,
    isView,
    setPaperMode,
    setToolOption,
  ])

  useEffect(() => {
    setDrawType()
  }, [editMode, setDrawType])

  const { setShift, focusInput } = useKeyEventStore()

  const handleShortcut = useCallback(
    (key: string, ctrl: boolean) => {
      let checkOperation = getOperationSchema(key)
      const mode = usePaperStore.getState().mode
      // 标注方案里面存在的非文本类型标注才能切换
      if (checkOperation) {
        // 辅助标注模式下非多边形类型不能切换
        if (mode === "support" && checkOperation.label_type !== 102) return
        if (ctrl) {
          setActiveOperation((+key + 10).toString())
        } else {
          setActiveOperation(key)
        }
      }
    },
    [getOperationSchema, setActiveOperation]
  )

  useEffect(() => {
    const down = (e: KeyboardEvent) => {
      // console.log(e, e.key);
      if (focusInput || isView) return

      console.log(e.key)
      const mode = usePaperStore.getState().mode

      if (e.key === "Alt" && mode !== "support") {
        e.preventDefault()
        // console.log(e.key);
        setEditMode(!editMode)
        if (!editMode) setPressA(false)
      }

      if (e.key === "Shift") {
        e.preventDefault()
        setShift(true)
        useKeyboardStore.getState().setShift(true)
      }

      if (mode !== "support")
        if (Number(e.key)) {
          handleShortcut(e.key, e.ctrlKey)
        } else if (Number(e.key) === 0) {
          handleShortcut("10", e.ctrlKey)
        }

      if (e.key === "s" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        setIsConfirmSave(true)
      }

      if (e.key === "g" && (e.metaKey || e.ctrlKey)) {
        e.preventDefault()
        paperContainerRef.current.handleCreatePathGroup()
      }

      if (e.key === "a") {
        e.preventDefault()
        setPressA(true)
      }

      if (e.key === "Control") {
        e.preventDefault()
        useKeyboardStore.getState().setCtrl(true)
      }
      // 辅助标注 分割
      if (e.key === "F1") {
        // 判断类型
        e.preventDefault()
        const schema = getOperationSchema(
          useTopToolsStore.getState().activeOperation
        )
        console.log(schema)
        if (schema?.label_type !== 102) {
          showNotification({
            title: "错误",
            message: "当前类型不支持辅助标注！",
            color: "red",
          })
        } else {
          if (mode === "support") {
            // 辅助标注生成对应标注结果
            paperContainerRef.current.saveSupportAnnotationData()
          } else {
            usePaperStore.getState().setPaperMode("support")
          }
        }
      }

      // 追踪
      if (e.key === "i") {
        e.preventDefault()
        paperContainerRef.current.renderTrackingAnnotation()
      }

      // 复制
      if (e.key === "c" && e.ctrlKey) {
        e.preventDefault()
        useKeyboardStore
          .getState()
          .setCopyDataIds(
            useObjectStore.getState().selectedPath[
              useBottomToolsStore.getState().activeImage
            ]
          )
      }

      // 粘贴
      if (e.key === "v" && e.ctrlKey) {
        e.preventDefault()
        paperContainerRef.current.copyAnnotationDataToMultiFrame()
      }

      // 撤回
      if (e.key === "z" && e.ctrlKey) {
        e.preventDefault()
        // 清除当前页数据
        const clear = () => {
          usePaperStore
            .getState()
            .group!.getItems({})
            .filter((item) => item.data.id)
            .forEach((item) => {
              item.remove()
            })
        }
        const data = useLabelStore.getState().popStateStack()
        console.log("弹出栈的数据", data)
        if (data) {
          clear()
          const imageId = useBottomToolsStore.getState().activeImage
          const pathGroupMap = new Map()
          for (const [imageKey, categories] of data) {
            const groupMap = new Map()
            for (const [key, value] of categories) {
              value.forEach((item) => {
                const vId = item[2].parentGroupId
                if (vId)
                  if (groupMap.has(vId)) groupMap.get(vId).push(item[0])
                  else groupMap.set(vId, [item[0]])
              })
              if (imageId === imageKey)
                paperContainerRef.current.renderPolygons(key, categories)
            }
            pathGroupMap.set(imageKey, groupMap)
          }
          useRightToolsStore.getState().setPathGroupMap(pathGroupMap)

          console.log(pathGroupMap)
          // if (data.size) {
          //   if (data.has(imageId)) {
          //     const map = data.get(imageId);
          //     if (map) {
          //       for (const [key, value] of map) {
          //         console.log(key, value);
          //         paperContainerRef.current.renderPolygons(key, map);
          //       }
          //     }
          //   }
          // }
          // 更新当前数据
          useLabelStore.getState().setLabel(structuredClone(data))
        }
      }

      if (e.key === "p") {
        e.preventDefault()
        if (projectDetail?.label_type === 6 && qaToolContainerRef.current)
          qaToolContainerRef.current.checkWrongWords()
      }

      // if (e.key === "=" && (e.metaKey || e.ctrlKey)) {
      //   e.preventDefault();
      //   setScale((num) => {
      //     let newScale = num + 0.1;
      //     return newScale;
      //   });
      // } else if (e.key === "-" && (e.metaKey || e.ctrlKey)) {
      //   e.preventDefault();
      //   setScale((num) => {
      //     if (num <= 1) {
      //       let newScale = num * 0.9;
      //       return newScale;
      //     } else {
      //       let newScale = num - 0.1;
      //       return newScale;
      //     }
      //   });
      // } else if (e.key === "3") {
      //   e.preventDefault();
      // } else if (e.key === "4") {
      //   e.preventDefault();
      // } else if (e.key === "5") {
      //   e.preventDefault();
      // } else if (e.key === "a" && (e.metaKey || e.ctrlKey)) {
      //   e.preventDefault();
      // }
    }
    const up = (e: KeyboardEvent) => {
      // console.log("键盘抬起", e);
      if (e.key === "Shift") {
        setShift(false)
        useKeyboardStore.getState().setShift(false)
      }
      if (e.key === "Control") {
        useKeyboardStore.getState().setCtrl(false)
      }
    }
    const wheel = (e: WheelEvent) => {
      e.preventDefault()
      const currentScale = useTopToolsStore.getState().scale
      let newScale = e.deltaY < 0 ? currentScale * 1.1 : currentScale * 0.9
      if (newScale >= 100) return
      setScale(newScale)
      setGroupScale(newScale)
    }

    const mouseclick = (_e: MouseEvent) => {
      useTopToolsStore.getState().setSubAttrPresetShow(false)
    }

    const mousemove = (event: { clientX: number; clientY: number }) => {
      paperContainerRef.current.handleCrosshairMove(event)
    }

    let element = document.getElementById("resize-container")
    document.addEventListener("keydown", down)
    document.addEventListener("keyup", up)
    element?.addEventListener("wheel", wheel)
    element?.addEventListener("mousedown", mouseclick)
    element?.addEventListener("mousemove", mousemove)

    return () => {
      document.removeEventListener("keydown", down)
      document.removeEventListener("keyup", up)
      element?.removeEventListener("wheel", wheel)
      element?.removeEventListener("mousedown", mouseclick)
      element?.removeEventListener("mousemove", mousemove)
    }
  }, [
    editMode,
    focusInput,
    getOperationSchema,
    handleShortcut,
    isView,
    projectDetail?.label_type,
    setEditMode,
    setGroupScale,
    setPressA,
    setScale,
    setShift,
  ])

  const setGlobalLoading = useCallback((flag: boolean) => {
    setLoading(flag)
  }, [])

  // 切换图片时清空复制保存的数组
  useEffect(() => {
    useKeyboardStore.getState().setCopyDataIds([])
  }, [activeImage])

  const handleBeforeUnload = (e: any) => {
    e.preventDefault()
    // 备份
    topRef.current.handleBackup("auto_backup")
    // 清空操作栏状态
    useObjectStore.getState().resetPathAndOperationStatus()
  }

  // 更新Splitter状态
  const updateSplitterSizes = useCallback(() => {
    console.log(
      "document.documentElement.clientWidth",
      document.documentElement.clientWidth
    )

    const len = document.documentElement.clientWidth - 4
    let arr = [len, 0, 0, 0, 0, 0]
    const flags = [
      showTaskList,
      showGroupList,
      showDescList && projectDetail && projectDetail.label_type === 5,
      showDescList && projectDetail && projectDetail.label_type === 6,
      showObjectList,
    ]
    let count = 0
    flags.forEach((flag) => {
      if (flag) count++
    })
    if (count === 1 || count === 2) {
      arr[0] = count === 1 ? len * 0.8 : len * 0.6
      flags.forEach((flag, index) => {
        if (flag) {
          arr[index + 1] = len * 0.2
        }
      })
    } else if (count === 3) {
      arr[0] = len * 0.55
      flags.forEach((flag, index) => {
        if (flag) {
          arr[index + 1] = len * 0.15
        }
      })
    } else if (count === 4) {
      arr[0] = len * 0.6
      flags.forEach((flag, index) => {
        if (flag) {
          arr[index + 1] = len * 0.1
        }
      })
    }
    setSizes(arr)
  }, [projectDetail, showDescList, showGroupList, showObjectList, showTaskList])

  useEffect(() => {
    updateSplitterSizes()
  }, [updateSplitterSizes])

  useEffect(() => {
    if (!isView) {
      const delay = 10 * 60000
      // 编辑模式下，修改labelData时启动或更新定时器
      useTimerStore.getState().startTimer(() => {
        useTopToolsStore.getState().setIsView(true)
      }, delay)
    } else {
      useTimerStore.getState().clearTimer()
    }

    // 组件卸载时清理定时器
    return () => {
      useTimerStore.getState().clearTimer()
    }
  }, [isView, labelData])

  // auto save
  useEffect(() => {
    if (isAutoSave && !isView) {
      const minute = 60 * 1000
      useIntervalStore.getState().startTimer(() => {
        topRef.current.handleSave()
      }, autoSaveGap * minute)
    } else {
      useIntervalStore.getState().clearTimer()
    }

    return () => {
      useIntervalStore.getState().clearTimer()
    }
  }, [autoSaveGap, isAutoSave, isView])

  useEffect(() => {
    window.addEventListener("beforeunload", handleBeforeUnload)
    return () => {
      window.removeEventListener("beforeunload", handleBeforeUnload)
    }
  }, [])

  const detectEnvironment = async () => {
    try {
      const result = await getName()
      console.log("Running in Tauri environment", result)
      return true
    } catch {
      // console.log("Not running in Tauri environment", error);
      return false
    }
  }

  // tauri://close-requested
  useEffect(() => {
    ;(async () => {
      if (await detectEnvironment()) {
        const window = getCurrentWindow()
        const unlisten = await window.onCloseRequested(async (event) => {
          useTopToolsStore.getState().setNeedBackup(true)
          event.preventDefault()
        })

        return () => {
          unlisten()
        }
      }
    })()
  }, [])

  const mainBoxHeight = useMemo(() => {
    if (projectDetail?.label_type === 5 && metaOperation) {
      let h = `calc(100% - ${headerHeight}px - 198px)`
      return h
    } else if (showMultiFrame) {
      let h = `calc(100% - ${headerHeight}px - 150px)`
      return h
    }
    let h = `calc(100% - ${headerHeight}px - 70px)`
    return h
  }, [projectDetail?.label_type, metaOperation, showMultiFrame, headerHeight])

  const fullscreenRef = useRef<HTMLDivElement>(null)

  return (
    <Stack w="100%" h="100vh" pos="relative" ref={fullscreenRef} gap={0}>
      <LoadingOverlay
        visible={loading}
        zIndex={2000}
        overlayProps={{ radius: "sm", blur: 2 }}
      />
      <Box w="100%" h={80}>
        <TopTools
          ref={topRef}
          taskDetail={taskDetail}
          projectDetail={projectDetail}
          oldWorkLoad={oldWorkLoad}
          updateOldWorkLoad={updateOldWorkLoad}
          isLabelTask={isLabelTask}
          renderPolygons={
            paperContainerRef.current
              ? paperContainerRef.current.renderPolygons
              : null
          }
        />
      </Box>
      <Flex w="calc(100% - 4px)" h={mainBoxHeight}>
        {/* <Flex h="100%" w={"100%"}> */}
        <Box w={sizes[0] - leftWidth} style={{ flexShrink: 0 }}>
          <Box h="100%" id="resize-container">
            <Flex h="100%" w="100%">
              <Flex
                direction="column"
                h="100%"
                w={`calc(100% - 64px)`}
                pos="relative"
                style={{ overflow: "hidden" }}>
                <ScaleComponent
                  options={{
                    offsetX: 0,
                    offsetY: 0,
                    scale: scale,
                  }}
                  mode="horizontal"
                />
                <Flex h="calc(100% - 32px)">
                  <ScaleComponent
                    options={{
                      offsetX: 0,
                      offsetY: 0,
                      scale: scale,
                    }}
                    mode="vertical"
                  />
                  <PaperContainer
                    imgSrc={"/test.jpeg"}
                    ref={paperContainerRef}
                    forceUpdate={forceUpdate}
                    labelState={labelState}
                    projectDetail={projectDetail}
                    updateLoadingFlag={setGlobalLoading}
                  />
                </Flex>
              </Flex>
              <ScaleToolContainer />
            </Flex>
          </Box>
        </Box>
        {showTaskList && (
          <Box w={sizes[1]} miw={300} style={{ flexShrink: 0 }}>
            <RightTaskTools
              projectDetail={projectDetail}
              project_id={projectId}
              task_id={taskId}
            />
          </Box>
        )}
        {showGroupList && (
          <Box w={sizes[2]} miw={200} style={{ flexShrink: 0 }}>
            <RightGroupTools
              labelState={labelState}
              projectDetail={projectDetail}
            />
          </Box>
        )}
        {showDescList && projectDetail && projectDetail.label_type === 5 && (
          <Box w={sizes[3]} miw={350} style={{ flexShrink: 0 }}>
            <RightDescTools taskDetail={taskDetail} />
          </Box>
        )}
        {showDescList && projectDetail && projectDetail.label_type === 6 && (
          <Box w={sizes[4]} miw={350} style={{ flexShrink: 0 }}>
            <RightQATools ref={qaToolContainerRef} taskDetail={taskDetail} />
          </Box>
        )}
        {showObjectList && (
          <Box w={sizes[5]} miw={350} style={{ flexShrink: 0 }}>
            <RightObjectTools
              taskDetail={taskDetail}
              labelState={labelState}
              projectDetail={projectDetail}
            />
          </Box>
        )}
        {/* </Flex> */}
      </Flex>
      <Box
        w="100%"
        h={projectDetail?.label_type === 5 && metaOperation ? 128 : 80}
        display={showMultiFrame ? "block" : "none"}>
        <BottomTools
          labelState={labelState}
          projectDetail={projectDetail}
          taskDetail={taskDetail}
          renderPolygons={
            paperContainerRef.current
              ? paperContainerRef.current.renderPolygons
              : null
          }
        />
      </Box>
      {isConfirmSave && (
        <ConfirmModal
          open={isConfirmSave}
          title="保存标注结果"
          content="是否确定保存当前标注结果？"
          onOk={async () => {
            try {
              await topRef.current?.handleSave()
              setIsConfirmSave(false)
            } catch {}
          }}
          onCancel={() => {
            setIsConfirmSave(false)
          }}
        />
      )}
    </Stack>
  )
}

export default LabelPage
