<template>
  <div
      ref="wrapperRef"
      @mousedown="addDrawAreaFocus"
      v-contextmenu="contextMenus"
      v-click-outside="remDrawAreaFocus"
  >
    <canvas ref="canvasRef" class="background-grid"></canvas>
  </div>
</template>

<script lang="ts" setup>
import {storeToRefs} from 'pinia'
import {computed, onMounted, onUnmounted, ref} from 'vue'
import {useFabricStore, useMainStore, useTemplatesStore, useUserStore} from '@/store'
import {useRouter} from 'vue-router'
import {unzip} from "@/utils/crypto"
import {getDesignTemplateEdit, getPreViewTemplate, getTemplateData, newDesignOrder, tmpSaveUserDesign, updateDesignTemplate} from '@/api/template'
import {contextMenus} from '@/configs/contextMenu'
import useCanvas, {initEditor} from '@/views/Canvas/useCanvas'
import {initPixi} from '@/views/Canvas/usePixi'
import {ElMessage, ElLoading} from 'element-plus'
import useCanvasHotkey from '@/hooks/useCanvasHotkey'
import useCanvasExport from "@/hooks/useCanvasExport";
import {WorkSpaceElement} from "@/types/canvas";
import {propertiesToInclude, WorkSpaceDrawType} from "@/configs/canvas";
import {Pattern} from "fabric";
import {MaxSize, MinSize, TransparentFill} from "@/configs/background";
import {mm2px, px2mm} from "@/utils/image";


const fabricStore = useFabricStore()
const mainStore = useMainStore()
const {sizeMode, unitMode} = storeToRefs(mainStore);
const {clip, safe, zoom, opacity} = storeToRefs(fabricStore);
const router = useRouter()
const templatesStore = useTemplatesStore()
const userStore = useUserStore()
const {uuid} = storeToRefs(userStore);
const {wrapperRef, canvasRef} = storeToRefs(fabricStore)
const {getJSONData, getSVGData} = useCanvasExport()
let outerSessionId = ""
let tmpSaveFlag = true

const {drawAreaFocus} = storeToRefs(mainStore)
const {keydownListener, keyupListener, pasteListener} = useCanvasHotkey()


const addDrawAreaFocus = () => {
  if (!drawAreaFocus.value) mainStore.setDrawAreaFocus(true)
}

const remDrawAreaFocus = () => {
  if (drawAreaFocus.value) mainStore.setDrawAreaFocus(false)
}

const getTemplateDetail = async (pk: number) => {
  // const result = await getTemplateData(pk)
  // if (result.data && result.data.code === 200 && result.data.data) {
  //   try {
  //     router.push(`${router.currentRoute.value.path}?template=${pk}`)
  //     console.log('result.data.data.id:', result.data.data.id)
  //     const data = unzip(result.data.data.data)
  //     await templatesStore.changeTemplate(data)
  //   } catch (error) {
  //     ElMessage({
  //       type: 'error',
  //       message: '模板加载失败,请联系管理员修改bug了',
  //     })
  //   }
  // }

  //todo 传参测试
  const templateParams = {
    backgroundWidth: 250.0,
    backgroundHeight: 300.0,
    backgroundColor: 'rgba(200, 100, 100, 1)'
  }
  const params = {
    id: pk,
    // params: JSON.stringify(templateParams)
  }
  const res = await getDesignTemplateEdit(params)

  if (res.httpCode == 200) {
    try {
      templatesStore.setTemplateName(res.data.templateName)
      templatesStore.setProductIdentity(res.data.productIdentity ? res.data.productIdentity.split(",") : [])
      const data = res.data.jsonContent
      await templatesStore.changeTemplate(JSON.parse(data))
    } catch (e) {
      ElMessage({
        type: 'error',
        message: '模板加载失败,请联系系统管理员',
      })
    }
  }
}

const getPreviewTemplateDetail = async (pk: number, templateParams: any, outerSessionId: any) => {
  //todo 传参测试
  // const templateParams = {
  //   backgroundWidth: 250.0,
  //   backgroundHeight: 300.0,
  //   backgroundColor: 'rgba(200, 100, 100, 1)'
  // }
  if (!outerSessionId) return

  let params = {}
  if (!templateParams) {
    params = {
      id: pk,
      outerSessionId: outerSessionId
    }
  } else {
    params = {
      id: pk,
      params: JSON.stringify(templateParams),
      outerSessionId: outerSessionId
    }
  }
  const res = await getPreViewTemplate(params)

  if (res.httpCode == 200) {
    try {
      templatesStore.setTemplateName(res.data.templateName)
      templatesStore.setProductIdentity(res.data.productIdentity ? res.data.productIdentity.split(",") : [])
      const data = res.data.jsonContent
      await templatesStore.changeTemplate(JSON.parse(data))
    } catch (e) {
      ElMessage({
        type: 'error',
        message: '模板加载失败,请联系系统管理员',
      })
    }
  }
}

