<template lang="pug">
  q-dialog(
    v-model="value"
    @show="onShow",
    @hide="onHide",
    ref="dialog"
    )
    .base-content(:class="{'draggable': draggable}", ref="contentRef", :style="{...contentStyles, height}")
      q-resize-observer(@resize="onResize")
      .base-header(draggable, :class="{'cursor-move': draggable}", ref="headerRef")
        .header-title.text {{ title }}
        .icon-cancel.text-sm(@click="value = false", v-if="!showCloseIcon")
      slot
</template>

<script>
import { v_model } from "@/shared/mixins/v-model";

export default {
  name: "BaseModal",
  mixins: [v_model],
  emits: ["show", "hide"],
  props: {
    title: String,
    showCloseIcon: Boolean,
    draggable: Boolean,
    hideOverlay: Boolean,
    height: {
      type: String,
    },
  },
  data() {
    return {
      contentStyles: {},
    };
  },
  methods: {
    onShow() {
      if (this.draggable) {
        this.$refs.headerRef.addEventListener("mousedown", this.onGrab);
      }
      this.$emit("show");
    },
    onHide() {
      if (this.draggable) {
        document.removeEventListener("mousemove", this.onDrag);
        document.removeEventListener("mouseup", this.onLetGo);
      }
      this.$emit("hide");
    },
    onDrag(e) {
      const target = this.$refs.contentRef;
      const originalStyles = window.getComputedStyle(target);
      const { x, width, y, height } = target.getBoundingClientRect();
      if (
        x + e.movementX > 10 &&
        x + e.movementX + width + 10 <= window.innerWidth
      )
        this.contentStyles.left =
          parseInt(originalStyles.left) + e.movementX + "px";
      if (
        y + e.movementY > 10 &&
        y + e.movementY + height + 10 <= window.innerHeight
      )
        this.contentStyles.top =
          parseInt(originalStyles.top) + e.movementY + "px";
      this.contentStyles.bottom = "unset";
      this.contentStyles.right = "unset";
    },

    onLetGo() {
      document.removeEventListener("mousemove", this.onDrag);
      document.removeEventListener("mouseup", this.onLetGo);
    },

    onGrab() {
      document.addEventListener("mousemove", this.onDrag);
      document.addEventListener("mouseup", this.onLetGo);
    },
    onResize() {
      const target = this.$refs.contentRef;
      const originalStyles = window.getComputedStyle(target);
      const { x, width, y, height } = target.getBoundingClientRect();
      if (x < 10) {
        const delta = 10 - x;
        this.contentStyles.left = parseInt(originalStyles.left) + delta + "px";
      }
      if (y < 10) {
        const delta = 10 - y;
        this.contentStyles.top = parseInt(originalStyles.top) + delta + "px";
      }
      if (x + width + 10 > window.innerWidth) {
        const delta = window.innerWidth - (x + width + 10);
        this.contentStyles.left = parseInt(originalStyles.left) + delta + "px";
      }
      if (y + height + 10 > window.innerHeight) {
        const delta = window.innerHeight - (y + height + 10);
        this.contentStyles.top = parseInt(originalStyles.top) + delta + "px";
      }
    },
  },
  updated() {
    const backdropEl = this.$refs.dialog?.contentEl?.previousSibling;
    if (!backdropEl) return;
    if (!this.hideOverlay) {
      backdropEl.style.background = "rgba(37, 40, 80, 0.2)";
      backdropEl.style.backdropFilter = "blur(4px)";
    } else backdropEl.style.background = "rgba(0,0,0,0)";
  },
  watch: {
    value(val) {
      if (val || !this.draggable) return;
      this.contentStyles = {};
    },
  },
};
</script>

<style lang="sass" scoped>
.base-overlay
  z-index: 10000
  position: absolute
  left: 0
  top: 0
  display: flex
  justify-content: center
  align-items: center

.base-content
  width: auto
  padding: 32px 40px
  background-color: var(--default-white)
  box-shadow: 4px 4px 8px rgba(9, 10, 21, 0.1), -4px -4px 8px rgba(9, 10, 21, 0.1)
  border-radius: 4px
  &.draggable
    position: fixed
    bottom: 10px
    right: 10px

.header-title
  font-weight: 700
  font-size: 20px
  line-height: 23px
  color: var(--font-dark-blue-color)
  user-select: none
.base-header
  display: flex
  justify-content: space-between
  gap: 16px
.icon-cancel
  margin-top: -11px
  margin-right: -11px
  cursor: pointer
  color: var(--font-grey-color)
</style>
<style lang="sass">
@media (min-width: 600px)
  .q-dialog__inner--minimized > div
    max-width: 100vh !important
</style>
