<template>
  <Modal :is-open="isOpen" @close="cancel" title="Split spritesheet">
    <div class="space-y-6">
      <!-- Preview Image -->
      <div class="flex items-center justify-center">
        <img :src="imageUrl" alt="Spritesheet" class="max-w-full max-h-48 sm:max-h-64 border border-gray-300 dark:border-gray-600 rounded-lg" :style="settingsStore.pixelPerfect ? { 'image-rendering': 'pixelated' } : {}" />
      </div>

      <!-- Detection Mode -->
      <div class="space-y-4">
        <div class="space-y-2">
          <label class="block text-sm font-medium text-gray-700 dark:text-gray-300"> Detection Mode </label>
          <div class="grid grid-cols-2 gap-3">
            <button @click="detectionMode = 'grid'" :class="['px-4 py-3 rounded-lg border-2 text-left transition-all', detectionMode === 'grid' ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/30' : 'border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500']">
              <div class="font-medium text-gray-900 dark:text-gray-100">Grid</div>
              <div class="text-xs text-gray-500 dark:text-gray-400">Split by cell size</div>
            </button>
            <button @click="detectionMode = 'auto'" :class="['px-4 py-3 rounded-lg border-2 text-left transition-all', detectionMode === 'auto' ? 'border-blue-500 bg-blue-50 dark:bg-blue-900/30' : 'border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500']">
              <div class="font-medium text-gray-900 dark:text-gray-100">Auto-detect</div>
              <div class="text-xs text-gray-500 dark:text-gray-400">Find individual sprites</div>
            </button>
          </div>
        </div>

        <!-- Grid Mode Options -->
        <div v-if="detectionMode === 'grid'" class="space-y-4">
          <div class="grid grid-cols-2 gap-4">
            <div class="space-y-1">
              <label for="cell-width" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> Cell Width (px) </label>
              <input type="number" id="cell-width" v-model.number="cellWidth" min="1" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" />
            </div>
            <div class="space-y-1">
              <label for="cell-height" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> Cell Height (px) </label>
              <input type="number" id="cell-height" v-model.number="cellHeight" min="1" class="w-full px-3 py-2 border border-gray-300 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-200 rounded-md shadow-sm focus:outline-none focus:ring-blue-500 focus:border-blue-500" />
            </div>
          </div>

          <div class="flex items-center">
            <input type="checkbox" id="preserve-cell-size" v-model="preserveCellSize" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
            <label for="preserve-cell-size" class="ml-2 block text-sm text-gray-700 dark:text-gray-300"> Preserve cell size (keep transparent padding) </label>
          </div>

          <div v-if="imageElement" class="text-xs text-gray-500 dark:text-gray-400">Image: {{ imageElement.width }}×{{ imageElement.height }}px → {{ gridCols }}×{{ gridRows }} cells</div>
        </div>

        <!-- Auto-detect Options -->
        <div v-if="detectionMode === 'auto'" class="space-y-2">
          <label for="sensitivity" class="block text-sm font-medium text-gray-700 dark:text-gray-300"> Detection Sensitivity </label>
          <input type="range" id="sensitivity" v-model.number="sensitivity" min="1" max="100" class="w-full dark:accent-blue-400" />
          <div class="text-xs text-gray-500 dark:text-gray-400 flex justify-between">
            <span>Low (more sprites)</span>
            <span>High (fewer sprites)</span>
          </div>
        </div>

        <!-- Common Options -->
        <div class="flex items-center">
          <input type="checkbox" id="remove-empty" v-model="removeEmpty" class="h-4 w-4 text-blue-600 focus:ring-blue-500 border-gray-300 rounded" />
          <label for="remove-empty" class="ml-2 block text-sm text-gray-700 dark:text-gray-300"> Remove empty sprites </label>
        </div>
      </div>

      <!-- Preview -->
      <div v-if="previewSprites.length > 0 || isProcessing" class="space-y-2">
        <h3 class="text-sm font-medium text-gray-700 dark:text-gray-300">
          <span v-if="isProcessing">Detecting sprites...</span>
          <span v-else>Preview ({{ previewSprites.length }} sprites)</span>
        </h3>
        <div class="grid grid-cols-4 sm:grid-cols-6 md:grid-cols-8 gap-2 max-h-80 overflow-y-auto p-2 border border-gray-200 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-800">
          <div v-for="(sprite, index) in previewSprites" :key="index" class="relative border border-gray-300 dark:border-gray-600 rounded bg-white dark:bg-gray-700 flex items-center justify-center aspect-square">
            <img :src="sprite.url" alt="Sprite" class="max-w-full max-h-full object-contain" :style="settingsStore.pixelPerfect ? { 'image-rendering': 'pixelated' } : {}" />
          </div>
        </div>
      </div>

      <!-- Actions -->
      <div class="flex justify-end space-x-3">
        <button
          @click="cancel"
          class="px-4 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm text-sm font-medium text-gray-700 dark:text-gray-300 bg-white dark:bg-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
        >
          Cancel
        </button>
        <button
          @click="confirm"
          :disabled="previewSprites.length === 0 || isProcessing"
          class="px-4 py-2 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-blue-600 hover:bg-blue-700 disabled:opacity-50 disabled:cursor-not-allowed focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500"
        >
          {{ isProcessing ? 'Processing...' : 'Split spritesheet' }}
        </button>
      </div>
    </div>
  </Modal>