const initRouter = async (templateId: number, runMode: number, outerSessionId: any) => {
  if (templateId) {
    templatesStore.setTemplateId(templateId)
    const loadingInstance = ElLoading.service({fullscreen: true, background: 'rgba(122, 122, 122, 0.5)'})
    //判断一下是后台设计还是前台预览
    if (runMode == 1) {
      await getTemplateDetail(templateId)
    } else if (runMode == 0) {
      await getPreviewTemplateDetail(templateId, null, outerSessionId)
    }
    nextTick(() => loadingInstance.close())
  }
}

//递归调用的目的是不会导致任务堆积,虽然也没什么可能存一下超过5秒
const tmpSaveCurrentTemplate = () => {
  if (tmpSaveFlag) {
    const tmpTemplate = {
      templateName: outerSessionId,
      jsonContent: getJSONData()
    }

    tmpSaveUserDesign(JSON.stringify(tmpTemplate)).then((res) => {
      if (res.httpCode == 200) {
        // ElMessage.success('暂存成功')
        setTimeout(tmpSaveCurrentTemplate, 5000);
      }
    })
  }
}

onMounted(async () => {
  const query = router.currentRoute.value.query
  initRouter(query.template, query.runMode, query.sessionId)
  initEditor(query.template)
  initPixi()
  outerSessionId = query.sessionId
  document.addEventListener('keydown', keydownListener)
  document.addEventListener('keyup', keyupListener)
  window.addEventListener('blur', keyupListener)
  window.addEventListener('paste', pasteListener as any)

  if (query.runMode == 0) {
    // 使用iframe方案,本网页是内嵌页面
    // 监听来自父页面的消息
    window.addEventListener("message", function (event) {
      // 确保消息来自信任的来源
      // if (event.origin !== "https://www.sd2000.com") {
      //   return;
      // }

      // 处理接收到的消息
      console.log("Received message:", event.data);

      //消息格式
      // {
      //   msgType: 'loadTemplate',
      //   data: {
      //      xxx
      //   }
      // }
      const message = JSON.parse(event.data);

      if (message.msgType == "loadTemplate") {
        // getPreviewTemplateDetail(query.template, message.data, outerSessionId)
        // 这个地方有未知原因,重新加载模板后会让canvas渲染停止,用别的方法该参数吧

        // const formData = ref({
        //   backgroundWidth: 2000.0,
        //   backgroundHeight: 400.0,
        //   backgroundColor: "rgba(255,0,0,1)",
        //   objects: "",
        // });
        const color = message.data.backgroundColor
        const width = mm2px(message.data.backgroundWidth) * zoom.value
        const height = mm2px(message.data.backgroundHeight) * zoom.value
        updateBackground({color: color, fill: color})
        changeTemplateSize(width, height)
      } else if (message.msgType == "submitOrder") {
        //提交当前设计
        // const svgData: string[] = []
        // svgData.push(btoa(unescape(encodeURIComponent(getSVGData()))))

        // exportSVG()

        //先停止自动暂存定时器
        tmpSaveFlag = false

        const svgHtml = getSVGData()
        console.log(svgHtml)
        newDesignOrder(svgHtml, uuid.value).then((response) => {
          if (response.httpCode == 200) {
            console.log(response.data)

            //给父页面发送canClose消息,表示可以关掉本页面了
            const closeMsg = {
              msgType: 'canClose'
            }
            window.parent.postMessage(JSON.stringify(closeMsg), '*');
          }
        });

      }
    })

    //每隔5秒暂存一次用户的设计
    setTimeout(tmpSaveCurrentTemplate, 5000);
  }
})

onUnmounted(() => {
  document.removeEventListener('keydown', keydownListener)
  document.removeEventListener('keyup', keyupListener)
  window.removeEventListener('blur', keyupListener)
  window.removeEventListener('paste', pasteListener as any)
})

