<script setup>
import ToastCreator from '~/components/daisy/DToast/toastCreator'
const { t } = useI18n()
let ImgList = $ref([])
let currentImg = $ref('')
let editImg = $ref()
const getImgFolder = async () => {
  ImgList = (await window.pywebview.api.getPersonalizationPrimaryImg())[1]
  currentImg = 0
}

// onBeforeMount(async () => {
//   // await getImgFolder()
//   // await getEditImg()
// })

let Drag = $ref(false)

const categories = [
  { supercategory: 'none', id: 1, name: 'closed_eye', color: '#E3170D85' },
  { supercategory: 'none', id: 2, name: 'closed_mouth', color: '#1E90FF85' },
  { supercategory: 'none', id: 3, name: 'open_eye', color: '#32CD3285' },
  { supercategory: 'none', id: 4, name: 'open_mouth', color: '#C0C0C085' },
]

let classIndex = $ref(2)
const changeIndex = (index) => {
  classIndex = index
}

const saveData = reactive({
  image: {
    file_name: '',
    height: 320,
    width: 320,
  },
  annotation: [],
})

const expertData = reactive({
  annotationData: {}, // 前端格式
  mergeData: {
    // COCO格式
    images: [],
    type: 'instances',
    annotations: [],
    categories,
  },
})

// 绑定DOM元素
const ImgLayer = $ref()
const TempLayer = $ref()
const DrawLayer = $ref()
let DrawCtx = $ref()
let myContext = $ref()
let TempCtx = $ref()
const canvasContainer = $ref() // 画布容器

// 变量
const editData = reactive({
  startX: 0,
  startY: 0,
  cRect: null,
  offsetX: null,
  offsetY: null,
})

const saveImgAnnotationData = () => {
  expertData.annotationData[saveData.image.file_name] = JSON.parse(
    JSON.stringify(saveData),
  )
  // saveData.annotation = [];
  // console.log(expertData.annotationData);
  const toast = new ToastCreator({ message: '图片标注结果已保存', type: 'success', duration: 1500 })
  toast.createToast()
}

const clearCanvas = (isSave = true) => {
  DrawCtx.clearRect(0, 0, DrawLayer.width, DrawLayer.height)
  saveData.annotation = []
  if (saveData.image.file_name !== '' && isSave)
    saveImgAnnotationData()
}

const getEditImg = async (num = 0) => {
  if (currentImg + num < ImgList.length && currentImg + num >= 0) {
    currentImg += num
  }
  else {
    (new ToastCreator({
      message: '到底/顶啦！',
      type: 'success',
      duration: 1500,
    })).createToast()
  }
  const imgData = (await window.pywebview.api.getPrimaryListImg(ImgList[currentImg]))
  editImg = `data:image/png;base64,${imgData}`
  const myImage = new Image()
  myImage.src = editImg
  // console.log(e.target.result)
  myImage.onload = function (ev) {
    clearCanvas(false)
    saveData.image.file_name = ImgList[currentImg]
    saveData.image.height = myImage.height
    saveData.image.width = myImage.width

    DrawLayer.setAttribute('width', myImage.width)
    DrawLayer.setAttribute('height', myImage.height)
    TempLayer.setAttribute('width', myImage.width)
    TempLayer.setAttribute('height', myImage.height)
    ImgLayer.setAttribute('width', myImage.width)
    ImgLayer.setAttribute('height', myImage.height)
    canvasContainer.style.width = `${myImage.width}px`
    canvasContainer.style.height = `${myImage.height}px`

    // 将图片读入canvas

    myContext.drawImage(
      myImage,
      0,
      0,
      myImage.width,
      myImage.height,
      0,
      0,
      myImage.width,
      myImage.height,
    )

    TempCtx.fillStyle = categories[classIndex].color
    DrawCtx.fillStyle = categories[classIndex].color

    // let imgData = ImgLayer.toDataURL("image/jpeg",0.75)
    // console.log(imgData)

    // 读取已有的标注数据
    if (expertData.annotationData[saveData.image.file_name]) {
      saveData.annotation = expertData.annotationData[
        saveData.image.file_name
      ].annotation
      saveData.annotation.forEach((item) => {
        // 更换画笔颜色
        DrawCtx.fillStyle = categories[item.category_id - 1].color
        DrawCtx.fillRect(
          item.bbox[0],
          item.bbox[1],
          item.bbox[2],
          item.bbox[3],
        )
      })
    }
  }
}

const DrawLayerMouseup = (e) => {
  Drag = false

  const mouseX = Math.round(e.clientX - editData.offsetX)
  const mouseY = Math.round(e.clientY - editData.offsetY)

  const Width = mouseX - editData.startX
  const Height = mouseY - editData.startY

  TempCtx.clearRect(0, 0, TempLayer.width, TempLayer.height)
  DrawCtx.fillRect(editData.startX, editData.startY, Width, Height)

  const annotation = {
    area: Math.round(Width * Height),
    iscrowd: 0,
    bbox: [editData.startX, editData.startY, Width, Height],
    category_id: categories[classIndex].id,
    ignore: 0,
    // "image_id": saveData.image.id,
    // "id": saveData.annotation.length
  }
  if (annotation.area !== 0)
    saveData.annotation.push(annotation)
}

