<template>
    <div class="space-y-6">
        <div v-for="group in groupedItems" :key="group.categoryName" class="category-group"
            :class="{ 'highlight': supermarktMode && group.items.some(i => i.is_complete) }">
            <h3 v-if="group.items.length" class="text-lg font-semibold mb-2 px-1">{{ group.categoryName }}</h3>
            <draggable :list="group.items" item-key="id" handle=".drag-handle" @end="handleDragEnd"
                :disabled="!isOnline || supermarktMode" class="space-y-1" ghost-class="opacity-50"
                drag-class="shadow-lg">
                <template #item="{ element: item }">
                    <ListItem :item="item" :is-online="isOnline" :category-options="categoryOptions"
                        :supermarkt-mode="supermarktMode" @delete-item="$emit('delete-item', item)"
                        @checkbox-change="(item, checked) => $emit('checkbox-change', item, checked)"
                        @update-price="$emit('update-price', item)" @start-edit="$emit('start-edit', item)"
                        @save-edit="$emit('save-edit', item)" @cancel-edit="$emit('cancel-edit', item)"
                        @update-quantity="(item, qty) => $emit('update-quantity', item, qty)"
                        @mark-bought="handleMarkBought" @update:editName="item.editName = $event"
                        @update:editQuantity="item.editQuantity = $event"
                        @update:editCategoryId="item.editCategoryId = $event"
                        @update:priceInput="item.priceInput = $event" :list="list" />
                </template>
            </draggable>
        </div>

        <!-- New Add Item Form, integrated into the list with sticky positioning -->
        <div v-show="!supermarktMode" class="sticky bottom-0 bg-white border-t border-gray-200 p-4 shadow-lg z-30">
            <div class="flex items-center gap-2">
                <div class="flex-shrink-0 text-neutral-400">
                    <BaseIcon name="heroicons:plus-20-solid" class="w-5 h-5" />
                </div>
                <form @submit.prevent="$emit('add-item')" class="flex-grow flex items-center gap-2">
                    <Input type="text" class="flex-grow"
                        :placeholder="t('listDetailPage.items.addItemForm.placeholder', 'Add a new item...')"
                        ref="itemNameInputRef" :model-value="newItem.name"
                        @update:modelValue="$emit('update:newItemName', $event)" @blur="handleNewItemBlur" />
                    <div class="w-40 relative">
                        <select v-if="!showAddCategoryInput" :value="newItem.category_id || ''"
                            @change="handleCategoryChange"
                            class="w-full px-3 py-2 border border-gray-300 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
                            <option value="">{{ t('listDetailPage.noCategory', 'No Category') }}</option>
                            <option v-for="option in categoryOptions" :key="option.value || 'null'"
                                :value="option.value || ''">
                                {{ option.label }}
                            </option>
                            <option value="__ADD_NEW__">{{ t('listDetailPage.addNewCategory', '+ Add New Category') }}
                            </option>
                        </select>

                        <!-- Add new category input -->
                        <div v-if="showAddCategoryInput" class="flex gap-1">
                            <Input ref="newCategoryInputRef" v-model="newCategoryName" type="text"
                                placeholder="Category name..." class="flex-1 text-xs" size="sm"
                                @keyup.enter="createNewCategory" @keyup.escape="cancelAddCategory" />
                            <Button type="button" size="xs" @click="createNewCategory"
                                :disabled="!newCategoryName.trim()">✓</Button>
                            <Button type="button" size="xs" variant="ghost" @click="cancelAddCategory">✕</Button>
                        </div>
                    </div>
                    <Button type="submit" size="sm" :disabled="!newItem.name.trim()">{{ t('listDetailPage.buttons.add',
                        'Add')
                    }}</Button>
                </form>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, defineProps, defineEmits, onMounted, watch, nextTick } from 'vue';
import type { PropType } from 'vue';
import draggable from 'vuedraggable';
import { useI18n } from 'vue-i18n';
import ListItem from './ListItem.vue';
import type { Item } from '@/types/item';
import type { List } from '@/types/list';
import { useItemHelpers, type Category } from '@/composables/useItemHelpers';

// New component imports
import { Listbox } from '@headlessui/vue'; // This might not be needed if we make a full wrapper
import Button from '@/components/ui/Button.vue';
import Input from '@/components/ui/Input.vue';
import BaseIcon from '@/components/BaseIcon.vue';
import PurchaseConfirmationDialog from './PurchaseConfirmationDialog.vue'
import { useOptimisticUpdates } from '@/composables/useOptimisticUpdates'
import { useSocket } from '@/composables/useSocket'
import { enqueue } from '@/utils/offlineQueue'

interface ItemWithUI extends Item {
    updating: boolean;
    deleting: boolean;
    priceInput: string | number | null;
    swiped: boolean;
    isEditing?: boolean;
    editName?: string;
    editQuantity?: number | string | null;
    editCategoryId?: number | null;
    showFirework?: boolean;
    group_id?: number;
}

