<template>
  <view class="mix-modal__container" :class="[show ? 'mix-modal-show' : '']" :style="{ zIndex: zIndex }" @touchmove.stop.prevent>
    <view
      class="mix-modal-box"
      :style="{ width: width, padding: padding, borderRadius: radius, backgroundColor: bgColor, zIndex: zIndex + 1 }"
      :class="[fadeIn || show ? 'mix-modal-normal' : 'mix-modal-scale', show ? 'mix-modal-show' : '']"
    >
      <view v-if="$slots.default">
        <!-- @slot 默认插槽，使用自定义内容 -->
        <slot></slot>
      </view>
      <view v-else>
        <view class="mix-modal-title" v-if="title">{{ title }}</view>
        <view class="mix-modal-content" :class="[title ? '' : 'mix-mtop']" :style="{ color: color, fontSize: color + 'rpx' }" v-html="content">{{ content }}</view>
        <view class="mix-modalBtn-box" v-if="button.length == 2">
          <block v-for="(item, index) in button" :key="index">
            <mix-button class="mix-modal-btn" :type="item.type" :shape="shape" :plain="item.plain" @click="handleClick(index)">
              {{ item.text || '确定' }}{{ button.length }}
            </mix-button>
          </block>
        </view>
        <view class="mix-modalBtn-box mix-flex-column" v-else>
          <template v-if="button.length == 1">
            <block v-for="(item, index) in button" :key="index">
              <mix-button class="mix-modal-btn mix-btn-width" :type="item.type" :shape="shape" :plain="item.plain" @click="handleClick(index)">
                {{ item.text || '确定' }}
              </mix-button>
            </block>
          </template>
          <template v-if="button.length > 2">
            <block v-for="(item, index) in button" :key="index">
              <mix-button class="mix-modal-btn mix-btn-width mix-mbtm" :type="item.type" :shape="shape" :plain="item.plain" @click="handleClick(index)">
                {{ item.text || '确定' }}{{ button.length }}
              </mix-button>
            </block>
          </template>
        </view>
      </view>
    </view>
    <view class="mix-modal-mask" :class="[show ? 'mix-mask-show' : '']" :style="{ zIndex: maskZIndex }" @tap="handleClickCancel"></view>
  </view>
</template>

<script>
/**
 * Modal弹框:可设置按钮数，按钮样式，提示文字样式等，还可自定义弹框内容。
 * @since 0.0.1
 * @displayName Modal
 * @property {String} width 弹窗宽度（默认630rpx）
 * @property {String} bg-color 弹窗背景色（默认#fff）
 * @property {String} padding 弹窗padding（默认40rpx 64rpx'）
 * @property {String} radius 弹窗背景色（默认24rpx）
 * @property {Boolean} fade-in = [true|false] 淡入效果，自定义弹框插入input输入框时传true（默认false）
 * @property {Number} z-index 弹窗 z-index（默认9997）
 * @property {Number} mask-z-index 遮罩层 z-index（默认9990）
 * @event {Function} click 按钮点击
 */