const DrawLayerMousedown = (e) => {
  editData.cRect = TempLayer.getBoundingClientRect()
  editData.offsetX = editData.cRect.left
  editData.offsetY = editData.cRect.top
  const cX = Math.round(e.clientX - editData.offsetX)
  const cY = Math.round(e.clientY - editData.offsetY)

  Drag = true
  editData.startX = cX
  editData.startY = cY

  TempCtx.fillStyle = categories[classIndex].color
  DrawCtx.fillStyle = categories[classIndex].color
}

const DrawLayerMousemove = (e) => {
  if (Drag === true) {
    const mouseX = Math.round(e.clientX - editData.offsetX)
    const mouseY = Math.round(e.clientY - editData.offsetY)

    const Width = mouseX - editData.startX
    const Height = mouseY - editData.startY

    TempCtx.clearRect(
      0,
      0,
      TempLayer.width,
      TempLayer.height,
    )
    TempCtx.fillRect(editData.startX, editData.startY, Width, Height)
  }
}

const unFinished = () => {
  alert('目前仅支持云端训练，且只支持手动上传数据集，后续会支持更多功能')
}

const expertAllData = async () => {
  const imgData = []
  let annotationData = []
  let id = 0
  let anno_id = 0
  for (const key in expertData.annotationData) {
    const img = JSON.parse(
      JSON.stringify(expertData.annotationData[key].image),
    )
    img.id = id
    imgData.push(img)
    const annotation = JSON.parse(
      JSON.stringify(expertData.annotationData[key].annotation),
    )
    for (let i = 0; i < annotation.length; i++) {
      annotation[i].image_id = id
      annotation[i].id = anno_id
      anno_id++
    }
    annotationData = [...annotationData, ...annotation]
    id++
  }
  expertData.mergeData.images = imgData
  expertData.mergeData.annotations = annotationData
  await window.pywebview.api.saveAnnotationData(expertData.annotationData, expertData.mergeData)

  const toast = new ToastCreator({ message: '数据集标注结果已保存', type: 'success', duration: 1500 })
  toast.createToast()
  unFinished()
}

watch(
  () => classIndex,
  (newVal, oldVal) => {
    TempCtx.fillStyle = categories[newVal].color
    DrawCtx.fillStyle = categories[newVal].color
  },
)
onBeforeMount(async () => {
  const getAnnotationData = await window.pywebview.api.getAnnotationData()
  if (JSON.stringify(getAnnotationData) !== '{}') {
    expertData.annotationData = getAnnotationData.annotationData
    expertData.mergeData = getAnnotationData.mergeData
  }
})
onMounted(async () => {
  await getImgFolder()
  await getEditImg()
  myContext = ImgLayer.getContext('2d')
  DrawCtx = DrawLayer.getContext('2d')
  TempCtx = TempLayer.getContext('2d')
})
</script>

