<script>
/**
 * vs-dialog 2022-05-26
 *
 * left 左侧偏移量 0
 * right 右侧偏移量 0 如果设置left则该属性不生效
 * top 顶部偏移量 0
 * isCenter 是否水平居中  如果设置left或right则该属性不生效
 * width 弹窗宽度 360px
 * height 弹窗高度 550px
 * header 弹窗头部高度 50px
 * title 弹窗标题内容 vs-dialog
 * showTitle 是否显示标题 true
 * bg 弹窗背景图片
 *
 * isMini 是否显示最小化按钮 true
 * isFullScreen 是否显示最大化按钮 true
 * isClose 是否显示关闭按钮 true
 * isDrag 是否允许拖动 true
 *
 * @mini 最小化点击回调
 * @fullScreen 最大化点击回调
 * @close 关闭点击回调
 * @back 点击还原回调
 * @dragstop 拖拽结束回调
 */
export default {
  name: "vs-dialog",
};
</script>
<script setup>
import draggable from "../../../../../../../tevs/packages/plugins/vue3-draggable-resizable/typings/typings";
import "../../../plugins/vue3-draggable-resizable/dist/Vue3DraggableResizable.css";
import {
  ref,
  reactive,
  getCurrentInstance,
  onBeforeMount,
  onBeforeUnmount,
  nextTick,
  watch,
} from "vue";
const props = defineProps({
  left: {
    type: Number,
    default: undefined,
  },
  right: {
    type: Number,
    default: undefined,
  },
  isCenter: {
    type: Boolean,
    default: false,
  },
  top: {
    type: Number,
    default: 0,
  },
  width: {
    type: String,
    default: "360px",
  },
  height: {
    type: String,
    default: "550px",
  },
  header: {
    type: String,
    default: "50px",
  },
  title: {
    type: String,
    default: "vs-dialog",
  },
  showTitle: {
    type: Boolean,
    default: true,
  },
  bg: {
    type: String,
    default: "",
  },
  isMini: {
    type: Boolean,
    default: true,
  },
  isFullScreen: {
    type: Boolean,
    default: true,
  },
  isClose: {
    type: Boolean,
    default: true,
  },
  isDrag: {
    type: Boolean,
    default: true,
  },

  mountDom: {
    type: Object,
    default: () => { },
  }
});

//弹窗背景图
const dialogProps = reactive({
  isMini: props.isMini,
  isFullScreen: props.isFullScreen,
  isClose: props.isClose,
  showTitle: props.showTitle,
  width: props.width,
  height: props.height,
  left: props.left || 0,
  right: props.right || 0,
  top: props.top,
  isDrag: props.isDrag,
});

const styleToolbar = reactive({
  paddingTop: (parseInt(props.header) - 22) / 2 + "px",
});

const style = reactive({
  width: dialogProps.width,
  height: dialogProps.height,
});
const styleheader = reactive({
  height: props.header,
  lineHeight: props.header,
});

const stylecon = reactive({
  height: `calc(100% - ${props.header})`,
});

const styleUndrag = reactive({
  width: dialogProps.width,
  height: dialogProps.height,
});

onBeforeMount(() => {
  if (props.left === undefined && props.right !== undefined) {
    const _w = document.body.clientWidth;
    dialogProps.left = _w - parseInt(dialogProps.width) - props.right;
    window.addEventListener("resize", () => {
      if (!dialogProps.isDrag) {
        dialogProps.isDrag = true;
        nextTick(() => {
          dialogProps.isDrag = false;
        });
      }
      const _w = document.body.clientWidth;
      dialogProps.left = _w - parseInt(dialogProps.width) - props.right;
    });
  }

  if (props.left === undefined && props.right === undefined && props.isCenter) {
    const _w = document.body.clientWidth;
    dialogProps.left = (_w - parseInt(dialogProps.width)) / 2;
    window.addEventListener("resize", () => {
      if (!dialogProps.isDrag) {
        dialogProps.isDrag = true;
        nextTick(() => {
          dialogProps.isDrag = false;
        });
      }
      const _w = document.body.clientWidth;
      dialogProps.left = (_w - parseInt(dialogProps.width)) / 2;
    });
  }

  posi.left = dialogProps.left;
  posi.top = dialogProps.top;

  if (props.bg) {
    style.background = `url(${props.bg}) no-repeat`;
    style.backgroundSize = "100% 100%";
    styleheader.background = "unset";
  }
  if (props.header === "0px") {
    headerProps.isMini = false;
    headerProps.isFullScreen = false;
    headerProps.isClose = false;
    headerProps.showTitle = false;
  }
});
const emit = defineEmits(["mini", "fullScreen", "close", "back", "dragstop"]);

const posi = reactive({
  left: 0,
  top: 0,
});
const onDragstop = function (e) {
  if (Object.is(e.x, NaN)) return;
  posi.left = e.x;
  posi.top = e.y;
  emit('dragstop', e)
};

//最小化方法
const ismini = ref("mini");
const miniClickHandle = () => {
  if (ismini.value === "mini") {
    style.height = styleUndrag.height = props.header;
    ismini.value = "miniback";
    emit("mini");
  } else if (ismini.value === "miniback") {
    backClickHandle();
  }
};