</template>

<script setup lang="ts">
  import { ref, watch, computed, onUnmounted } from 'vue';
  import Modal from './utilities/Modal.vue';
  import { useSettingsStore } from '@/stores/useSettingsStore';
  import { useSpritesheetSplitter } from '@/composables/useSpritesheetSplitter';
  import type { SpriteFile } from '@/types/sprites';
  import type { DetectionMode, SpritePreview } from '@/types/spritesheet';

  const props = defineProps<{
    isOpen: boolean;
    imageUrl: string;
    imageFile: File | null | undefined;
  }>();

  const emit = defineEmits<{
    (e: 'close'): void;
    (e: 'split', sprites: SpriteFile[]): void;
  }>();

  const settingsStore = useSettingsStore();
  const splitter = useSpritesheetSplitter();

  // State
  const detectionMode = ref<DetectionMode>('grid');
  const cellWidth = ref(64);
  const cellHeight = ref(64);
  const sensitivity = ref(50);
  const removeEmpty = ref(true);
  const preserveCellSize = ref(true);
  const previewSprites = ref<SpritePreview[]>([]);
  const isProcessing = ref(false);
  const imageElement = ref<HTMLImageElement | null>(null);

  // Computed
  const gridCols = computed(() => (imageElement.value && cellWidth.value > 0 ? Math.floor(imageElement.value.width / cellWidth.value) : 0));

  const gridRows = computed(() => (imageElement.value && cellHeight.value > 0 ? Math.floor(imageElement.value.height / cellHeight.value) : 0));

  // Load image and set initial cell size
  watch(
    () => props.imageUrl,
    url => {
      if (!url) return;

      const img = new Image();
      img.onload = () => {
        imageElement.value = img;

        // Set suggested cell size
        const suggested = splitter.getSuggestedCellSize(img.width, img.height);
        cellWidth.value = suggested.width;
        cellHeight.value = suggested.height;

        generatePreview();
      };
      img.src = url;
    },
    { immediate: true }
  );

  // Regenerate preview when options change
  watch([detectionMode, cellWidth, cellHeight, sensitivity, removeEmpty, preserveCellSize], () => {
    if (imageElement.value) {
      generatePreview();
    }
  });

  // Generate preview
  async function generatePreview() {
    if (!imageElement.value) return;

    isProcessing.value = true;
    previewSprites.value = [];

    try {
      const img = imageElement.value;

      if (detectionMode.value === 'grid') {
        previewSprites.value = await splitter.splitByGrid(img, {
          cellWidth: cellWidth.value,
          cellHeight: cellHeight.value,
          preserveCellSize: preserveCellSize.value,
          removeEmpty: removeEmpty.value,
        });
      } else {
        previewSprites.value = await splitter.detectSprites(img, {
          sensitivity: sensitivity.value,
          removeEmpty: removeEmpty.value,
        });
      }
    } catch (error) {
      console.error('Error generating preview:', error);
    } finally {
      isProcessing.value = false;
    }
  }

  // Actions
  function cancel() {
    emit('close');
  }

  async function confirm() {
    if (previewSprites.value.length === 0) return;

    isProcessing.value = true;

    try {
      const spriteFiles: SpriteFile[] = [];

      for (let i = 0; i < previewSprites.value.length; i++) {
        const sprite = previewSprites.value[i];
        const response = await fetch(sprite.url);
        const blob = await response.blob();
        const file = new File([blob], `sprite_${i + 1}.png`, { type: 'image/png' });

        spriteFiles.push({
          file,
          x: sprite.x,
          y: sprite.y,
          width: sprite.width,
          height: sprite.height,
        });
      }

      emit('split', spriteFiles);
      emit('close');
    } catch (error) {
      console.error('Error creating sprite files:', error);
    } finally {
      isProcessing.value = false;
    }
  }

  onUnmounted(() => {
    splitter.cleanup();
  });
</script>
