<script setup>
import { ref, computed, watch, onMounted } from 'vue'
import { VueDraggableNext } from 'vue-draggable-next'
import useDebounce from '../../../../composables/useDebounce.js'

const props = defineProps({
    field: Object,
})

const model = defineModel()

const searchQuery = ref('')
const searchResults = ref([])
const isLoading = ref(false)
const isOpen = ref(false)
const selectedItems = ref([])

// Debounce search to avoid too many API calls
const debouncedSearchFn = useDebounce((query) => {
    searchItems(query)
}, 300)

// Initialize selected items from model
onMounted(async () => {
    // Ensure model.value is always an array of IDs
    if (!model.value) {
        model.value = []
    } else if (!Array.isArray(model.value)) {
        model.value = [model.value]
    }
    
    if (model.value.length > 0) {
        await loadSelectedItems()
    }
})

// Load currently selected items to display their names
const loadSelectedItems = async () => {
    if (!model.value || model.value.length === 0) {
        selectedItems.value = []
        return
    }

    try {
        const response = await fetch(`${window.daylight.apiBase}/search?model=${props.field.relatedType}&selected=${model.value.join(',')}`, {
            credentials: 'same-origin'
        })
        const data = await response.json()
        const fetchedItems = data.results || []
        
        // Preserve the order from model.value
        selectedItems.value = model.value.map(id => {
            return fetchedItems.find(item => item.id == id)
        }).filter(Boolean) // Remove any undefined items
        
    } catch (error) {
        console.error('Error loading selected items:', error)
        selectedItems.value = []
    }
}

// Search for items based on query
const searchItems = async (query) => {
    if (!query || query.length < 2) {
        searchResults.value = []
        return
    }

    isLoading.value = true
    
    try {
        const selected = model.value || []
        const response = await fetch(`${window.daylight.apiBase}/search?model=${props.field.relatedType}&query=${encodeURIComponent(query)}&selected=${selected.join(',')}`, {
            credentials: 'same-origin'
        })
        const data = await response.json()
        searchResults.value = data.results || []
    } catch (error) {
        console.error('Error searching items:', error)
        searchResults.value = []
    } finally {
        isLoading.value = false
    }
}

// Watch for search query changes
watch(searchQuery, (newQuery) => {
    debouncedSearchFn(newQuery)
})

// Add item to selection
const selectItem = (item) => {
    if (!model.value) {
        model.value = []
    }
    
    // Ensure model.value is an array and check if item already selected
    const currentSelection = Array.isArray(model.value) ? model.value : []
    
    if (!currentSelection.includes(item.id)) {
        if (props.field.multiple !== false) {
            model.value = [...currentSelection, item.id]
            selectedItems.value = [...selectedItems.value, item]
        } else {
            // Single selection
            model.value = [item.id]
            selectedItems.value = [item]
        }
    }
    
    searchQuery.value = ''
    searchResults.value = []
    isOpen.value = false
}

// Remove item from selection
const removeItem = (itemId) => {
    if (model.value && Array.isArray(model.value)) {
        model.value = model.value.filter(id => id !== itemId)
        selectedItems.value = selectedItems.value.filter(item => item.id !== itemId)
    }
}

// Show/hide dropdown
const toggleDropdown = () => {
    isOpen.value = !isOpen.value
    if (isOpen.value) {
        searchQuery.value = ''
        searchResults.value = []
    }
}

const isMultiple = computed(() => props.field.multiple !== false)

// Clear all selected items
const clearSelection = () => {
    model.value = []
    selectedItems.value = []
}

// Handle drag and drop reordering
const onDragEnd = (event) => {
    // Update model.value to match the new order of selectedItems
    const newOrder = selectedItems.value.map(item => item.id)
    model.value = newOrder
}

// Handle input blur with proper timeout
const handleBlur = () => {
    setTimeout(() => {
        isOpen.value = false
    }, 200)
}
</script>

<template>
    <div class="relative">
        <!-- Selected items display -->
        <div v-if="selectedItems.length > 0" class="mb-3">
            <div class="bg-gray-50 rounded-lg border border-gray-200 p-3">
                <div class="flex items-center justify-between mb-2">
                    <span class="text-sm font-medium text-gray-700">
                        {{ __('daylight::general.selected_items') }} ({{ selectedItems.length }})
                    </span>
                    <div class="flex items-center gap-2">
                        <span class="text-xs text-gray-500">{{ __('daylight::general.drag_to_reorder') }}</span>
                        <button 
                            @click.prevent="clearSelection"
                            type="button"
                            class="text-xs text-red-500 hover:text-red-700"
                            :title="__('daylight::general.clear_all')"
                        >
                            {{ __('daylight::general.clear_all') }}
                        </button>
                    </div>
                </div>
                
                <VueDraggableNext 
                    v-model="selectedItems"
                    @end="onDragEnd"
                    class="flex flex-wrap gap-2"
                    :group="{ name: 'selected-items' }"
                    ghost-class="opacity-50"
                    chosen-class="ring-blue-500"
                >
                    <div 
                        v-for="(item, index) in selectedItems" 
                        :key="item.id"
                        class="group inline-flex items-center gap-2 px-3 py-2 bg-white border border-gray-200 text-gray-900 text-sm rounded-md shadow-sm hover:shadow-md transition-all cursor-move"
                    >
                        <svg class="w-3 h-3 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
                        </svg>
                        <div class="flex items-center gap-2">
                            <span class="text-xs text-gray-400 font-mono">#{{ item.id }}</span>
                            <span class="font-medium">{{ item.name }}</span>
                            <span class="text-xs text-gray-500 bg-gray-100 px-1.5 py-0.5 rounded">{{ item.type }}</span>
                        </div>
                        <button 
                            @click.prevent="removeItem(item.id)"
                            class="text-gray-400 hover:text-red-500 opacity-0 group-hover:opacity-100 transition-opacity"
                            type="button"
                            :title="__('daylight::general.remove_item')"
                        >
                            <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                                <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path>
                            </svg>
                        </button>
                    </div>
                </VueDraggableNext>
            </div>
        </div>

        <!-- Search input -->
        <div class="relative">
            <input
                v-model="searchQuery"
                @focus="isOpen = true"
                @blur="handleBlur"
                type="text"
                :placeholder="field.options?.placeholder || __('daylight::general.search_items')"
                class="block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
            />
            
            <!-- Loading indicator -->
            <div v-if="isLoading" class="absolute right-3 top-3">
                <svg class="animate-spin h-4 w-4 text-gray-400" fill="none" viewBox="0 0 24 24">
                    <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
                    <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                </svg>
            </div>
        </div>

        <!-- Search results dropdown -->
        <div 
            v-if="isOpen && (searchResults.length > 0 || searchQuery.length >= 2)"
            class="absolute z-10 mt-1 w-full bg-white border border-gray-300 rounded-md shadow-lg max-h-60 overflow-auto"
        >
            <div v-if="searchResults.length === 0 && searchQuery.length >= 2 && !isLoading" class="px-3 py-2 text-sm text-gray-500">
                {{ __('daylight::general.no_results_found') }}
            </div>
            
            <button
                v-for="item in searchResults"
                :key="item.id"
                @click.prevent="selectItem(item)"
                type="button"
                class="w-full text-left px-3 py-2 text-sm hover:bg-gray-100 focus:bg-gray-100 focus:outline-none"
            >
                <div class="font-medium">{{ item.name }}</div>
                <div class="text-xs text-gray-500">{{ item.type }} #{{ item.id }}</div>
            </button>
        </div>

        <!-- No hidden input needed - data flows through v-model to component data -->
    </div>
</template>