import { Component, Prop, Mixins, Watch } from 'vue-property-decorator';
import ContextMenuMixin from '@editor/mixins/contextMenu.mixin';
import TransformStyleMixin from '@/page/mixins/transformStyle.mixin';
import { cloneDeep, pick, omit, throttle } from 'lodash';
import { Action, Mutation, State, Getter } from 'vuex-class';
import { convertPointStyle, getStyle } from '@/service/utils.service';
import EventBus from '@service/eventBus.service';
// import CsGuideCube from '@/lib/DownloadGuide/index.vue';
// import CsMarquee from '@/lib/Marquee/index.vue';

@Component({ components: { }, name: 'FreedomContainer' })
export default class FreedomContainer extends Mixins(ContextMenuMixin, TransformStyleMixin) {
  @Action('setDragable') setDragable;
  @State(state => state.editor.curEleIndex) curEleIndex;
  @State(state => state.editor.curChildIndex) curChildIndex;
  @Getter('pageData') pageData;

  @Prop({type: Object, default: () => ({ child: [] })}) childItem;
  @Prop({type: Number, default: 0}) containerIndex;
  @Prop({ type: Boolean, default: false }) showHeader;
  @Prop(String) backgroundImage;
  @Prop({ type: String, default: '#fff' }) backgroundColor;

  dots: object = {};

  mousedown(childIndex, event) {
    this.setDragable(false);
    const childItem = cloneDeep(this.childItem);
    const { top: startTop, left: startLeft } = childItem.child[childIndex].commonStyle;
    const { clientY, clientX } = event;

    const move = throttle(moveEvent => {
      moveEvent.stopPropagation();
      moveEvent.preventDefault();

      const top = moveEvent.clientY - clientY + startTop;
      const left = moveEvent.clientX - clientX + startLeft;

      this.updatePageInfo({ containerIndex: this.containerIndex, childIndex, data: { ...childItem.child[childIndex], commonStyle: {...childItem.child[childIndex].commonStyle, top, left} } });
    }, 50);
    const up = () => {
      this.setDragable(true);
      document.removeEventListener('mousemove', move, true);
      document.removeEventListener('mouseup', up, true);
    };
    document.addEventListener('mousemove', move, true);
    document.addEventListener('mouseup', up, true);
  }

  handleElementClick(curEleIndex, curChildIndex) {
    this.$emit('handleElementClick', curEleIndex, curChildIndex);
  }

  get commonStyle() {
    if ((this.curEleIndex || this.curEleIndex === 0 ) && (this.curChildIndex || this.curChildIndex === 0)) {
      return this.pageData?.elements[this.curEleIndex]?.child[this.curChildIndex]?.commonStyle;
    }
    return null;
  }

  @Watch('curChildIndex')
  onIndexChange(newVal) {
    this.dots = {};
    // console.log('onIndexChange');
    if (this.curChildIndex || this.curChildIndex === 0 && this.containerIndex === this.curEleIndex) {
      this.setPointStyle();
    }
  }

  @Watch('commonStyle')
  onCommonStyleChange(newVal) {
    console.log('onCommonStyleChange', newVal);
    if (newVal) {
      this.setDotsStyle();
    }
  }

  mounted() {
    EventBus.$on('resizedChildEvent', (type) => {
      if (this.curEleIndex === this.containerIndex) {
        this.setChildSize(type);
        this.setPointStyle();
      }
    });
  }

  // 获取point计算后样式
  setPointStyle() {
    this.$nextTick(() => {
      if (!this.curChildIndex && this.curChildIndex !== 0) { return; }
      const [height, width] = this.getHW(this.curChildIndex);
      const childEle = this.childItem.child[this.curChildIndex];
      this.setDotsStyle();
      this.updateCommonStyle({ containerIndex: this.containerIndex, childIndex: this.curChildIndex, data: { ...childEle.commonStyle, height: +height, width: +width }});
    });
  }

