<template>
  <div :key="p.key" class="fp-editor-wrapper" :style="{ 'width': wpx, 'height': hpx }">
    <div class="fp-poster-canvas" :style="{ 'width': wpx, 'height': hpx }">
      <div class="fp-poster" id="key-down" :tabindex="0" @keydown="keydownHandler" @click.stop="cancelActive"
        :style="pointerStyle">
        <fp-poster-item v-for="item in p.items" :key="item.uuid" @click.native="click($event, item)" :item="item" />
      </div>
      <fp-lock v-if="ai && ai.lock" :scale="scale" :item="ai"></fp-lock>
      <fp-drag ref="fpDragRef" v-if="ai && !ai.lock" :width="w" :height="h" :scale="scale"
        @dblclick.native="dblclickDrag($event)" @change="change" @changeEnd="changeEnd"></fp-drag>
      <fp-line ref="fpLineRef"></fp-line>
    </div>
    <div id="imgViewer">
      <img ref="previewImg">
    </div>
  </div>
</template>

<script>
import http from '@/api/fastposter'
import fpDrag from '@/components/fastposter/drag/FpDrag.vue'
import fpLine from '@/components/fastposter/drag/FpLine.vue'
import fpLock from '@/components/fastposter/drag/FpLock.vue'
import Viewer from 'viewerjs'
import 'viewerjs/dist/viewer.css'
import { mapActions, mapGetters, mapMutations, mapState } from 'vuex'
import { EVENT_KEYS } from '../drag/eventBus'
import FpPosterItem from "./FpPosterItem.vue"
export default {
  name: "FpPoster",
  components: { FpPosterItem, fpDrag, fpLock, fpLine },
  computed: {
    ...mapState({
      'p': state => state.poster.p
    }),
    ...mapGetters({
      'w': 'poster/w',
      'h': 'poster/h',
      'scale': 'poster/scale',
      'ai': 'poster/ai',
    }),
    wpx() {
      return this.w * this.scale + 'px'
    },
    hpx() {
      return this.h * this.scale + 'px'
    },
    pointerStyle() {
      return {
        'width': this.wpx,
        'height': this.hpx,
        'background-color': this.p.bgc,
        'background-size': `${this.wpx} ${this.hpx}`,
        'background-image': this.p.use === 'bgUrl' ? `url(${http.imgUrl(this.p.bgUrl)})` : ''
      }
    }
  },
  watch: {
    ai: {
      handler(newVal, oldVal) {
        if (newVal && !newVal.lock) {
          this.$nextTick(() => {
            this.$refs.fpDragRef.setItem(newVal)
          })
        } else {
          this.isTextEdit(false)
        }
      },
      deep: true
    }
  },
  mounted() {
    if (this.$route.query.id) {
      this.loadPoster(this.$route.query.id)
    } else {
      this.clear()
      this.createPoster(this.$route.query.appId)
    }
    this.$EventBus.$on(EVENT_KEYS.UPDATE_DRAG, (type) => {
      this.$refs.fpDragRef?.setItem(this.ai)
    })
    this.$EventBus.$on(EVENT_KEYS.UPDATE_RECORD, (type) => {
      this.changeEnd('', type)
    })

  },
  beforeDestroy() {
    this.$EventBus.$off(EVENT_KEYS.UPDATE_DRAG)
    this.$EventBus.$off(EVENT_KEYS.UPDATE_RECORD)
  },
  methods: {
    ...mapMutations({
      'setActiveItemId': 'poster/setActiveItemId',
      'record': 'snapshots/record',
      'undo': 'snapshots/undo',
      'redo': 'snapshots/redo',
      'up': 'poster/up',
      'down': 'poster/down',
      'clear': 'snapshots/clear',
      'removeActiveItem': 'poster/removeActiveItem',
      'copyActiveItem': 'poster/copyActiveItem',
      'changeActiveItem': 'poster/changeActiveItem',
      'setUnActiveAllItem': 'poster/setUnActiveAllItem',
      'isTextEdit': 'poster/isTextEdit',
    }),
    ...mapActions({
      'createPoster': 'poster/createPoster',
      'copyPoster': 'poster/copyPoster',
      'loadPoster': 'poster/loadPoster',
      'savePoster': 'poster/savePoster',
      'previewPoster': 'poster/previewPoster',
    }),
    click(ev, item) {
      // 不要向上传递
      ev = ev || window.event
      ev.stopPropagation()
      if (!item.bool) {
        this.setActiveItemId(item.uuid)
        this.$nextTick(() => {
          this.$refs.fpDragRef.setItem(item)
        })
      }
    },
    cancelActive(ev) {
      console.log('cancelActive')
      this.setUnActiveAllItem()
    },
    change(uuid, type, drag) {
      this.changeActiveItem(drag)
      this.$refs.fpLineRef?.showLine()
    },
    preview() {
      const img = this.$refs.previewImg
      this.previewPoster().then(r => {
        img.src = window.URL.createObjectURL(r)
        const viewer = new Viewer(document.getElementById('imgViewer'), {
          hide() {
            viewer.destroy()
          }
        })
        viewer.show()
      })
    },
    dblclickDrag(ev) {
      console.log('dblclickDrag')
      ev.stopPropagation()
      if (this.ai.t == 'text') {
        this.isTextEdit(true)
      }
    },

    changeEnd(uuid, type) {
      switch (type) {
        case 'move':
          this.record(`${this.ai?.name} 移动位置 `)
          break
        case 'rotate':
          this.record(`${this.ai?.name} 旋转角度 `)
          break
        default:
          this.record(`${this.ai?.name} 更改尺寸 `)
          break
      }
      this.$refs.fpLineRef?.hideLine()
    },

    keydownHandler(e) {
      // 不需要选中元素的情况
      switch (e.code) {
        case 'KeyZ':
          if ((e.ctrlKey || e.metaKey) && e.shiftKey) {
            this.redo()
          } else if (e.ctrlKey || e.metaKey) {
            this.undo()
          }
          break
        case 'KeyP':
          if (e.ctrlKey || e.metaKey) {
            e.preventDefault()  // 阻止默认行为
            this.preview()
          }
          break
        case 'KeyS':
          if (e.ctrlKey || e.metaKey) {
            e.preventDefault()  // 阻止默认行为
            this.savePoster().then(r => {
              this.$message({
                message: '保存成功',
                type: 'success',
                duration: 1000
              })
            })
          }
          break
      }
      console.log(e)
      // 必须有选中元素的情况
      let item = this.ai
      if (!item) {
        return
      }

      let i = e.altKey ? 5 : e.metaKey || e.ctrlKey ? 10 : 1       // 每次移动间隔 +cmd = 10, +alt = 5
      switch (e.code) {
        case 'ArrowLeft':
          if (!this.ai.bool) {
            item.x -= i
            e.preventDefault()  // 阻止默认行为
          }
          break
        case 'ArrowRight':
          if (!this.ai.bool) {
            item.x += i
            e.preventDefault()  // 阻止默认行为
          }
          break
        case 'ArrowUp':
          if (e.shiftKey) {
            this.up(item)
          } else {
            item.y -= i
          }
          e.preventDefault()  // 阻止默认行为
          break
        case 'ArrowDown':
          if (e.shiftKey) {
            this.down(item)
          } else {
            item.y += i
          }
          e.preventDefault()  // 阻止默认行为
          break
        case 'Delete':
        case 'Backspace':
          if (!this.ai.bool) {
            this.removeActiveItem()
            this.record(`删除组件: ${item.name} - ${item.uuid}`)
          }
          break
        case 'KeyV':
          if (e.ctrlKey || e.metaKey) {
            this.copyActiveItem(item)
            this.record(`复制组件: ${this.ai.name} - ${this.ai.uuid}`)
          }
          e.preventDefault()  // 阻止默认行为
          break
      }

    }
  }
}
</script>

<style scoped>
.fp-editor-wrapper {
  position: relative;
  box-sizing: initial;
  margin: 0 auto;
  overflow: visible;
  padding: 100px;
  width: 360px;
  height: 640px;
  outline: none;
}

.fp-poster-canvas {
  z-index: 1;
  user-select: none;
  position: relative;
}

.fp-poster {
  width: 360px;
  height: 640px;
  background-color: #fff;
  position: relative;
  box-shadow: 1px 1px 15px rgba(0, 0, 0, 0.2);
  background-repeat: no-repeat;
  overflow: hidden;
  outline-width: 0px;
}
</style>