<template>
  <Teleport to="body">
    <Transition name="bottom-sheet">
      <div v-if="modelValue" class="bottom-sheet-overlay" @click.self="handleOverlayClick">
        <div
          class="bottom-sheet"
          ref="sheetRef"
          @touchstart="handleTouchStart"
          @touchmove="handleTouchMove"
          @touchend="handleTouchEnd"
        >
          <!-- Drag Handle -->
          <div class="bottom-sheet-handle" @click="close">
            <div class="handle-bar"></div>
          </div>

          <!-- Content Slot -->
          <div class="bottom-sheet-content">
            <slot></slot>
          </div>
        </div>
      </div>
    </Transition>
  </Teleport>
</template>

<script setup>
import { ref } from 'vue'

/**
 * BottomSheet - Material Design 3 inspired bottom sheet for mobile filters and actions
 *
 * Props:
 * - modelValue (v-model:visible): Controls visibility of the bottom sheet
 * - closeOnOverlay: Whether to close when clicking the overlay (default: true)
 * - closeOnSwipeDown: Whether to close when swiping down on handle (default: true)
 *
 * Events:
 * - update:modelValue: Emitted when visibility changes (for v-model support)
 *
 * Slots:
 * - default: Content to display inside the bottom sheet
 *
 * Features:
 * - Smooth slide-up animation
 * - Drag handle at top for visual affordance
 * - Close on tap outside (overlay)
 * - Swipe down to close (touch gesture)
 * - Teleported to body to avoid z-index issues
 *
 * Usage:
 * <BottomSheet v-model="isFilterOpen">
 *   <FilterContent />
 * </BottomSheet>
 */

const props = defineProps({
  /**
   * Controls visibility of the bottom sheet (v-model support)
   */
  modelValue: {
    type: Boolean,
    default: false
  },
  /**
   * Whether clicking the overlay closes the sheet
   */
  closeOnOverlay: {
    type: Boolean,
    default: true
  },
  /**
   * Whether swiping down on the handle closes the sheet
   */
  closeOnSwipeDown: {
    type: Boolean,
    default: true
  }
})

const emit = defineEmits(['update:modelValue'])

// Reference to the sheet element for touch handling
const sheetRef = ref(null)

// Touch tracking state
let touchStartY = 0
let touchCurrentY = 0
const SWIPE_THRESHOLD = 100 // Minimum swipe distance to close

/**
 * Close the bottom sheet
 */
const close = () => {
  emit('update:modelValue', false)
}

/**
 * Handle click on overlay background
 */
const handleOverlayClick = () => {
  if (props.closeOnOverlay) {
    close()
  }
}

/**
 * Handle touch start for swipe gesture
 */
const handleTouchStart = (event) => {
  if (!props.closeOnSwipeDown) return
  touchStartY = event.touches[0].clientY
  touchCurrentY = touchStartY
}

/**
 * Handle touch move for swipe gesture
 */
const handleTouchMove = (event) => {
  if (!props.closeOnSwipeDown) return
  touchCurrentY = event.touches[0].clientY

  // Calculate drag distance (only allow downward movement)
  const dragDistance = Math.max(0, touchCurrentY - touchStartY)

  // Apply transform for visual feedback
  if (sheetRef.value && dragDistance > 0) {
    sheetRef.value.style.transform = `translateY(${dragDistance}px)`
    sheetRef.value.style.transition = 'none'
  }
}

/**
 * Handle touch end - close if swiped enough
 */
const handleTouchEnd = () => {
  if (!props.closeOnSwipeDown || !sheetRef.value) return

  const dragDistance = touchCurrentY - touchStartY

  // Reset transform and enable transition
  sheetRef.value.style.transition = ''
  sheetRef.value.style.transform = ''

  // Close if dragged past threshold
  if (dragDistance > SWIPE_THRESHOLD) {
    close()
  }

  // Reset touch tracking
  touchStartY = 0
  touchCurrentY = 0
}
</script>

<style scoped>
/* ================================================
   BottomSheet Component Styles
   Material Design 3 inspired bottom sheet
   ================================================ */

/* Overlay background */
.bottom-sheet-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.5);
  z-index: var(--z-modal-backdrop);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

/* Main bottom sheet container */
.bottom-sheet {
  width: 100%;
  max-height: 90vh;
  background: var(--surface-card);
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  box-shadow: var(--shadow-xl);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  z-index: var(--z-modal);
}

/* Drag handle container */
.bottom-sheet-handle {
  display: flex;
  justify-content: center;
  padding: var(--space-sm) var(--space-md);
  cursor: pointer;
  /* Touch target minimum size */
  min-height: 32px;
}

/* Drag handle bar (visual indicator) */
.handle-bar {
  width: 40px;
  height: 4px;
  background: var(--surface-border);
  border-radius: var(--radius-full);
}

/* Content area with scroll support */
.bottom-sheet-content {
  flex: 1;
  padding: 0 var(--space-md) var(--space-lg);
  overflow-y: auto;
  -webkit-overflow-scrolling: touch;
}

/* ================================================
   Slide-up Animation (Vue Transition)
   ================================================ */

.bottom-sheet-enter-active,
.bottom-sheet-leave-active {
  transition: opacity var(--transition-normal);
}

.bottom-sheet-enter-active .bottom-sheet,
.bottom-sheet-leave-active .bottom-sheet {
  transition: transform var(--transition-normal);
}

/* Initial state: invisible + sheet below viewport */
.bottom-sheet-enter-from,
.bottom-sheet-leave-to {
  opacity: 0;
}

.bottom-sheet-enter-from .bottom-sheet,
.bottom-sheet-leave-to .bottom-sheet {
  transform: translateY(100%);
}

/* Final state: visible + sheet in place */
.bottom-sheet-enter-to,
.bottom-sheet-leave-from {
  opacity: 1;
}

.bottom-sheet-enter-to .bottom-sheet,
.bottom-sheet-leave-from .bottom-sheet {
  transform: translateY(0);
}

/* ================================================
   Dark Mode Support
   ================================================ */

/* Manual dark mode via data-theme attribute */
[data-theme="dark"] .bottom-sheet-overlay {
  background: rgba(0, 0, 0, 0.7);
}

[data-theme="dark"] .bottom-sheet {
  background: var(--surface-card);
  box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.4);
}

[data-theme="dark"] .handle-bar {
  background: var(--surface-border);
}

/* Auto dark mode (when no manual theme is set) */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme]) .bottom-sheet-overlay {
    background: rgba(0, 0, 0, 0.7);
  }

  :root:not([data-theme]) .bottom-sheet {
    background: var(--surface-card);
    box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.4);
  }

  :root:not([data-theme]) .handle-bar {
    background: var(--surface-border);
  }
}
</style>
