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

const props = defineProps({
    productId: {
        type: [Number, String],
        default: null
    },
    uploadUrl: {
        type: String,
        required: true
    },
    initialImages: {
        type: Array,
        default: () => []
    }
})

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

// --- State ---
const images = ref([])   // { id, name, url, uploading?, progress? }
const isDragging = ref(false)

// Hydrate from initial data (Edit Mode)
watch(() => props.initialImages, (val) => {
    if (val && val.length > 0) {
        images.value = val.map(img => ({
            id: img.id,
            name: img.name,
            url: img.url,
            existing: true
        }))
        emitMediaIds()
    }
}, { immediate: true })

// --- Upload Logic ---
const fileInput = ref(null)

const triggerUpload = () => {
    fileInput.value?.click()
}

const handleFiles = (files) => {
    Array.from(files).forEach(file => {
        if (!file.type.startsWith('image/')) return
        uploadFile(file)
    })
}

const onFileSelected = (e) => {
    handleFiles(e.target.files)
    e.target.value = '' // Reset so same file can be re-selected
}

const uploadFile = async (file) => {
    // Create a preview placeholder
    const tempId = 'temp_' + Date.now() + '_' + Math.random().toString(36).substr(2, 5)
    const previewUrl = URL.createObjectURL(file)

    const placeholder = {
        id: tempId,
        name: file.name,
        url: previewUrl,
        uploading: true,
        progress: 0,
        existing: false
    }
    images.value.push(placeholder)

    const formData = new FormData()
    formData.append('file', file)
    formData.append('tag', 'gallery')
    if (props.productId) {
        formData.append('product_id', props.productId)
    }

    try {
        const response = await axios.post(props.uploadUrl, formData, {
            headers: { 'Content-Type': 'multipart/form-data' },
            onUploadProgress: (e) => {
                const idx = images.value.findIndex(i => i.id === tempId)
                if (idx > -1) {
                    images.value[idx].progress = Math.round((e.loaded / e.total) * 100)
                }
            }
        })

        // Replace temp with real data
        const idx = images.value.findIndex(i => i.id === tempId)
        if (idx > -1) {
            images.value[idx].id = response.data // AdminMediaController returns media ID
            images.value[idx].uploading = false
            images.value[idx].existing = false   // Newly uploaded (needs attach on create)
        }

        URL.revokeObjectURL(previewUrl)
        emitMediaIds()
    } catch (err) {
        console.error('Upload failed:', err)
        // Remove failed placeholder
        images.value = images.value.filter(i => i.id !== tempId)
        URL.revokeObjectURL(previewUrl)
    }
}

const removeImage = async (index) => {
    const image = images.value[index]
    
    // If it's an existing image attached to the product, detach it via API?
    // For simplicity, we just remove from our list. The backend can sync on save.
    // TODO: Optionally call a delete endpoint here.
    
    images.value.splice(index, 1)
    emitMediaIds()
}

const emitMediaIds = () => {
    // Emit all current image IDs (existing + newly uploaded) so the backend
    // can sync the full gallery set and detect removals.
    const allIds = images.value
        .filter(i => !i.uploading)
        .map(i => i.id)
    emit('update:mediaIds', allIds)
}

// --- Drag & Drop ---
const onDragOver = (e) => {
    e.preventDefault()
    isDragging.value = true
}

const onDragLeave = () => {
    isDragging.value = false
}

const onDrop = (e) => {
    e.preventDefault()
    isDragging.value = false
    if (e.dataTransfer.files.length) {
        handleFiles(e.dataTransfer.files)
    }
}

// Expose method for parent to get all media IDs
const getMediaIds = () => {
    return images.value
        .filter(i => !i.uploading)
        .map(i => i.id)
}

defineExpose({ getMediaIds })
</script>

<template>
    <div class="card rounded-xl border-0 p-4">
        <h2 class="h6 fw-semibold mb-3 d-flex align-items-center gap-2">
            <span class="material-icons text-secondary" style="font-size: 1.2rem;">image</span>
            Product Images
        </h2>

        <!-- Image Grid -->
        <div class="row g-2 mb-3" v-if="images.length > 0">
            <div class="col-6" v-for="(image, index) in images" :key="image.id">
                <div class="position-relative rounded-lg overflow-hidden border bg-light group-hover-container"
                     style="aspect-ratio: 1;">
                    <img :src="image.url" class="w-100 h-100 object-fit-cover" :alt="image.name">

                    <!-- Upload Progress Overlay -->
                    <div v-if="image.uploading" 
                         class="position-absolute top-0 start-0 w-100 h-100 d-flex flex-column align-items-center justify-content-center"
                         style="background: rgba(0,0,0,0.5);">
                        <div class="spinner-border text-white spinner-border-sm mb-2"></div>
                        <span class="text-white small fw-medium">{{ image.progress }}%</span>
                    </div>

                    <!-- Remove Button -->
                    <button v-if="!image.uploading"
                            class="btn btn-sm position-absolute top-0 end-0 m-1 p-1 rounded-circle d-flex align-items-center justify-content-center"
                            style="width: 28px; height: 28px; background: rgba(0,0,0,0.6);"
                            @click="removeImage(index)">
                        <span class="material-icons text-white" style="font-size: 16px;">close</span>
                    </button>
                </div>
            </div>
        </div>

        <!-- Drop Zone / Upload Button -->
        <div class="border-2 border-dashed rounded-lg p-4 text-center cursor-pointer transition"
             :class="isDragging ? 'border-primary bg-primary-subtle' : 'border-secondary-subtle bg-light'"
             @click="triggerUpload"
             @dragover="onDragOver"
             @dragleave="onDragLeave"
             @drop="onDrop">
            <span class="material-icons text-secondary mb-2 d-block" style="font-size: 2rem;">cloud_upload</span>
            <p class="small text-secondary mb-1 fw-medium">
                {{ images.length > 0 ? 'Add more images' : 'Click to upload or drag & drop' }}
            </p>
            <p class="x-small text-secondary mb-0 opacity-75">PNG, JPG, WEBP up to 5MB</p>
        </div>

        <!-- Hidden File Input -->
        <input type="file" ref="fileInput" class="d-none" accept="image/*" multiple @change="onFileSelected">
    </div>
</template>