export default {
  name: 'mix-modal',
  props: {
    /**
     * 弹窗背景色
     */
    bgColor: { type: String, default: '#fff' },
    /**
     * 弹窗padding
     */
    padding: { type: String, default: '40rpx 64rpx' },
    /**
     * 弹窗圆角
     */
    radius: { type: String, default: '24rpx' },
    /**
     * 淡入效果，自定义弹框插入input输入框时传true
     */
    fadeIn: { type: Boolean, default: false },
    /**
     * 弹窗 z-index
     */
    zIndex: { type: Number, default: 9997 },
    /**
     * 遮罩层 z-index
     */
    maskZIndex: { type: Number, default: 9990 }
  },
  data() {
    return {
      show: false,
      title: '',
      content: '',
      color: '',
      color: '',
      asyncClose: false,
      shape: 'square',
      button: [
        {
          text: '确定',
          type: 'error',
          plain: false
        }
      ],
      maskCloseAble: true,
      width: '630rpx'
    }
  },
  methods: {
    /**
     * 打开模态框
     *
     * 调用使用 this.$refs.modal.open(options) 方式
     * @param {Object} options {title, content, button, shape, maskCloseAble, asyncClose, color,size, width}
     * @param {String} title 标题
     * @param {String} content 内容
     * @param {Arrary} button 按钮组，查看属性中说明
     * @param {String} shape 按钮形状，默认值square，查看属性中说明
     * @param {Boolean} maskCloseAble 点击遮罩 是否可关闭，默认值true
     * @param {Boolean} asyncClose 是否异步关闭，对所有按钮有效，需要手动弹窗，默认值false
     * @param {Number} size 内容字体大小，单位rpx，默认28
     * @param {String} color 颜色，默认值 '#999'
     * @param {String} width 弹窗宽度（默认630rpx）
     * @public
     */
    open({
      title = '',
      content = '',
      button = [{ text: '确定', type: 'error', plain: false }],
      shape = 'square',
      maskCloseAble = true,
      asyncClose = false,
      color = '#999',
      size = 28,
      width = '630rpx'
    } = {}) {
      this.button = button
      this.title = title
      this.content = content
      this.shape = shape
      this.maskCloseAble = maskCloseAble
      this.asyncClose = asyncClose
      this.color = color
      this.color = size
      this.show = true
      this.width = width
    },
    handleClick(index) {
      if (!this.show) return
      if (Object.prototype.toString.call(this.button[index].fun) === '[object Function]') {
        this.button[index].fun({ index })
      } else {
        /**
         * @event click
         * @property {Object} e  {index} 按钮索引
         * 点击回调
         */
        this.$emit('click', { index })
      }
      if (!this.asyncClose) {
        this.close()
      }
    },
    handleClickCancel() {
      if (!this.maskCloseAble) return
      /**
       * @event click
       * @property {Object} e  {index} 按钮索引
       * 点击回调
       */
      this.$emit('cancel')
      this.close()
    },
    /**
     * 关闭模态框
     * @public
     */
    close() {
      this.show = false
    }
  }
}
</script>

<style scoped>
.mix-modal__container {
  width: 100%;
  height: 100%;
  position: fixed;
  left: 0;
  top: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  visibility: hidden;
}
.mix-modal-box {
  position: relative;
  opacity: 0;
  visibility: hidden;
  box-sizing: border-box;
  transition: all 0.2s ease-in-out;
}

.mix-modal-scale {
  transform: scale(0);
}

.mix-modal-normal {
  transform: scale(1);
}

.mix-modal-show {
  opacity: 1;
  visibility: visible;
}

.mix-modal-mask {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(0, 0, 0, 0.6);
  transition: all 0.2s ease-in-out;
  opacity: 0;
  visibility: hidden;
}

.mix-mask-show {
  visibility: visible;
  opacity: 1;
}

.mix-modal-title {
  text-align: center;
  font-size: 34rpx;
  color: #333;
  padding-top: 20rpx;
  font-weight: bold;
}

.mix-modal-content {
  text-align: center;
  color: #999;
  font-size: 28rpx;
  padding-top: 20rpx;
  padding-bottom: 60rpx;
}

.mix-mtop {
  margin-top: 30rpx;
}

.mix-mbtm {
  margin-bottom: 30rpx;
}

.mix-modalBtn-box {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.mix-flex-column {
  flex-direction: column;
}

.mix-modal-btn {
  width: 232rpx;
  height: 68rpx;
  line-height: 68rpx;
  font-size: 26rpx;
  margin-left: 1rpx;
  margin-right: 1rpx;
  border-radius: 10rpx;
}
.mix-modal-btn::after {
  border-radius: 20rpx;
}

.mix-btn-width {
  width: 400rpx !important;
}
</style>
