const BindingX = uni.requireNativePlugin("bindingx");
const dom = uni.requireNativePlugin("dom");
const animation = uni.requireNativePlugin("animation");

export default {
  data() {
    return {};
  },

  watch: {
    show(newVal) {
      if (this.autoClose) return;
      if (this.stop) return;
      this.stop = true;
      if (newVal) {
        this.open(newVal);
      } else {
        this.close();
      }
    },
    leftOptions() {
      this.getSelectorQuery();
      this.init();
    },
    rightOptions() {
      this.init();
    }
  },
  created() {
    if (this.swipeaction.children !== undefined) {
      this.swipeaction.children.push(this);
    }
  },
  mounted() {
    this.box = this.getEl(this.$refs["selector-box--hock"]);
    this.selector = this.getEl(this.$refs["selector-content--hock"]);
    this.leftButton = this.getEl(this.$refs["selector-left-button--hock"]);
    this.rightButton = this.getEl(this.$refs["selector-right-button--hock"]);
    this.init();
  },
  beforeDestroy() {
    this.swipeaction.children.forEach((item, index) => {
      if (item === this) {
        this.swipeaction.children.splice(index, 1);
      }
    });
  },
  methods: {
    init() {
      this.$nextTick(() => {
        this.x = 0;
        this.button = {
          show: false
        };
        setTimeout(() => {
          this.getSelectorQuery();
        }, 200);
      });
    },
    onClick(index, item, position) {
      this.$emit("click", {
        content: item,
        index,
        position
      });
    },
    touchstart() {
      // 每次只触发一次，避免多次监听造成闪烁
      if (this.stop) return;
      this.stop = true;
      if (this.autoClose) {
        this.$emit("closeOther", this);
      }

      const leftWidth = this.button.left.width;
      const rightWidth = this.button.right.width;
      let expression = this.range(this.x, -rightWidth, leftWidth);
      let leftExpression = this.range(this.x - leftWidth, -leftWidth, 0);
      let rightExpression = this.range(this.x + rightWidth, 0, rightWidth);

      this.eventpan = BindingX.bind(
        {
          anchor: this.box,
          eventType: "pan",
          props: [
            {
              element: this.selector,
              property: "transform.translateX",
              expression
            },
            {
              element: this.leftButton,
              property: "transform.translateX",
              expression: leftExpression
            },
            {
              element: this.rightButton,
              property: "transform.translateX",
              expression: rightExpression
            }
          ]
        },
        e => {
          // nope
          if (e.state === "end") {
            this.x = e.deltaX + this.x;
            this.isclick = true;
            this.bindTiming(e.deltaX);
          }
        }
      );
    },
    touchend() {
      if (this.isopen !== "none" && !this.isclick) {
        this.open("none");
      }
    },
    bindTiming(x) {
      const left = this.x;
      const leftWidth = this.button.left.width;
      const rightWidth = this.button.right.width;
      const threshold = this.threshold;
      if (!this.isopen || this.isopen === "none") {
        if (left > threshold) {
          this.open("left");
        } else if (left < -threshold) {
          this.open("right");
        } else {
          this.open("none");
        }
      } else {
        if ((x > -leftWidth && x < 0) || x > rightWidth) {
          if ((x > -threshold && x < 0) || x - rightWidth > threshold) {
            this.open("left");
          } else {
            this.open("none");
          }
        } else {
          if ((x < threshold && x > 0) || x + leftWidth < -threshold) {
            this.open("right");
          } else {
            this.open("none");
          }
        }
      }
    },

    /**
     * 移动范围
     * @param {Object} num
     * @param {Object} mix
     * @param {Object} max
     */
    range(num, mix, max) {
      return `min(max(x+${num}, ${mix}), ${max})`;
    },

    /**
     * 开启swipe
     */
    open(type) {
      this.animation(type);
    },

    /**
     * 关闭swipe
     */
    close() {
      this.animation("none");
    },

    /**
     * 开启关闭动画
     * @param {Object} type
     */
    animation(type) {
      const leftWidth = this.button.left.width;
      const rightWidth = this.button.right.width;
      if (this.eventpan && this.eventpan.token) {
        BindingX.unbind({
          token: this.eventpan.token,
          eventType: "pan"
        });
      }

      switch (type) {
        case "left":
          Promise.all([
            this.move(this.selector, leftWidth),
            this.move(this.leftButton, 0),
            this.move(this.rightButton, rightWidth * 2)
          ]).then(() => {
            this.setEmit(leftWidth, type);
          });
          break;
        case "right":
          Promise.all([
            this.move(this.selector, -rightWidth),
            this.move(this.leftButton, -leftWidth * 2),
            this.move(this.rightButton, 0)
          ]).then(() => {
            this.setEmit(-rightWidth, type);
          });
          break;
        default:
          Promise.all([
            this.move(this.selector, 0),
            this.move(this.leftButton, -leftWidth),
            this.move(this.rightButton, rightWidth)
          ]).then(() => {
            this.setEmit(0, type);
          });
      }
    },
    setEmit(x, type) {
      const leftWidth = this.button.left.width;
      const rightWidth = this.button.right.width;
      this.isopen = this.isopen || "none";
      this.stop = false;
      this.isclick = false;
      // 只有状态不一致才会返回结果
      if (this.isopen !== type && this.x !== x) {
        if (type === "left" && leftWidth > 0) {
          this.$emit("change", "left");
        }
        if (type === "right" && rightWidth > 0) {
          this.$emit("change", "right");
        }
        if (type === "none") {
          this.$emit("change", "none");
        }
      }
      this.x = x;
      this.isopen = type;
    },
    move(ref, value) {
      return new Promise(resolve => {
        animation.transition(
          ref,
          {
            styles: {
              transform: `translateX(${value})`
            },
            duration: 150, //ms
            timingFunction: "linear",
            needLayout: false,
            delay: 0 //ms
          },
          function(res) {
            resolve(res);
          }
        );
      });
    },

    /**
     * 获取ref
     * @param {Object} el
     */
    getEl(el) {
      return el.ref;
    },
    /**
     * 获取节点信息
     */
    getSelectorQuery() {
      Promise.all([this.getDom("left"), this.getDom("right")]).then(() => {
        let show = "none";
        if (this.autoClose) {
          show = "none";
        } else {
          show = this.show;
        }

        if (show === "none") {
          // this.close()
        } else {
          this.open(show);
        }
      });
    },
    getDom(str) {
      return new Promise((resolve, reject) => {
        dom.getComponentRect(this.$refs[`selector-${str}-button--hock`], data => {
          if (data) {
            this.button[str] = data.size;
            resolve(data);
          } else {
            reject();
          }
        });
      });
    }
  }
};
