<template>
  <!-- Make the outer container always pointer-events-none so clicks pass through -->
  <div class="fixed inset-0 flex items-center justify-center z-50 pointer-events-none">
    <!-- Apply pointer-events-auto ONLY to the modal itself so it can be interacted with -->
    <div
      class="bg-gray-800 rounded-lg overflow-auto scrollbar-hide shadow-lg pointer-events-auto relative"
      :class="{ invisible: !isModalOpen, visible: isModalOpen }"
      :style="{
        transform: `translate3d(${position.x}px, ${position.y + (isModalOpen ? 0 : -20)}px, 0)`,
        width: `${modalSize.width}px`,
        height: `${modalSize.height}px`,
        maxWidth: '90vw',
        maxHeight: '90vh',
      }"
    >
      <div class="flex items-center justify-between p-4 bg-gray-700 border-b border-gray-600 cursor-move" @mousedown="startDrag">
        <div class="flex items-center gap-2 text-lg font-semibold select-none">
          <i class="fas fa-film text-blue-500"></i>
          <span>Animation Preview</span>
        </div>
        <button @click="closeModal" class="text-gray-400 hover:text-gray-200 text-xl">
          <i class="fas fa-times"></i>
        </button>
      </div>

      <div class="p-6 flex flex-col h-[calc(100%-64px)]">
        <div class="flex flex-wrap items-center gap-4 mb-6">
          <div class="flex gap-2">
            <button
              @click="startAnimation"
              :disabled="sprites.length === 0"
              :class="{
                'bg-blue-500 border-blue-500 hover:bg-blue-600 hover:border-blue-600': !animation.isPlaying,
              }"
              class="flex items-center gap-2 border rounded px-4 py-2 text-sm transition-colors disabled:opacity-60 disabled:cursor-not-allowed"
            >
              <i class="fas fa-play"></i> Play
            </button>
            <button
              @click="stopAnimation"
              :disabled="sprites.length === 0"
              :class="{
                'bg-blue-500 border-blue-500 hover:bg-blue-600 hover:border-blue-600': animation.isPlaying,
              }"
              class="flex items-center gap-2 bg-gray-700 text-gray-200 border border-gray-600 rounded px-4 py-2 text-sm transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500"
            >
              <i class="fas fa-pause"></i> Pause
            </button>
          </div>

          <div class="flex flex-col gap-2 flex-grow">
            <div class="flex justify-between text-sm text-gray-400">
              <label for="frame-slider">Frame:</label>
              <span>{{ currentFrameDisplay }}</span>
            </div>
            <input type="range" id="frame-slider" v-model="currentFrame" :min="0" :max="Math.max(0, sprites.length - 1)" class="w-full h-1 bg-gray-600 rounded appearance-none focus:outline-none cursor-pointer" @input="handleFrameChange" />
          </div>

          <div class="flex flex-col gap-2 flex-grow">
            <div class="flex justify-between text-sm text-gray-400">
              <label for="framerate">Frame Rate:</label>
              <span>{{ animation.frameRate }} FPS</span>
            </div>
            <input type="range" id="framerate" v-model.number="animation.frameRate" min="1" max="30" class="w-full h-1 bg-gray-600 rounded appearance-none focus:outline-none cursor-pointer" @input="handleFrameRateChange" />
          </div>
        </div>

        <div class="flex flex-wrap items-center justify-between gap-4 mb-6">
          <!-- Zoom controls -->
          <div class="flex items-center gap-2">
            <button @click="zoomOut" :disabled="previewZoom <= 1" class="flex items-center justify-center w-8 h-8 bg-gray-700 text-gray-200 border border-gray-600 rounded transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500">
              <i class="fas fa-search-minus"></i>
            </button>
            <span class="text-sm text-gray-300">{{ Math.round(previewZoom * 100) }}%</span>
            <button @click="zoomIn" :disabled="previewZoom >= 5" class="flex items-center justify-center w-8 h-8 bg-gray-700 text-gray-200 border border-gray-600 rounded transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500">
              <i class="fas fa-search-plus"></i>
            </button>
            <button
              @click="applyOffsetsToMainView"
              :disabled="!hasSpriteOffset"
              class="flex items-center gap-1 px-2 h-8 bg-gray-700 text-gray-200 border border-gray-600 rounded text-xs transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500"
              title="Permanently apply offset to sprite position"
            >
              <i class="fas fa-save"></i>
              Apply Offset
            </button>
            <button @click="resetZoom" :disabled="previewZoom === 1" class="flex items-center justify-center px-2 h-8 bg-gray-700 text-gray-200 border border-gray-600 rounded text-xs transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500">Reset Zoom</button>
          </div>

          <!-- Controls -->
          <div class="flex items-center gap-4">
            <!-- Show all sprites toggle -->
            <label class="flex items-center gap-2 text-sm text-gray-300 cursor-pointer">
              <input type="checkbox" v-model="showAllSprites" class="form-checkbox h-4 w-4 text-blue-500 rounded border-gray-600 bg-gray-700 focus:ring-blue-500" />
              Show all frames
            </label>

            <!-- Reset sprite position button -->
            <button
              @click="resetSpritePosition"
              :disabled="!hasSpriteOffset"
              class="flex items-center gap-1 px-2 h-8 bg-gray-700 text-gray-200 border border-gray-600 rounded text-xs transition-colors disabled:opacity-60 disabled:cursor-not-allowed hover:border-blue-500"
              title="Reset sprite to original position"
            >
              <i class="fas fa-crosshairs"></i>
              Reset Position
            </button>
          </div>
        </div>

        <div class="flex flex-col justify-center items-center bg-gray-700 p-6 rounded mb-6 relative overflow-auto flex-grow">
          <!-- Tooltip for dragging instructions -->
          <div class="text-xs text-gray-400 mb-2" v-if="hasSpriteOffset || sprites.length > 0">
            <span v-if="hasSpriteOffset">Sprite offset: {{ Math.round(spriteOffset.x) }}px, {{ Math.round(spriteOffset.y) }}px</span>
            <span v-else>Click and drag the sprite to move it within the cell</span>
          </div>

          <div
            class="canvas-container relative transition-transform duration-100 flex items-center justify-center"
            :style="{
              minWidth: `${store.cellSize.width * previewZoom}px`,
              minHeight: `${store.cellSize.height * previewZoom}px`,
              cursor: previewZoom > 1 ? (isViewportDragging ? 'grabbing' : 'grab') : 'default',
            }"
            @mousedown="startViewportDrag"
            @wheel="handleCanvasWheel"
          >
            <div
              class="sprite-wrapper"
              :style="{
                transform: `scale(${previewZoom}) translate(${viewportOffset.x}px, ${viewportOffset.y}px)`,
                cursor: isCanvasDragging ? 'grabbing' : 'move',
              }"
              @mousedown.stop="startCanvasDrag"
              title="Drag to move sprite within cell"
            >
              <canvas ref="animCanvas" class="block" style="image-rendering: pixelated"></canvas>
            </div>
          </div>
        </div>
      </div>

      <!-- Resize handle - larger and more noticeable -->
      <div class="absolute bottom-0 right-0 w-8 h-8 cursor-se-resize flex items-end justify-end bg-gradient-to-br from-transparent to-gray-700 hover:to-blue-500 transition-colors duration-200" @mousedown="startResize">
        <i class="fas fa-grip-lines-diagonal text-gray-400 hover:text-white p-1"></i>
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
  import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
  import { useSpritesheetStore } from '../composables/useSpritesheetStore';

  const store = useSpritesheetStore();
  const animCanvas = ref<HTMLCanvasElement | null>(null);

  const isModalOpen = computed(() => store.isModalOpen.value);
  const sprites = computed(() => store.sprites.value);
  const animation = computed(() => store.animation);
  const previewBorder = computed(() => store.previewBorder);

  const currentFrame = ref(0);
  const position = ref({ x: 0, y: 0 });
  const isDragging = ref(false);
  const dragOffset = ref({ x: 0, y: 0 });

  // New state for added features
  const previewZoom = ref(1);
  const showAllSprites = ref(false);
  // Use a computed property to access and modify the store's sprite offset for the current frame
  const spriteOffset = computed({
    get: () => {
      // Get the offset for the current frame
      const frameOffset = store.getSpriteOffset(currentFrame.value);
      // Update the current offset for UI display
      store.currentSpriteOffset.x = frameOffset.x;
      store.currentSpriteOffset.y = frameOffset.y;
      return store.currentSpriteOffset;
    },
    set: val => {
      // Update both the current offset and the frame-specific offset
      store.currentSpriteOffset.x = val.x;
      store.currentSpriteOffset.y = val.y;

      // Get the frame-specific offset and update it
      const frameOffset = store.getSpriteOffset(currentFrame.value);
      frameOffset.x = val.x;
      frameOffset.y = val.y;
    },
  });
  const isCanvasDragging = ref(false);
  const canvasDragStart = ref({ x: 0, y: 0 });

  // Canvas viewport navigation state
  const viewportOffset = ref({ x: 0, y: 0 });
  const isViewportDragging = ref(false);
  const viewportDragStart = ref({ x: 0, y: 0 });

  // Modal size state for resize functionality
  const modalSize = ref({ width: 800, height: 600 });
  const isResizing = ref(false);
  const initialSize = ref({ width: 0, height: 0 });
  const resizeStart = ref({ x: 0, y: 0 });

  const currentFrameDisplay = computed(() => {
    const totalFrames = Math.max(1, sprites.value.length);
    const frame = Math.min(currentFrame.value + 1, totalFrames);
    return `${frame} / ${totalFrames}`;
  });

  // Computed property to check if sprite has been moved from original position
  const hasSpriteOffset = computed(() => {
    return spriteOffset.x !== 0 || spriteOffset.y !== 0;
  });

  const applyOffsetsToMainView = () => {
    store.applyOffsetsToMainView();
    store.showNotification('Offset permanently applied to sprite position');
  };

  const handleKeyDown = (e: KeyboardEvent) => {
    if (!isModalOpen.value) return;

    if (e.key === 'Escape') {
      closeModal();
    } else if (e.key === ' ' || e.key === 'Spacebar') {
      // Toggle play/pause
      if (animation.value.isPlaying) {
        stopAnimation();
      } else if (sprites.value.length > 0) {
        startAnimation();
      }
      e.preventDefault();
    } else if (e.key === 'ArrowRight' && !animation.value.isPlaying && sprites.value.length > 0) {
      // Next frame
      currentFrame.value = (currentFrame.value + 1) % sprites.value.length;
      updateFrame();
    } else if (e.key === 'ArrowLeft' && !animation.value.isPlaying && sprites.value.length > 0) {
      // Previous frame
      currentFrame.value = (currentFrame.value - 1 + sprites.value.length) % sprites.value.length;
      updateFrame();
    } else if (e.key === '+' || e.key === '=') {
      // Zoom in
      zoomIn();
      e.preventDefault();
    } else if (e.key === '-' || e.key === '_') {
      // Zoom out
      zoomOut();
      e.preventDefault();
    } else if (e.key === '0') {
      // Reset zoom
      resetZoom();
      e.preventDefault();
    } else if (e.key === 'r') {
      if (e.shiftKey) {
        // Shift+R: Reset sprite position only
        resetSpritePosition();
      } else {
        // R: Reset both sprite position and viewport
        // Reset the sprite offset for the current frame
        const frameOffset = store.getSpriteOffset(currentFrame.value);
        frameOffset.x = 0;
        frameOffset.y = 0;
        store.currentSpriteOffset.x = 0;
        store.currentSpriteOffset.y = 0;
        viewportOffset.value = { x: 0, y: 0 };
        updateFrame();
        store.showNotification('View and position reset');
      }
      e.preventDefault();
    } else if (previewZoom.value > 1) {
      // Arrow key navigation for panning when zoomed in
      const panAmount = 10;
      if (e.key === 'ArrowUp') {
        viewportOffset.value.y += panAmount / previewZoom.value;
        e.preventDefault();
      } else if (e.key === 'ArrowDown') {
        viewportOffset.value.y -= panAmount / previewZoom.value;
        e.preventDefault();
      } else if (e.key === 'ArrowLeft' && animation.value.isPlaying) {
        viewportOffset.value.x += panAmount / previewZoom.value;
        e.preventDefault();
      } else if (e.key === 'ArrowRight' && animation.value.isPlaying) {
        viewportOffset.value.x -= panAmount / previewZoom.value;
        e.preventDefault();
      }
    }
  };

  const openModal = async () => {
    if (sprites.value.length === 0) {
      store.showNotification('Please add sprites first', 'error');
      return;
    }

    // Center the modal in the viewport
    const viewportWidth = window.innerWidth;
    const viewportHeight = window.innerHeight;
    position.value = {
      x: (viewportWidth - modalSize.value.width) / 2,
      y: (viewportHeight - modalSize.value.height) / 2,
    };

    // Reset zoom but keep sprite offset if it exists
    previewZoom.value = 1;
    viewportOffset.value = { x: 0, y: 0 };

    // Reset modal size to default
    modalSize.value = { width: 800, height: 600 };

    // Reset to first frame
    currentFrame.value = 0;
    animation.value.currentFrame = 0;

    await initializeCanvas();

    // Set modal open state if not already open
    if (!store.isModalOpen.value) {
      store.isModalOpen.value = true;
    }

    // Wait for next frame to ensure DOM is updated
    await new Promise(resolve => requestAnimationFrame(resolve));

    // Set proper canvas size before rendering
    updateCanvasSize();

    // Force render the first frame
    if (sprites.value.length > 0) {
      // Get the frame-specific offset for the first frame
      const frameOffset = store.getSpriteOffset(0);

      // Update the current offset for UI display
      store.currentSpriteOffset.x = frameOffset.x;
      store.currentSpriteOffset.y = frameOffset.y;

      // Render with the frame-specific offset
      store.renderAnimationFrame(0, showAllSprites.value, frameOffset);
    }
  };

  const updateCanvasSize = () => {
    if (animCanvas.value && store.cellSize.width && store.cellSize.height) {
      animCanvas.value.width = store.cellSize.width;
      animCanvas.value.height = store.cellSize.height;

      // Also update container size
      updateCanvasContainerSize();
    }
  };

  const closeModal = () => {
    store.isModalOpen.value = false;

    // Stop animation if it's playing
    if (animation.value.isPlaying) {
      stopAnimation();
    }
  };

  const startAnimation = () => {
    if (sprites.value.length === 0) return;
    store.startAnimation();
  };

  const stopAnimation = () => {
    store.stopAnimation();
  };

  const handleFrameChange = () => {
    // Stop any running animation
    if (animation.value.isPlaying) {
      stopAnimation();
    }
    updateFrame();
  };

  const updateFrame = () => {
    animation.value.currentFrame = currentFrame.value;
    animation.value.manualUpdate = true;

    // Get the frame-specific offset
    const frameOffset = store.getSpriteOffset(currentFrame.value);

    // Render with the frame-specific offset
    store.renderAnimationFrame(currentFrame.value, showAllSprites.value, frameOffset);
  };

  const handleFrameRateChange = () => {
    // If animation is currently playing, restart it with the new frame rate
    if (animation.value.isPlaying) {
      stopAnimation();
      startAnimation();
    }
  };

  // Modal drag functionality
  const startDrag = (e: MouseEvent) => {
    // Don't allow drag if currently resizing
    if (isResizing.value) return;

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

    // Add temporary event listeners
    window.addEventListener('mousemove', handleDrag);
    window.addEventListener('mouseup', stopDrag);
  };

  const handleDrag = (e: MouseEvent) => {
    if (!isDragging.value) return;

    requestAnimationFrame(() => {
      position.value = {
        x: e.clientX - dragOffset.value.x,
        y: e.clientY - dragOffset.value.y,
      };
    });
  };

  const stopDrag = () => {
    isDragging.value = false;
    window.removeEventListener('mousemove', handleDrag);
    window.removeEventListener('mouseup', stopDrag);
  };

  // NEW: Modal resize functionality
  const startResize = (e: MouseEvent) => {
    isResizing.value = true;
    initialSize.value = { ...modalSize.value };
    resizeStart.value = { x: e.clientX, y: e.clientY };

    // Add temporary event listeners
    window.addEventListener('mousemove', handleResize);
    window.addEventListener('mouseup', stopResize);

    // Prevent default to avoid text selection
    e.preventDefault();
  };

  const handleResize = (e: MouseEvent) => {
    if (!isResizing.value) return;

    const deltaX = e.clientX - resizeStart.value.x;
    const deltaY = e.clientY - resizeStart.value.y;

    requestAnimationFrame(() => {
      // Calculate new size with minimum constraints
      const newWidth = Math.max(400, initialSize.value.width + deltaX);
      const newHeight = Math.max(400, initialSize.value.height + deltaY);

      // Update modal size
      modalSize.value = {
        width: newWidth,
        height: newHeight,
      };
    });
  };

  const stopResize = () => {
    isResizing.value = false;
    window.removeEventListener('mousemove', handleResize);
    window.removeEventListener('mouseup', stopResize);
  };

  const initializeCanvas = async () => {
    if (!animCanvas.value) {
      console.error('PreviewModal: Animation canvas not found');
      return;
    }

    try {
      const context = animCanvas.value.getContext('2d');
      if (!context) {
        console.error('PreviewModal: Failed to get 2D context from animation canvas');
        return;
      }

      store.animation.canvas = animCanvas.value;
      store.animation.ctx = context;
    } catch (error) {
      console.error('PreviewModal: Error initializing animation canvas:', error);
    }
  };

  // Zoom functions
  const zoomIn = () => {
    if (previewZoom.value < 5) {
      previewZoom.value = Math.min(5, previewZoom.value + 0.5);

      // Adjust container size after zoom change
      nextTick(() => {
        updateCanvasContainerSize();
      });
    }
  };

  const zoomOut = () => {
    if (previewZoom.value > 1) {
      previewZoom.value = Math.max(1, previewZoom.value - 0.5);

      // Adjust container size after zoom change
      nextTick(() => {
        updateCanvasContainerSize();
      });
    }
  };

  const resetZoom = () => {
    previewZoom.value = 1;
    viewportOffset.value = { x: 0, y: 0 };

    // Adjust container size after zoom change
    nextTick(() => {
      updateCanvasContainerSize();
    });
  };

  // Reset sprite position to original
  const resetSpritePosition = () => {
    // Reset the sprite offset for the current frame to zero
    const frameOffset = store.getSpriteOffset(currentFrame.value);
    frameOffset.x = 0;
    frameOffset.y = 0;

    // Also update the current offset
    store.currentSpriteOffset.x = 0;
    store.currentSpriteOffset.y = 0;

    // Update the frame to reflect the change
    updateFrame();

    // Show a notification
    store.showNotification('Sprite position reset to original');
  };

  // Update canvas container size based on zoom level
  const updateCanvasContainerSize = () => {
    // This ensures the container grows with zoom while keeping the sprite visible
    if (!store.cellSize.width || !store.cellSize.height) return;

    // We'll update the container if needed through the reactive bindings
  };

  // Canvas drag functions for moving the sprite within its cell
  const startCanvasDrag = (e: MouseEvent) => {
    if (sprites.value.length === 0) return;

    // Don't start sprite dragging if we're already dragging the viewport
    if (isViewportDragging.value) return;

    isCanvasDragging.value = true;
    canvasDragStart.value = {
      x: e.clientX,
      y: e.clientY,
    };

    // Add temporary event listeners
    window.addEventListener('mousemove', handleCanvasDrag);
    window.addEventListener('mouseup', stopCanvasDrag);

    // Prevent default to avoid text selection
    e.preventDefault();
  };

  const handleCanvasDrag = (e: MouseEvent) => {
    if (!isCanvasDragging.value) return;

    const deltaX = e.clientX - canvasDragStart.value.x;
    const deltaY = e.clientY - canvasDragStart.value.y;

    // Update sprite offset with the delta, scaled by zoom level
    // Use requestAnimationFrame for smoother dragging
    requestAnimationFrame(() => {
      // Get the frame-specific offset
      const frameOffset = store.getSpriteOffset(currentFrame.value);

      // Update both the current offset and the frame-specific offset
      const newX = frameOffset.x + deltaX / previewZoom.value;
      const newY = frameOffset.y + deltaY / previewZoom.value;

      frameOffset.x = newX;
      frameOffset.y = newY;
      store.currentSpriteOffset.x = newX;
      store.currentSpriteOffset.y = newY;

      // Reset drag start position
      canvasDragStart.value = {
        x: e.clientX,
        y: e.clientY,
      };

      // Update the frame with the new offset
      updateFrame();

      // Re-render the main view to reflect the changes
      store.renderSpritesheetPreview();
    });
  };

  const stopCanvasDrag = () => {
    isCanvasDragging.value = false;
    window.removeEventListener('mousemove', handleCanvasDrag);
    window.removeEventListener('mouseup', stopCanvasDrag);
  };

  // Canvas viewport navigation functions
  const startViewportDrag = (e: MouseEvent) => {
    // Only enable viewport dragging when zoomed in
    if (previewZoom.value <= 1 || isCanvasDragging.value) return;

    isViewportDragging.value = true;
    viewportDragStart.value = {
      x: e.clientX,
      y: e.clientY,
    };

    // Add temporary event listeners
    window.addEventListener('mousemove', handleViewportDrag);
    window.addEventListener('mouseup', stopViewportDrag);

    // Prevent default to avoid text selection
    e.preventDefault();
  };

  const handleViewportDrag = (e: MouseEvent) => {
    if (!isViewportDragging.value) return;

    const deltaX = e.clientX - viewportDragStart.value.x;
    const deltaY = e.clientY - viewportDragStart.value.y;

    // Update viewport offset with the delta, scaled by zoom level
    viewportOffset.value = {
      x: viewportOffset.value.x + deltaX / previewZoom.value,
      y: viewportOffset.value.y + deltaY / previewZoom.value,
    };

    // Reset drag start position
    viewportDragStart.value = {
      x: e.clientX,
      y: e.clientY,
    };
  };

  const stopViewportDrag = () => {
    isViewportDragging.value = false;
    window.removeEventListener('mousemove', handleViewportDrag);
    window.removeEventListener('mouseup', stopViewportDrag);
  };

  // Handle mouse wheel zooming and panning
  const handleCanvasWheel = (e: WheelEvent) => {
    // Prevent the default scroll behavior
    e.preventDefault();

    if (e.ctrlKey) {
      // Ctrl + wheel = zoom in/out
      if (e.deltaY < 0) {
        zoomIn();
      } else {
        zoomOut();
      }
    } else {
      // Just wheel = pan when zoomed in
      if (previewZoom.value > 1) {
        // Adjust pan amount by zoom level
        const panFactor = 0.5 / previewZoom.value;

        if (e.shiftKey) {
          // Shift + wheel = horizontal pan
          viewportOffset.value.x -= e.deltaY * panFactor;
        } else {
          // Regular wheel = vertical pan
          viewportOffset.value.y -= e.deltaY * panFactor;
        }
      }
    }
  };

  onMounted(() => {
    initializeCanvas();
    window.addEventListener('keydown', handleKeyDown);
  });

  onBeforeUnmount(() => {
    window.removeEventListener('keydown', handleKeyDown);
    window.removeEventListener('mousemove', handleDrag);
    window.removeEventListener('mouseup', stopDrag);
    window.removeEventListener('mousemove', handleCanvasDrag);
    window.removeEventListener('mouseup', stopCanvasDrag);
    window.removeEventListener('mousemove', handleResize);
    window.removeEventListener('mouseup', stopResize);
    window.removeEventListener('mousemove', handleViewportDrag);
    window.removeEventListener('mouseup', stopViewportDrag);
  });

  // Keep currentFrame in sync with animation.currentFrame
  watch(
    () => animation.value.currentFrame,
    newVal => {
      currentFrame.value = newVal;
    }
  );

  // Watch for changes in sprites to update the canvas when new sprites are added
  watch(
    () => sprites.value,
    newSprites => {
      if (isModalOpen.value && newSprites.length > 0) {
        updateCanvasSize();
        updateCanvasContainerSize();
        store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
      }
    },
    { deep: true }
  );

  // Watch zoom changes to update container size
  watch(
    () => previewZoom.value,
    () => {
      updateCanvasContainerSize();
    }
  );

  // Watch for changes in border settings to update the preview
  watch(
    () => previewBorder.value,
    () => {
      if (isModalOpen.value && sprites.value.length > 0) {
        store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
      }
    },
    { deep: true }
  );

  // Watch for changes in showAllSprites to update the preview
  watch(
    () => showAllSprites.value,
    () => {
      if (isModalOpen.value && sprites.value.length > 0) {
        store.renderAnimationFrame(currentFrame.value, showAllSprites.value, spriteOffset.value);
      }
    }
  );

  // Expose openModal for external use
  defineExpose({ openModal });
</script>

<style scoped>
  input[type='range']::-webkit-slider-thumb {
    appearance: none;
    width: 15px;
    height: 15px;
    background: #0096ff;
    border-radius: 50%;
    cursor: pointer;
  }

  input[type='range']::-moz-range-thumb {
    width: 15px;
    height: 15px;
    background: #0096ff;
    border-radius: 50%;
    cursor: pointer;
  }

  /* Prevent text selection while dragging */
  .cursor-move {
    user-select: none;
  }

  /* Hide scrollbar styles */
  .scrollbar-hide {
    -ms-overflow-style: none; /* IE and Edge */
    scrollbar-width: none; /* Firefox */
  }

  .scrollbar-hide::-webkit-scrollbar {
    display: none; /* Chrome, Safari and Opera */
  }

  /* Cursor styles */
  .cursor-se-resize {
    cursor: se-resize;
  }

  /* Canvas container styles */
  .canvas-container {
    margin: auto;
    transition:
      min-width 0.2s,
      min-height 0.2s;
  }

  .sprite-wrapper {
    transform-origin: center;
  }
</style>
