<template>
  <view v-if="showPopup" class="uni-popup" :class="[popupstyle]" @touchmove.stop.prevent="clear">
    <uni-transition
      v-if="maskShow"
      :mode-class="['fade']"
      :styles="maskClass"
      :duration="duration"
      :show="showTrans"
      @click="onTap"
    />
    <uni-transition
      :mode-class="ani"
      :styles="transClass"
      :duration="duration"
      :show="showTrans"
      @click="onTap"
    >
      <view class="uni-popup__wrapper-box" @click.stop="clear">
        <text class="uni-popup-icon iconfont icon-close-plane" @click="onTap" />
        <view v-if="title || desc" class="uni-popup-header">
          <text v-if="title" class="uni-popup-title">{{ title }}</text>
          <text v-if="desc" class="uni-popup-desc">{{ desc }}</text>
        </view>
        <slot />
      </view>
    </uni-transition>
  </view>
</template>

<script>
import { uniTransition } from "@dcloudio/uni-ui";

const config = {
  // 顶部弹出
  top: "top",
  // 底部弹出
  bottom: "bottom",
  // 居中弹出
  center: "center",
  // 消息提示
  message: "top",
  // 对话框
  dialog: "center",
  // 分享
  share: "bottom"
};

export default {
  name: "UniPopup",
  components: {
    uniTransition
  },
  provide() {
    return {
      popup: this
    };
  },
  props: {
    // 开启动画
    animation: {
      type: Boolean,
      default: true
    },
    // 弹出层类型，可选值，top: 顶部弹出层；bottom：底部弹出层；center：全屏弹出层
    // message: 消息提示 ; dialog : 对话框
    type: {
      type: String,
      default: "bottom"
    },
    // maskClick
    maskClick: {
      type: Boolean,
      default: true
    },
    title: {
      type: String,
      default: ""
    },
    desc: {
      type: String,
      default: ""
    }
  },
  data() {
    return {
      duration: 300,
      ani: [],
      showPopup: false,
      showTrans: false,
      maskClass: {
        position: "fixed",
        bottom: 0,
        top: 0,
        left: 0,
        right: 0,
        backgroundColor: "rgba(0, 0, 0, 0.4)"
      },
      transClass: {
        position: "fixed",
        left: 0,
        right: 0
      },
      maskShow: true,
      mkclick: true,
      popupstyle: "top",
      config
    };
  },
  watch: {
    /**
     * 监听type类型
     */
    type: {
      handler: function(newVal) {
        this[this.config[newVal]]();
      },
      immediate: true
    },
    /**
     * 监听遮罩是否可点击
     * @param {Object} val
     */
    maskClick(val) {
      this.mkclick = val;
    }
  },
  created() {
    this.mkclick = this.maskClick;
    if (this.animation) {
      this.duration = 300;
    } else {
      this.duration = 0;
    }
  },
  methods: {
    clear(e) {
      // TODO nvue 取消冒泡
      e.stopPropagation();
    },
    open() {
      this.showPopup = true;
      this.$nextTick(() => {
        new Promise(resolve => {
          clearTimeout(this.timer);
          this.timer = setTimeout(() => {
            this.showTrans = true;
            // fixed by mehaotian 兼容 app 端
            this.$nextTick(() => {
              resolve();
            });
          }, 50);
        }).then(() => {
          // 自定义打开事件
          clearTimeout(this.msgtimer);
          this.msgtimer = setTimeout(() => {
            this.customOpen && this.customOpen();
          }, 100);
          this.$emit("change", {
            show: true,
            type: this.type
          });
        });
      });
    },
    close() {
      this.showTrans = false;
      this.$nextTick(() => {
        this.$emit("change", {
          show: false,
          type: this.type
        });
        clearTimeout(this.timer);
        // 自定义关闭事件
        this.customOpen && this.customClose();
        this.timer = setTimeout(() => {
          this.showPopup = false;
        }, 300);
      });
    },
    onTap() {
      if (!this.mkclick) return;
      this.close();
    },
    /**
     * 顶部弹出样式处理
     */
    top() {
      this.popupstyle = "top";
      this.ani = ["slide-top"];
      this.transClass = {
        position: "fixed",
        left: 0,
        right: 0
      };
    },
    /**
     * 底部弹出样式处理
     */
    bottom() {
      this.popupstyle = "bottom";
      this.ani = ["slide-bottom"];
      this.transClass = {
        position: "fixed",
        left: 0,
        right: 0,
        bottom: 0
      };
    },
    /**
     * 中间弹出样式处理
     */
    center() {
      this.popupstyle = "center";
      this.ani = ["zoom-out", "fade"];
      this.transClass = {
        position: "fixed",
        /* #ifndef APP-NVUE */
        display: "flex",
        flexDirection: "column",
        /* #endif */
        bottom: 0,
        left: 0,
        right: 0,
        top: 0,
        justifyContent: "center",
        alignItems: "center"
      };
    }
  }
};
</script>
<style lang="scss" scoped>
.uni-popup {
  position: fixed;
  /* #ifndef APP-NVUE */
  z-index: 99;
  /* #endif */
}

.uni-popup__mask {
  position: absolute;
  top: 0;
  bottom: 0;
  left: 0;
  right: 0;
  background-color: $uni-bg-color-mask;
  opacity: 0;
}

.mask-ani {
  transition-property: opacity;
  transition-duration: 0.2s;
}

.uni-top-mask {
  opacity: 1;
}

.uni-bottom-mask {
  opacity: 1;
}

.uni-center-mask {
  opacity: 1;
}

.uni-popup__wrapper {
  /* #ifndef APP-NVUE */
  display: block;
  /* #endif */
  position: absolute;
}

.top {
  /* #ifdef H5 */
  top: var(--window-top);
  /* #endif */
  /* #ifndef H5 */
  top: 0;
  /* #endif */
}

.bottom {
  bottom: 0;
}

.uni-popup__wrapper-box {
  /* #ifndef APP-NVUE */
  display: block;
  /* #endif */
  position: relative;
  /* iphonex 等安全区设置，底部安全区适配 */
  /* #ifndef APP-NVUE */
  padding-bottom: constant(safe-area-inset-bottom);
  padding-bottom: env(safe-area-inset-bottom);
  /* #endif */
  padding: 40rpx 40rpx 0;
  border-radius: 12rpx 12rpx 0 0;
  background-color: #fff;
  .uni-popup-icon {
    position: absolute;
    right: 40rpx;
    top: 43rpx;
    font-size: 36rpx;
    color: #999999;
  }
  .uni-popup-header {
    margin-bottom: 40rpx;
    text {
      display: inline-block;
      width: 100%;
      text-align: center;
    }
    .uni-popup-title {
      font-size: 32rpx;
      line-height: 44rpx;
      font-weight: bold;
      color: #333333;
    }
    .uni-popup-desc {
      margin-top: 10rpx;
      font-size: 26rpx;
      color: #999999;
    }
  }
}

.content-ani {
  // transition: transform 0.3s;
  transition-property: transform, opacity;
  transition-duration: 0.2s;
}

.uni-top-content {
  transform: translateY(0);
}

.uni-bottom-content {
  transform: translateY(0);
}

.uni-center-content {
  transform: scale(1);
  opacity: 1;
}
</style>
