<template>
  <Teleport to="body">
    <div v-if="isOpen" class="fixed inset-0 z-50 flex items-center justify-center">
      <div
        ref="modalRef"
        :style="{
          position: 'absolute',
          left: `${position.x}px`,
          top: `${position.y}px`,
        }"
        class="bg-white rounded-2xl border-2 border-gray-300 shadow-xl max-w-4xl w-full max-h-[90vh] flex flex-col"
      >
        <!-- Header - Make it the drag handle -->
        <div class="flex justify-between items-center p-6 border-b border-gray-100 cursor-move" @mousedown="startDrag" @touchstart="startDrag">
          <h3 class="text-2xl font-semibold text-gray-900">{{ title }}</h3>
          <button @click="close" class="p-2 hover:bg-gray-100 rounded-lg transition-colors">
            <svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6 text-gray-500" fill="none" viewBox="0 0 24 24" stroke="currentColor">
              <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
            </svg>
          </button>
        </div>

        <!-- Body -->
        <div class="p-6 flex-1 overflow-auto">
          <slot></slot>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
  import { ref, onMounted, onUnmounted, watch } from 'vue';

  const props = defineProps<{
    isOpen: boolean;
    title: string;
  }>();

  const emit = defineEmits<{
    (e: 'close'): void;
  }>();

  const modalRef = ref<HTMLElement | null>(null);
  const position = ref({ x: 0, y: 0 });
  const isDragging = ref(false);
  const dragOffset = ref({ x: 0, y: 0 });

  // Center the modal when it opens
  const centerModal = () => {
    if (!modalRef.value) return;

    const modalRect = modalRef.value.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    position.value = {
      x: (viewportWidth - modalRect.width) / 2,
      y: (viewportHeight - modalRect.height) / 2,
    };
  };

  const startDrag = (event: MouseEvent | TouchEvent) => {
    if (!modalRef.value) return;
    event.preventDefault();

    isDragging.value = true;

    const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;
    const clientY = 'touches' in event ? event.touches[0].clientY : event.clientY;

    dragOffset.value = {
      x: clientX - position.value.x,
      y: clientY - position.value.y,
    };

    document.addEventListener('mousemove', drag);
    document.addEventListener('touchmove', drag, { passive: false });
    document.addEventListener('mouseup', stopDrag);
    document.addEventListener('touchend', stopDrag);
  };

  const drag = (event: MouseEvent | TouchEvent) => {
    if (!isDragging.value || !modalRef.value) return;
    event.preventDefault();

    const clientX = 'touches' in event ? event.touches[0].clientX : event.clientX;
    const clientY = 'touches' in event ? event.touches[0].clientY : event.clientY;

    const modalRect = modalRef.value.getBoundingClientRect();
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;

    // Calculate new position
    let newX = clientX - dragOffset.value.x;
    let newY = clientY - dragOffset.value.y;

    // Constrain to viewport bounds
    newX = Math.max(0, Math.min(newX, viewportWidth - modalRect.width));
    newY = Math.max(0, Math.min(newY, viewportHeight - modalRect.height));

    position.value = { x: newX, y: newY };
  };

  const stopDrag = () => {
    isDragging.value = false;
    document.removeEventListener('mousemove', drag);
    document.removeEventListener('touchmove', drag);
    document.removeEventListener('mouseup', stopDrag);
    document.removeEventListener('touchend', stopDrag);
  };

  const close = () => {
    emit('close');
    position.value = { x: 0, y: 0 };
  };

  // Handle ESC key to close modal
  const handleKeyDown = (event: KeyboardEvent) => {
    if (event.key === 'Escape' && props.isOpen) {
      close();
    }
  };

  // Handle window resize
  const handleResize = () => {
    if (!isDragging.value) {
      centerModal();
    }
  };

  // Watch for modal opening
  watch(
    () => props.isOpen,
    newValue => {
      if (newValue) {
        // Use nextTick to ensure the modal is mounted
        Vue.nextTick(() => {
          centerModal();
        });
      }
    }
  );

  onMounted(() => {
    document.addEventListener('keydown', handleKeyDown);
    window.addEventListener('resize', handleResize);
    if (props.isOpen) {
      centerModal();
    }
  });

  onUnmounted(() => {
    document.removeEventListener('keydown', handleKeyDown);
    window.removeEventListener('resize', handleResize);
    document.removeEventListener('mousemove', drag);
    document.removeEventListener('touchmove', drag);
    document.removeEventListener('mouseup', stopDrag);
    document.removeEventListener('touchend', stopDrag);
  });
</script>