  setDotsStyle() {
    this.$nextTick(() => {
      const points = ['lt', 'rt', 'lb', 'rb', 'l', 'r', 't', 'b'];
      const [height, width] = this.getHW(this.curChildIndex);
      const dots = points.reduce((pre, cur) => {
        pre[cur] = convertPointStyle(cur, {height, width});
        return pre;
      }, {});
      this.$set(this.dots, this.curChildIndex, dots);
      // console.log('setDotsStyle', this.dots[this.curChildIndex]);
    });
  }

  getHW(index) {
    // console.log('getHW', index);
    if (!this.$refs.childComponent || !this.$refs.childComponent.length) { return [0, 0]; }
    const childComponent = this.$refs.childComponent[index];
    if (!childComponent || !childComponent.$el) { return [0, 0]; }
    return [getStyle(childComponent.$el, 'height'), getStyle(childComponent.$el, 'width')];
  }

  setChildSize(type) {
    const childEle = this.childItem.child[this.curChildIndex];
    const [height, width] = [getStyle(this.$el, 'height'), getStyle(this.$el, 'width')];
    console.log('setChildSize', this, height, width);
    switch (type) {
    case 'width':
      this.updateCommonStyle({ containerIndex: this.containerIndex, childIndex: this.curChildIndex, data: { ...childEle.commonStyle, width: +width }});
      break;
    case 'height':
      this.updateCommonStyle({ containerIndex: this.containerIndex, childIndex: this.curChildIndex, data: { ...childEle.commonStyle, height: +height }});
      break;
    case 'full':
      this.updateCommonStyle({ containerIndex: this.containerIndex, childIndex: this.curChildIndex, data: { ...childEle.commonStyle, height: +height, width: +width }});
      break;
    }
  }

  handleMouseDownOnPoint(point, event) {
    const downEvent = event;
    // 抛出事件让父组件设置当前元素选中状态
    downEvent.stopPropagation();
    downEvent.preventDefault();
    const [height, width] = this.getHW(this.curChildIndex);
    const pos = {...this.childItem.child[this.curChildIndex].commonStyle, height, width };
    const top = pos.top;
    const left = pos.left;
    const startX = downEvent.clientX;
    const startY = downEvent.clientY;
    // 当前模块的最小宽度值
    let minWidth = 0;
    if (pos.minWidth) {
      minWidth = pos.minWidth;
    }
    // 当前模块的最小高度值
    let minHeight = 0;
    if (pos.minHeight) {
      minHeight = pos.minHeight;
    }
    const move = throttle(moveEvent => {
      this.setDragable(false);
      moveEvent.stopPropagation();
      moveEvent.preventDefault();

      const currX = moveEvent.clientX;
      const currY = moveEvent.clientY;
      const disY = currY - startY;
      const disX = currX - startX;
      const hasT = /t/.test(point);
      const hasB = /b/.test(point);
      const hasL = /l/.test(point);
      const hasR = /r/.test(point);
      const newHeight = +height + (hasT ? -disY : hasB ? disY : 0);
      const newWidth = +width + (hasL ? -disX : hasR ? disX : 0);
      pos.width = newWidth > 0 ? newWidth : 0;
      pos.height = newHeight > 0 ? newHeight : 0;
      pos.left = +left + (hasL ? disX : 0);
      pos.top = +top + (hasT ? disY : 0);
      if (!this.containerIndex && this.containerIndex !== 0 || !this.curChildIndex && this.curChildIndex !== 0) { return; }
      this.updateCommonStyle({ containerIndex: this.containerIndex, childIndex: this.curChildIndex, data: pos });
      this.setPointStyle();
    }, 100);
    const up = () => {
      this.setDragable(true);
      this.$emit('resize');
      document.removeEventListener('mousemove', move);
      document.removeEventListener('mouseup', up);
    };
    document.addEventListener('mousemove', move);
    document.addEventListener('mouseup', up);
  }
}