//最大化方法
const isfull = ref("full");
const fullScreenClickHandle = () => {
  if (!dialogProps.isDrag) {
    dialogProps.isDrag = true;
    nextTick(() => {
      dialogProps.isDrag = false;
    });
  }
  if (isfull.value === "full") {
    ismini.value = "mini";
    isfull.value = "fullback";
    style.width = "100vw";
    style.height = "100vh";
    dialogProps.left = 0;
    dialogProps.top = 0;
    emit("fullScreen");
  } else if (isfull.value === "fullback") {
    backClickHandle();
  }
};

//还原弹窗方法
const backClickHandle = () => {
  ismini.value = "mini";
  isfull.value = "full";
  style.width = props.width;
  style.height = props.height;
  dialogProps.left = posi.left;
  dialogProps.top = posi.top;
  emit("back");
};

//关闭弹窗方法
const dialogshow = ref(true);
const closeClickHandle = () => {

  //如果是通过方法打开弹窗
  // if (props.mountDom) {
  //   document.body.removeChild(props.mountDom);
  //   return
  // }

  dialogshow.value = false;
  emit("close");
};
</script>

<template>
  <div v-if="dialogshow">
    <div v-if="dialogProps.isDrag">
      <draggable :x="dialogProps.left" :y="dialogProps.top" :w="dialogProps.width" :h="dialogProps.height"
        :resizable="false" @dragging="onDragstop">
        <div :style="style" class="vs-dialog">
          <div v-if="dialogProps.showTitle" :style="styleheader" class="vs-dialog--header">
            <div class="title">
              <span>{{ props.title }}</span>
            </div>
            <div class="toolbar" :style="styleToolbar">
              <i v-if="dialogProps.isMini" @click="miniClickHandle" :class="ismini"></i>
              <i v-if="dialogProps.isFullScreen" @click="fullScreenClickHandle" :class="isfull"></i>
              <i v-if="dialogProps.isClose" @click="closeClickHandle" class="close"></i>
            </div>
          </div>
          <div :style="stylecon" class="vs-dialog--content">
            <div class="vs-dialog--content--scorll">
              <slot />
            </div>
          </div>
        </div>
      </draggable>
    </div>

    <div v-else class="vs-dialog-unDrag"
      :style="{ ...styleUndrag, left: dialogProps.left + 'px', top: dialogProps.top + 'px' }">
      <div :style="style" class="vs-dialog">
        <div v-if="dialogProps.showTitle" :style="styleheader" class="vs-dialog--header">
          <div class="title">
            <span>{{ props.title }}</span>
          </div>
          <div class="toolbar" :style="styleToolbar">
            <i v-if="dialogProps.isMini" @click="miniClickHandle" :class="ismini"></i>
            <i v-if="dialogProps.isFullScreen" @click="fullScreenClickHandle" :class="isfull"></i>
            <i v-if="dialogProps.isClose" @click="closeClickHandle" class="close"></i>
          </div>
        </div>
        <div :style="stylecon" class="vs-dialog--content">
          <div class="vs-dialog--content--scorll">
            <slot />
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<style  lang="scss" scope>
$main: var(--main);
$auxiliary: var(--auxiliary);

.vdr-container {
  border: none !important;
}

.vs-dialog {
  background: $auxiliary;
  border-radius: 5px;
  color: #fff;
  position: relative;
  z-index: 999;

  .vs-dialog--header {
    width: 100%;
    background: $main;
    border-top-left-radius: 5px;
    border-top-right-radius: 5px;
    display: flex;
    justify-content: space-around;

    .title {
      width: 100%;
      cursor: move;
      text-indent: 20px;
      overflow: hidden;
      /*超出部分隐藏*/
      white-space: nowrap;
      /*不换行*/
      text-overflow: ellipsis;
      /*超出部分文字以...显示*/
    }

    .toolbar {
      display: flex;
      justify-content: space-around;
      margin-right: 10px;

      .mini {
        background-image: url("../icon/mini.png");
      }

      .miniback {
        background-image: url("../icon/miniback.png");
      }

      .full {
        background-image: url("../icon/fullscreen.png");
      }

      .fullback {
        background-image: url("../icon/fullback.png");
      }

      .close {
        background-image: url("../icon/close.png");
      }

      i {
        width: 21px;
        height: 21px;
        background-size: 100% 100%;
        background-repeat: no-repeat;
        cursor: pointer;
        margin: 0px 3px;
      }
    }
  }

  .vs-dialog--content {
    width: 99%;
    padding: 10px 5px 10px 10px;
    box-sizing: border-box;

    .vs-dialog--content--scorll {
      height: 100%;
      padding-right: 5px;
      overflow-y: auto;
      overflow-x: hidden;
    }

    .vs-dialog--content--scorll::-webkit-scrollbar {
      width: 5px;
      height: 1px;
    }

    .vs-dialog--content--scorll::-webkit-scrollbar-thumb {
      border-radius: 10px;
      background: $main;
    }
  }
}

.vs-dialog-unDrag {
  position: absolute;
}
</style>
