<script setup>
import { ref, watch, onMounted, onUnmounted } from "vue";
import { breakpointsTailwind, useBreakpoints } from "@vueuse/core";
const props = defineProps({
  modelValue: { type: Boolean, required: true },
  padding: { type: Boolean, required: false, default: true }
});
const emit = defineEmits(["update:modelValue"]);
const mobileDrawerRef = ref();
const dragOffset = ref(0);
const isDragging = ref(false);
const isClosing = ref(false);
let startTouchY = 0;
function handleTouchStart(e) {
  startTouchY = e.touches[0].clientY;
  isDragging.value = true;
}
function handleTouchMove(e) {
  if (!isDragging.value) return;
  const currentY = e.touches[0].clientY;
  const deltaY = currentY - startTouchY;
  if (deltaY > 0) {
    dragOffset.value = deltaY;
  }
}
async function closeWithAnimation() {
  if (isClosing.value || !mobileDrawerRef.value?.open) return;
  isClosing.value = true;
  await new Promise((resolve) => setTimeout(resolve, 300));
  mobileDrawerRef.value?.close();
  isClosing.value = false;
  emit("update:modelValue", false);
  if (import.meta.client) {
    document.body.style.overflow = "";
  }
}
function handleTouchEnd() {
  if (!isDragging.value) return;
  isDragging.value = false;
  if (dragOffset.value > 100) {
    closeWithAnimation();
  } else {
    dragOffset.value = 0;
  }
}
const breakpoints = useBreakpoints(breakpointsTailwind);
const isLargeScreen = breakpoints.greaterOrEqual("lg");
function handleBackdropClick(event) {
  if (event.target === mobileDrawerRef.value) {
    closeWithAnimation();
  }
}
function syncDrawer() {
  if (!import.meta.client || !mobileDrawerRef.value) return;
  if (isLargeScreen.value) {
    if (mobileDrawerRef.value.open) {
      mobileDrawerRef.value.close();
    }
    document.body.style.overflow = "";
    return;
  }
  if (props.modelValue) {
    isClosing.value = false;
    if (!mobileDrawerRef.value.open) {
      mobileDrawerRef.value.showModal();
      document.body.style.overflow = "hidden";
    }
  } else {
    if (mobileDrawerRef.value.open && !isClosing.value) {
      closeWithAnimation();
    } else if (!mobileDrawerRef.value.open) {
      document.body.style.overflow = "";
    }
  }
}
watch([() => props.modelValue, isLargeScreen], syncDrawer);
onMounted(() => {
  syncDrawer();
});
onUnmounted(() => {
  if (import.meta.client) {
    document.body.style.overflow = "";
  }
});
</script>

<template>
  <dialog
    ref="mobileDrawerRef"
    class="lg:hidden fixed inset-x-0 mx-auto bottom-0 z-[100] m-0 mt-auto w-full max-h-[85dvh] rounded-t-[20px] border-none bg-default p-0 shadow-2xl backdrop:bg-black/50 backdrop:backdrop-blur-sm open:flex open:flex-col mobile-drawer"
    :class="{ 'is-closing': isClosing }"
    :style="{
  transform: dragOffset > 0 ? `translateY(${dragOffset}px)` : '',
  transition: isDragging ? 'none' : 'transform 0.3s ease-out'
}"
    @cancel="closeWithAnimation"
    @click="handleBackdropClick"
    @touchstart="handleTouchStart"
    @touchmove="handleTouchMove"
    @touchend="handleTouchEnd"
  >
    <div
      class="w-10 h-1.5 bg-muted rounded-full mx-auto my-3 shrink-0 cursor-grab active:cursor-grabbing"
    />
    <div
      class="overflow-y-auto"
      :class="[
  padding ? 'px-4 pb-[calc(env(safe-area-inset-bottom)+20px)]' : 'pb-[env(safe-area-inset-bottom)]'
]"
    >
      <slot />
    </div>
  </dialog>
</template>

<style scoped>
.mobile-drawer[open]{animation:slide-up .3s ease-out}.mobile-drawer[open]::backdrop{animation:fade-in .3s ease-out}.mobile-drawer.is-closing{animation:slide-down .3s ease-in forwards}.mobile-drawer.is-closing::backdrop{animation:fade-out .3s ease-in forwards}@keyframes slide-up{0%{transform:translateY(100%)}to{transform:translateY(0)}}@keyframes slide-down{0%{transform:translateY(0)}to{transform:translateY(100%)}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-out{0%{opacity:1}to{opacity:0}}
</style>
