<template>
  <ui-modal
    :id="id"
    :visible.sync="localVisible"
    :title="title"
    :closable="closable"
    :mask-closable="maskClosable"
    :esc-closable="escClosable"
    :lock-scroll="lockScroll"
    :before-close="beforeClose"
    :target="target"
    :class="customClass"
    :overflow-auto="overflowAuto"
    :width="width"
    class="mm-dialog"
    @close="closeHandler">
    <slot></slot>

    <div slot="footer">
      <template v-if="realButtons.length">
        <ui-button
          v-for="item in realButtons"
          @click="item.onClick"
          :key="item.name"
          v-bind="item"
          :loading="buttonsLoading"
          >{{ item.name }}
        </ui-button>
      </template>
      <template v-else>
        <ui-button
          v-if="showCancelButton"
          @click="handleCancel">
          <span>{{ cancelButtonText }}</span>
        </ui-button>
        <ui-button
          v-if="showConfirmButton"
          :loading="confirmLoading"
          type="primary"
          @click="handleConfirm">
          <span>{{ confirmButtonText }}</span>
        </ui-button>
      </template>
    </div>
  </ui-modal>
</template>

<script>
import isFunction from "lodash/isFunction"
import Modal from "../modal"
import Button from "../button"
import visible from "../../mixins/visible"
import { t } from "../../locale"
import config from "../../managers/config"

config.defaults({
  "Dialog.closable": true,
  "Dialog.lockScroll": true,
  "Dialog.showCancelButton": true,
  "Dialog.showConfirmButton": true,
  "Dialog.maskClosable": false,
  "Dialog.escClosable": false,
  "Dialog.target": undefined,
  "Dialog.width": undefined,
  "Dialog.overflowAuto": true,
})

export default {
  name: "mm-dialog",
  components: {
    "ui-modal": Modal,
    "ui-button": Button,
  },
  mixins: [visible],
  props: {
    id: {
      type: String,
      default: null,
    },
    title: {
      type: String,
      default() {
        return t("ui.dialog.title.dialog")
      },
    },
    closable: {
      type: Boolean,
      default: () => config.get("Dialog.closable"),
    },
    beforeClose: {
      type: Function,
    },
    lockScroll: {
      type: Boolean,
      default: () => config.get("Dialog.lockScroll"),
    },
    showCancelButton: {
      type: Boolean,
      default: () => config.get("Dialog.showCancelButton"),
    },
    showConfirmButton: {
      type: Boolean,
      default: () => config.get("Dialog.showConfirmButton"),
    },
    cancelButtonText: {
      type: String,
      default() {
        return t("ui.dialog.cancel")
      },
    },
    confirmButtonText: {
      type: String,
      default() {
        return t("ui.dialog.confirm")
      },
    },
    maskClosable: {
      type: Boolean,
      default: () => config.get("Dialog.maskClosable"),
    },
    escClosable: {
      type: Boolean,
      default: () => config.get("Dialog.maskClosable"),
    },
    onCancel: {
      type: Function,
      default() {},
    },
    onConfirm: {
      type: Function,
      default() {},
    },
    target: {
      type: null,
      default: () => config.get("Dialog.target"),
    },
    customClass: {
      type: [String, Array, Object],
    },
    width: {
      type: String,
      default: () => config.get("Dialog.width"),
    },
    overflowAuto: {
      type: Boolean,
      default: () => config.get("Dialog.overflowAuto"),
    },
    buttons: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      buttonsLoading: false,
      confirmLoading: false,
    }
  },
  computed: {
    realButtons() {
      return this.buttons.map(item => ({
        ...item,
        onClick: () => {
          this.buttonsLoading = true
          const result = isFunction(item.onClick) && item.onClick()
          return Promise.resolve(result).then(res => {
            this.buttonsLoading = false
            if (this.isValid(res)) {
              this.close()
            }
          })
        },
      }))
    },
  },  
  methods: {
    isValid(val) {
      if (val === undefined) {
        return true
      }

      return !val === false
    },

    handleConfirm(event) {
      if (this.confirmLoading) {
        return
      }

      this.$emit("confirm", event)

      this.confirmLoading = true

      const onConfirm = isFunction(this.onConfirm) ? this.onConfirm(event) : true

      return Promise.resolve(onConfirm)
        .catch(() => false)
        .then(res => {
          this.confirmLoading = false
          if (this.isValid(res)) {
            this.close()
          }
        })
    },
    handleCancel(event) {
      this.onCancel("cancel")
      this.close()
      this.$emit("cancel", event, "cancel")
    },
    closeHandler(event) {
      this.onCancel("close")
      this.$emit("cancel", event, "close")
    },
    close() {
      this.hide()
    },
  },
}
</script>