const props = defineProps({
    list: {
        type: Object as PropType<List>,
        required: true,
    },
    items: {
        type: Array as PropType<Item[]>,
        required: true,
    },
    isOnline: {
        type: Boolean,
        required: true,
    },
    supermarktMode: {
        type: Boolean,
        default: false,
    },
    categoryOptions: {
        type: Array as PropType<{ label: string; value: number | null }[]>,
        required: true,
    },
    newItem: {
        type: Object as PropType<{ name: string; category_id?: number | null }>,
        required: true,
    },
    categories: {
        type: Array as PropType<{ id: number; name: string }[]>,
        required: true,
    }
});

const emit = defineEmits([
    'delete-item',
    'checkbox-change',
    'update-price',
    'start-edit',
    'save-edit',
    'cancel-edit',
    'add-item',
    'handle-drag-end',
    'reorder-items',
    'update:newItemName',
    'update:newItemCategoryId',
    'update-quantity',
    'mark-bought',
    'create-category',
]);

const { t } = useI18n();
const { groupItemsByCategory } = useItemHelpers();
const itemNameInputRef = ref<HTMLInputElement | null>(null);
const showAddCategoryInput = ref(false);
const newCategoryName = ref('');
const newCategoryInputRef = ref<HTMLInputElement | null>(null);

const safeCategoryOptions = computed(() => props.categoryOptions.map(opt => ({
    ...opt,
    value: opt.value === null ? '' : opt.value
})));

// Optimistic updates wrapper so UI responds instantly
const itemsWithUI = computed(() =>
    props.items.map(item => ({
        ...item,
        updating: false,
        deleting: false,
        priceInput: item.price ?? null,
        swiped: false,
        isEditing: false,
        editName: item.name,
        editQuantity: item.quantity ?? null,
        editCategoryId: item.category_id,
        showFirework: false
    }))
)

const { data: optimisticItems, mutate: optimisticMutate } = useOptimisticUpdates<ItemWithUI>(itemsWithUI.value)

// Watch for props changes and update optimistic items
watch(() => props.items, (newItems) => {
    const updatedItemsWithUI = newItems.map(item => ({
        ...item,
        updating: false,
        deleting: false,
        priceInput: item.price ?? null,
        swiped: false,
        isEditing: false,
        editName: item.name,
        editQuantity: item.quantity ?? null,
        editCategoryId: item.category_id,
        showFirework: false
    }))
    optimisticMutate(() => updatedItemsWithUI)
}, { deep: true })

const groupedItems = computed(() => {
    return groupItemsByCategory(
        optimisticItems.value,
        props.categories,
        t('listDetailPage.items.noCategory', 'Uncategorized')
    );
});

const handleDragEnd = (evt: any) => {
    // Build new ordered array of all item IDs based on current DOM order
    const orderedIds: number[] = [];

    for (const group of groupedItems.value) {
        for (const item of group.items) {
            if (typeof item.id === 'number') {
                orderedIds.push(item.id);
            }
        }
    }

    // Emit reorder event with the complete ordered list
    emit('reorder-items', orderedIds);
};

const handleNewItemBlur = (event: FocusEvent) => {
    const inputElement = event.target as HTMLInputElement;
    if (inputElement.value.trim()) {
        emit('add-item');
    }
};

const focusNewItemInput = () => {
    itemNameInputRef.value?.focus();
}

defineExpose({
    focusNewItemInput
});

// === Real-time sync ===
const { on: onSocket, emit: wsEmit } = useSocket()

onMounted(() => {
    onSocket('lists:item:update', (payload: any) => {
        // Basic handler: update local optimistic list when other user updates.
        if (!payload?.id) return
        optimisticMutate((draft) => draft.map((i) => (i.id === payload.id ? { ...i, ...payload } : i)))
    })
})

function handleMarkBought(item: ItemWithUI) {
    // Optimistic update local state
    optimisticMutate((draft) => draft.map((i) => (i.id === item.id ? { ...i, is_complete: true } : i)))
    wsEmit('lists:item:update', { id: item.id, action: 'bought' })

    if (!props.isOnline) {
        enqueue({ type: 'item-bought', payload: { id: item.id } })
    }
}

function handleCategoryChange(event: Event) {
    const target = event.target as HTMLSelectElement;
    const value = target.value;

    if (value === '__ADD_NEW__') {
        showAddCategoryInput.value = true;
        newCategoryName.value = '';
        nextTick(() => {
            newCategoryInputRef.value?.focus();
        });
        return;
    }

    emit('update:newItemCategoryId', value ? Number(value) : null);
}

const createNewCategory = async () => {
    if (!newCategoryName.value.trim()) return;

    try {
        // This would need to be implemented in the parent component
        // For now, just emit an event
        emit('create-category', {
            name: newCategoryName.value.trim(),
            group_id: props.list.group_id
        });

        // Reset state
        showAddCategoryInput.value = false;
        newCategoryName.value = '';
    } catch (error) {
        console.error('Failed to create category:', error);
    }
};

const cancelAddCategory = () => {
    showAddCategoryInput.value = false;
    newCategoryName.value = '';
};

</script>

<style scoped>
/* All styles removed as they are now handled by Tailwind utility classes */
</style>