<template>
  <BottomSheet
    class="mobile"
    v-if="isMobile && isMounted"
    :draggable="closable"
    @close="$emit('close')"
  >
    <div class="modal-body">
      <slot />
    </div>
  </BottomSheet>
  <transition v-else-if="!isMobile && isMounted" appear name="modal">
    <div class="modal">
      <div class="modal-container">
        <div
          v-if="closable"
          id="modal-close"
          class="icon close"
          @click="$emit('close')"
        >
          <SpIcon name="sp-close" />
        </div>

        <div class="modal-body">
          <slot />
        </div>
      </div>
    </div>
  </transition>
</template>

<script lang="ts">
import { defineComponent, onBeforeUnmount, onMounted, ref } from "vue";

export default defineComponent({
  props: {
    closable: {
      type: Boolean,
      default: true,
    },
  },
  setup(props) {
    const positionY = ref<number | null>(null);
    const isMounted = ref<boolean>(false);
    const isMobile = ref<boolean>(false);

    const setPosition = (): void => {
      positionY.value = window.scrollY;

      document.documentElement.style.height = "100%";
      document.body.style.bottom = positionY.value + "px";
    };

    const clearPosition = (): void => {
      document.documentElement.style.height = "";
      document.body.style.bottom = "";
      window.scrollTo(0, positionY.value);
    };

    const resizeListener = (): void => {
      isMobile.value = window.innerWidth <= 768;
    };

    onMounted((): void => {
      resizeListener();
      window.addEventListener("resize", resizeListener);
      isMounted.value = true;
    });

    onBeforeUnmount((): void => {
      clearPosition();
      window.removeEventListener("resize", resizeListener);
    });

    return {
      ...props,
      clearPosition,
      setPosition,
      isMounted,
      positionY,
      isMobile,
    };
  },
});
</script>

<style lang="scss">
.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 5;
  background: rgba(142, 142, 147, 0.7);
  backdrop-filter: blur(7px);

  --width: 368px;
  --padding: 0px;

  .modal-container {
    width: var(--width);
    padding: var(--padding);

    .close {
      position: absolute;
      right: 16px;
      top: 16px;
      cursor: pointer;
    }
  }

  @include screen-sm() {
    --padding: 32px;

    .modal-container {
      padding: 32px;
      border-radius: 16px;
      background-color: var(--background-primary);
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
    }

    .bottom-sheet {
      display: none;
    }
  }

  @include screen-lg() {
    --padding: 48px;
  }
}

.modal-body {
  display: flex;
  flex-direction: column;
  align-items: center;
  width: 100%;

  .main,
  main {
    flex-grow: 1;
    flex-basis: 0;
    margin-bottom: auto;
    width: 100%;
  }

  .footer,
  footer {
    margin-top: 24px;
    width: 100%;

    .button {
      &:not(:last-child) {
        margin-bottom: 8px;
      }
    }
  }

  & > img,
  & > .icon {
    width: 48px;
    height: 48px;
    margin-bottom: 16px;
  }

  @include screen-sm() {
    padding: 0;

    & > img,
    & > .icon {
      width: 86px;
      height: 86px;
    }
  }

  @include screen-lg() {
    & > img,
    & > .icon {
      width: 108px;
      height: 108px;
      margin-bottom: 24px;
    }

    .footer,
    footer {
      .button {
        &:not(:last-child) {
          margin-bottom: 16px;
        }
      }
    }
  }
}

.modal-enter-active,
.modal-leave-active {
  transition: opacity 0.4s;

  .modal-container {
    transition: all 0.2s cubic-bezier(0.79, 0.14, 0.15, 0.86);
  }
}

.modal-enter,
.modal-leave-to {
  opacity: 0;

  .modal-container {
    transform: translate(-50%, -40%) scale(0.95) !important ;
    opacity: 0;
  }
}
</style>