<template>
  <div>
    <div class="hero justify-start">
      <div class="hero-content flex-col items-end pb-0">
        <div class=" flex">
          <!-- <router-link to="/" class="text-3xl">
            <div i-carbon-arrow-left class="mr-2 hover:bg-primary" />
          </router-link> -->
          <div>
            <ul class="steps">
              <li class="step step-primary">
                {{ t('Personalization.Collect') }}
              </li>
              <li class="step step-primary">
                {{ t('Personalization.Annotations') }}
              </li>
              <li class="step">
                {{ t('Personalization.Train') }}
              </li>
            </ul>
          </div>
        </div>
        <!-- <div class="text-gray-500">
          修改后重启生效
        </div> -->
      </div>
    </div>

    <div class="flex justify-center flex-col items-center">
      <div text-3xl class="label-title">
        图像标注
      </div>
      <div flex items-center mt-2>
        <div class="label-left mr-4">
          <div>
            <ul class="menu bg-base-100 p-1 py-2 rounded-box border">
              <li class="menu-title">
                <span>标注类别-眼睛</span>
              </li>
              <li @click="changeIndex(2)">
                <a :class="classIndex === 2 ? 'active' : ''"><div i-mingcute-eye-line />眼睛开</a>
              </li>
              <li @click="changeIndex(0)">
                <a :class="classIndex === 0 ? 'active' : ''"><div i-mingcute-eye-close-fill />眼睛闭</a>
              </li>
              <li class="menu-title">
                <span>标注类别-嘴巴</span>
              </li>
              <li @click="changeIndex(3)">
                <a :class="classIndex === 3 ? 'active' : ''"><div i-icon-park-outline-surprised-face-with-open-big-mouth />嘴巴开</a>
              </li>
              <li @click="changeIndex(1)">
                <a :class="classIndex === 1 ? 'active' : ''"><div i-icon-park-outline-face-without-mouth />嘴巴闭</a>
              </li>
            </ul>
          </div>
          <div />
          <div class="stats stats-vertical border mt-4">
            <div class="stat">
              <div class="stat-title flex items-center">
                <div i-ri-quill-pen-fill />已标记
              </div>
              <div class="stat-value">
                {{ ImgList.length }}
              </div>
            </div>

            <div class="stat">
              <div class="stat-title flex items-center">
                <div i-ep-warn-triangle-filled />未标记
              </div>
              <div class="stat-value">
                {{ ImgList.length - Object.keys(expertData.annotationData).length }}
              </div>
            </div>
          </div>
        </div>
        <div class="label-center flex ">
          <!-- <img class="max-w-full h-100 rounded-lg bg-contain bg-clip-border" :src="editImg" alt="image description"> -->
          <div ref="canvasContainer" class="container border" style="width:320px;height:320px;">
            <div class="CanvasWrapper">
              <canvas ref="ImgLayer" width="320" height="320" />
              <canvas ref="TempLayer" width="320" height="320" />
              <canvas
                ref="DrawLayer" width="320" height="320" @mousemove="DrawLayerMousemove"
                @mouseup="DrawLayerMouseup" @mousedown="DrawLayerMousedown"
              />
            </div>
          </div>
        </div>
        <div class="label-right ml-4 flex flex-col space-y-6">
          <div class="tooltip tooltip-right tooltip-primary" data-tip="上一张">
            <button class="btn btn-square btn-primary " @click="getEditImg(-1)">
              <div i-material-symbols-keyboard-double-arrow-up-rounded text-2xl />
            </button>
          </div>
          <div class="tooltip tooltip-right tooltip-primary" data-tip="清除">
            <button class="btn btn-square btn-primary " @click="clearCanvas">
              <div i-carbon-clean text-2xl />
            </button>
          </div>
          <div class="tooltip tooltip-right tooltip-primary" data-tip="保存" @click="saveImgAnnotationData">
            <button class="btn btn-square btn-primary ">
              <div i-material-symbols-save-as-rounded text-2xl />
            </button>
          </div>
          <div class="tooltip tooltip-right tooltip-primary" data-tip="下一张">
            <button class="btn btn-square btn-primary " @click="getEditImg(1)">
              <div i-material-symbols-keyboard-double-arrow-down-rounded text-2xl />
            </button>
          </div>
          <!-- <div class="label-imgs h-96 carousel carousel-vertical rounded-md">
            <div class="carousel-item h-2/5 indicator hover:cursor-pointer">
              <span class="indicator-item badge badge-primary indicator-start indicator-bottom "><div i-carbon:checkmark-filled />已标注</span>
              <img src="/Snipaste_2022-12-01_22-59-42.png">
            </div>
            <div class="carousel-item h-2/5 mt-1">
              <img src="/Snipaste_2022-12-01_22-59-42.png">
            </div>
            <div class="carousel-item h-2/5 mt-1">
              <img src="/Snipaste_2022-12-01_22-59-42.png">
            </div>
            <div class="carousel-item h-2/5 mt-1">
              <img src="/Snipaste_2022-12-01_22-59-42.png">
            </div>
          </div> -->
        </div>
      </div>
    </div>

    <div class="w-full flex justify-around mt-4">
      <div class="flex-col items-end">
        <div class=" flex">
          <router-link to="/Personalization">
            <button class="btn btn-primary ">
              <div i-carbon-arrow-left />采集
            </button>
          </router-link>
        </div>
      </div>
      <div class="flex-col items-end">
        <div class="btn-group">
          <button class="btn hover:btn-primary" @click="expertAllData()">
            <router-link class="flex items-center">
              <div i-mingcute-cloud-line />云端训练
            </router-link>
          </button>
          <button class="btn hover:btn-primary" @click="expertAllData()">
            <router-link class="flex items-center">
              <div i-mingcute-computer-line />本地训练
            </router-link>
          </button>
        </div>
      </div>
    </div>
  </div>
</template>

<style  scoped>
.indicator {
  position: relative;
  display: inline-flex;
  width: max-content;
}
.indicator :where(.indicator-item) {
  z-index: 1;
  position: absolute;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item) {
  right: 0px;
  left: auto;
  top: 0px;
  bottom: auto;
  --tw-translate-x: 50%;
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-start) {
  right: auto;
  left: 0px;
  --tw-translate-x: 0%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-center) {
  right: 50%;
  left: 50%;
  --tw-translate-x: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-end) {
  right: 0px;
  left: auto;
  --tw-translate-x: 50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-bottom) {
  top: auto;
  bottom: 0px;
  --tw-translate-y: -15%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-middle) {
  top: 50%;
  bottom: 50%;
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}
.indicator :where(.indicator-item.indicator-top) {
  top: 0px;
  bottom: auto;
  --tw-translate-y: -50%;
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
}

.stat {
    display: inline-grid;
    width: 100%;
    grid-template-columns: repeat(1, 1fr);
    -moz-column-gap: 1rem;
    column-gap: 1rem;
    border-color: hsl(var(--bc) / var(--tw-border-opacity));
    --tw-border-opacity: 0.1;
    padding-left: 1.5rem;
    padding-right: 1.5rem;
    padding-top: .5rem;
    padding-bottom: .5rem;
}

.CanvasWrapper {
  position: relative;
  width: 100%;
}

.CanvasWrapper canvas {
  position: absolute;
}
</style>