//以下是loadTemplate需要的东西,当前已放弃后台渲染,直接纯前端操作了
const {currentTemplate} = storeToRefs(templatesStore);
const background = computed(() => {
  if (!currentTemplate.value) {
    return {
      fillType: 0,
      fill: TransparentFill,
      backgroundColor: "#fff",
    } as WorkSpaceElement;
  }
  if (!currentTemplate.value.workSpace) {
    return {
      fillType: 0,
      fill: TransparentFill,
      backgroundColor: "#fff",
    } as WorkSpaceElement;
  }
  return currentTemplate.value.workSpace;
});
// 设置背景
const updateBackground = (props: Partial<WorkSpaceElement>) => {
  const [canvas] = useCanvas();
  const workSpaceDraw = canvas.getObjects().filter((item) => item.id === WorkSpaceDrawType)[0];
  if (!workSpaceDraw) return;
  workSpaceDraw.set({...props});
  if (props.fill instanceof Pattern) {
    props.fill = props.fill.toObject() as Pattern
  }
  templatesStore.updateWorkSpace({workSpace: {...background.value, ...props}});
  const workProps = workSpaceDraw.toObject(propertiesToInclude as any[]);
  templatesStore.updateElement({id: workSpaceDraw.id, props: {...workProps, ...props}});
  canvas.renderAll();
};

const templateWidth = computed(() => {
  const workWidth = currentTemplate.value.width / currentTemplate.value.zoom;
  return unitMode.value === 0 ? px2mm(workWidth) : workWidth;
});
const templateHeight = computed(() => {
  const workHeight = currentTemplate.value.height / currentTemplate.value.zoom;
  return unitMode.value === 0 ? px2mm(workHeight) : workHeight;
});
const canvasWidth = ref<number>(templateWidth.value);
const canvasHeight = ref<number>(templateHeight.value);
// 固定宽高
const isFixed = ref(false);
// 获取画布尺寸
const getCanvasSize = () => {
  let width =
      unitMode.value === 0 ? mm2px(canvasWidth.value) : canvasWidth.value;
  let height =
      unitMode.value === 0 ? mm2px(canvasHeight.value) : canvasHeight.value;
  width = width * zoom.value;
  height = height * zoom.value;
  return {width, height};
};

// 修改画布宽度
const changeTemplateSize = (width, height) => {
  const [canvas] = useCanvas();
  const workSpaceDraw = canvas
      .getObjects()
      .filter((item) => item.id === WorkSpaceDrawType)[0];
  if (!workSpaceDraw) return;
  const ratio = currentTemplate.value.height / currentTemplate.value.width;
  // let {width, height} = getCanvasSize();
  if (width / zoom.value < mm2px(MinSize)) {
    ElMessage({
      message: t("style.minimumSizeLimit") + MinSize,
      type: "warning",
    });
    width = mm2px(MinSize) * zoom.value;
  }
  if (width / zoom.value > mm2px(MaxSize)) {
    ElMessage({
      message: t("style.maximumSizeLimit") + MaxSize,
      type: "warning",
    });
    width = mm2px(MaxSize) * zoom.value;
  }
  if (height / zoom.value < mm2px(MinSize)) {
    ElMessage({
      message: t("style.minimumSizeLimit") + MinSize,
      type: "warning",
    });
    height = mm2px(MinSize) * zoom.value;
  }
  if (height / zoom.value > mm2px(MaxSize)) {
    ElMessage({
      message: t("style.maximumSizeLimit") + MaxSize,
      type: "warning",
    });
    height = mm2px(MaxSize) * zoom.value;
  }
  // width = isFixed.value ? height / ratio : width;
  // height = isFixed.value ? width * ratio : height;
  workSpaceDraw.set({width: width / zoom.value, height: height / zoom.value});
  templatesStore.setSize(width, height, zoom.value);
  sizeMode.value = 2;
  canvas.renderAll();
  // resetCanvas()
  // addHistorySnapshot();
};


</script>

<style lang="scss" scoped>
.full-size {
  height: 100%;
  width: 100%;
}

.background-grid {
  --offsetX: 0px;
  --offsetY: 0px;
  --size: 8px;
  --color: #dedcdc;
  background-image: linear-gradient(45deg, var(--color) 25%, transparent 0, transparent 75%, var(--color) 0),
  linear-gradient(45deg, var(--color) 25%, transparent 0, transparent 75%, var(--color) 0);
  background-position: var(--offsetX) var(--offsetY), calc(var(--size) + var(--offsetX)) calc(var(--size) + var(--offsetY));
  background-size: calc(var(--size) * 2) calc(var(--size) * 2);
}
</style>@/views/Canvas/usePixi
