<script setup lang="ts">
import { useGalleryStore } from "../stores/gallery";
import { convertFileSrc } from "@tauri-apps/api/core";
import { ref, computed, onMounted, onUnmounted, watch, nextTick } from "vue";

const store = useGalleryStore();
const isDragging = ref(false);
const dragStart = ref({ x: 0, y: 0 });
const imgRef = ref<HTMLImageElement | null>(null);
const parentRef = ref<HTMLElement | null>(null); // The black background container

// These dimensions will exactly match the rendered image size
const imageRect = ref({ width: 0, height: 0 });

let resizeObserver: ResizeObserver | null = null;

const calculateLayout = () => {
    if (!imgRef.value || !parentRef.value || !store.selectedImage) return;

    // Wait for image natural dimensions to be available
    const natW = imgRef.value.naturalWidth;
    const natH = imgRef.value.naturalHeight;
    
    if (!natW || !natH) return; // Not loaded yet

    const parentW = parentRef.value.clientWidth;
    const parentH = parentRef.value.clientHeight;

    // Calculate 'contain' fit manually
    const scale = Math.min(
        (parentW - 64) / natW, // 64px = 2rem padding * 2 sides (p-8)
        (parentH - 64) / natH
    );

    // Prevent scaling up if image is smaller than screen? 
    // Usually hero view scales up to fit. Let's stick to contain logic (can scale up).
    
    const finalW = Math.floor(natW * scale);
    const finalH = Math.floor(natH * scale);

    imageRect.value = { width: finalW, height: finalH };
};

onMounted(() => {
    // Observe the parent container (window size changes)
    if (parentRef.value) {
        resizeObserver = new ResizeObserver(() => {
            calculateLayout();
        });
        resizeObserver.observe(parentRef.value);
    }
    window.addEventListener('resize', calculateLayout);
});

onUnmounted(() => {
    if (resizeObserver) resizeObserver.disconnect();
    window.removeEventListener('resize', calculateLayout);
});

// Re-calculate when image changes
watch(() => store.selectedImage, () => {
    // Reset size until loaded to avoid jump
    // imageRect.value = { width: 0, height: 0 }; 
    nextTick(() => calculateLayout());
});

// Use either manual position (if override is true) or ZCA suggestion
const position = computed(() => {
    if (store.watermarkSettings.manual_override) {
        return store.watermarkSettings.manual_position;
    }
    return store.selectedImage?.zcaSuggestion ? { x: store.selectedImage.zcaSuggestion.x, y: store.selectedImage.zcaSuggestion.y } : { x: 0.5, y: 0.99 };
});

const onMouseDown = (e: MouseEvent) => {
    e.preventDefault();
    isDragging.value = true;
    dragStart.value = { x: e.clientX, y: e.clientY };
};

const onMouseMove = (e: MouseEvent) => {
    // Need exact dimensions for drag calculation
    if (!isDragging.value || !store.selectedImage || imageRect.value.width === 0) return;
    
    const rect = imageRect.value; // Use our calculated rect, not bounding client rect (though they should match)

    const deltaX = (e.clientX - dragStart.value.x) / rect.width;
    const deltaY = (e.clientY - dragStart.value.y) / rect.height;

    // Update manual position
    let newX = position.value.x + deltaX;
    let newY = position.value.y + deltaY;
    
    // Clamp logic (0-1) - This is now strictly inside the image content area
    const padding = 0.005; 
    newX = Math.max(padding, Math.min(1 - padding, newX));
    newY = Math.max(padding, Math.min(1 - padding, newY));

    // Set store to manual mode immediately
    store.updateWatermarkSettings({
        manual_override: true,
        manual_position: { x: newX, y: newY }
    });

    dragStart.value = { x: e.clientX, y: e.clientY };
};

const onMouseUp = () => {
    isDragging.value = false;
};

const onMouseLeave = () => {
    isDragging.value = false;
};
</script>

<template>
  <div 
    ref="parentRef"
    class="absolute inset-0 flex items-center justify-center bg-black overflow-hidden"
    @mousemove="onMouseMove"
    @mouseup="onMouseUp"
    @mouseleave="onMouseLeave"
  >
    <!-- 
      Dynamic Wrapper:
      Dimensions strictly equal to the rendered image size.
      This serves as the coordinate system for the watermark.
    -->
    <div 
        v-if="store.selectedImage" 
        class="relative shadow-2xl" 
        :style="{
            width: imageRect.width + 'px',
            height: imageRect.height + 'px'
        }"
    >
      <img 
        ref="imgRef"
        :src="convertFileSrc(store.selectedImage.path)" 
        class="block w-full h-full select-none pointer-events-none"
        alt="Hero Image"
        loading="eager"
        decoding="sync"
        fetchpriority="high"
        @load="calculateLayout"
        @error="(e) => console.error('Hero Image Load Error:', e)"
      />
      
      <!-- Text Watermark Overlay -->
      <div 
        v-if="store.watermarkSettings.text"
        class="absolute cursor-move select-none whitespace-nowrap font-sans font-medium"
        :style="{
            left: (position.x * 100) + '%',
            top: (position.y * 100) + '%',
            transform: 'translate(-50%, -50%)',
            opacity: store.watermarkSettings.opacity,
            color: store.watermarkSettings.color,
            /* Scale based on HEIGHT of the IMAGE */
            fontSize: (imageRect.height * store.watermarkSettings.scale) + 'px',
            height: '0px', 
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
        }"
        @mousedown="onMouseDown"
      >
        <span> 
            {{ store.watermarkSettings.text }}
        </span>
        
        <!-- Selection Ring when dragging -->
        <div v-if="isDragging" class="absolute -inset-2 border border-blue-500 rounded-sm"></div>
      </div>
    </div>
    <div v-else class="text-gray-500 flex flex-col items-center">
      <p>No image selected</p>
    </div>
  </div>
</template>

<style scoped>
.image-container {
    /* Removed container-type: size to prevent layout collapse */
}

span {
    text-shadow: 
        -1px -1px 0 #000,  
         1px -1px 0 #000,
        -1px  1px 0 #000,
         1px  1px 0 #000;
}
</style>
