<template>
  <transition
    appear
    :name="transition"
    @before-enter="handleBeforeTransition"
    @after-leave="handleAfterTransition">
    <div
      v-show="localVisible"
      ref="popup"
      v-portal="target"
      :class="{
        'mm-modal__overflow-auto': overflowAuto,
        'mm-modal--mask': mask,
      }"
      :style="{
        zIndex: realZIndex,
      }"
      class="mm-modal">
      <div
        v-if="mask"
        class="mm-modal-mask"
        @click.self="handleMaskClick">
      </div>
      <div
        :style="wrapperStyle"
        class="mm-modal-wrapper"
        @click.self="handleMaskClick">
        <div
          :style="contentStyle"
          :class="[customClass, { 'mm-modal__center': center }]"
          class="mm-modal-content">
          <ui-icon
            v-if="closable"
            name="close"
            class="mm-modal-close"
            size="14px"
            @click.stop="handleClose">
          </ui-icon>
          <div
            v-if="$slots.header || title"
            class="mm-modal-header">
            <slot name="header">
              <div class="mm-modal-title">
                <slot name="title">
                  <span>{{ title }}</span>
                </slot>
              </div>
            </slot>
          </div>
          <div class="mm-modal-body">
            <slot></slot>
          </div>
          <div
            v-if="$slots.footer"
            class="mm-modal-footer">
            <slot name="footer"></slot>
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import Icon from "../icon"
import popup from "../../utils/popup"
import portal from "../../directives/portal"
import config from "../../managers/config"

config.defaults({
  "Modal.escClosable": true,
  "Modal.maskClosable": true,
  "Modal.mask": true,
  "Modal.zIndex": undefined,
  "Modal.width": undefined,
  "Modal.maxHeight": undefined,
  "Modal.top": "15vh",
  "Modal.closable": true,
  "Modal.center": false,
  "Modal.overflowAuto": function() {
    return Boolean(this.maxHeight) || false
  },
  "Modal.transition": "mm-modal-fade",
  "Modal.target": undefined
})

export default {
  name: "mm-modal",
  components: {
    "ui-icon": Icon,
  },
  directives: {
    portal,
  },
  mixins: [popup],
  props: {
    escClosable: {
      type: Boolean,
      default: () => config.get("Modal.escClosable"),
    },
    maskClosable: {
      type: Boolean,
      default: () => config.get("Modal.maskClosable"),
    },
    mask: {
      type: Boolean,
      default: () => config.get("Modal.mask"),
    },
    zIndex: {
      type: Number,
      default: () => config.get("Modal.zIndex"),
    },
    visible: {
      type: Boolean,
      default: false,
      required: true,
    },
    title: {
      type: String,
    },
    width: {
      type: String,
      default: () => config.get("Modal.width"),
    },
    maxHeight: {
      type: String,
      default: () => config.get("Modal.maxHeight"),
    },
    top: {
      type: String,
      default: () => config.get("Modal.top"),
    },
    customClass: {
      type: String,
      default: "",
    },
    closable: {
      type: Boolean,
      default: () => config.get("Modal.closable"),
    },
    center: {
      type: Boolean,
      default: () => config.get("Modal.center"),
    },
    target: {
      type: [Object, String, Boolean],
      default: () => config.get("Modal.target"),
    },
    overflowAuto: {
      type: Boolean,
      default() {
        return config.get("Modal.overflowAuto").call(this)
      },
    },
    transition: {
      type: String,
      default: () => config.get("Modal.transition"),
    },
  },
  data() {
    return {
      bodyPaddingRight: 0,
      scrollBarWidth: 0,
    }
  },
  computed: {
    wrapperStyle() {
      return {
        paddingTop: this.top,
      }
    },
    contentStyle() {
      return {
        width: this.width,
        maxHeight: this.maxHeight,
        borderColor: this.mask && "transparent",
      }
    },
  },
  methods: {
    handleMaskClick() {
      if (this.maskClosable) {
        this.close("mask")
      }
    },

    handleClose() {
      this.close("close")
    },
  },
}
</script>
