<template>
    <div class="smart-shopping-list">
        <!-- List Header with Smart Actions -->
        <div class="list-header">
            <div class="header-info">
                <h2 class="list-title">{{ list.name }}</h2>
                <div class="list-stats">
                    <span class="item-count">{{ incompletedItems.length }} items</span>
                    <span v-if="claimedByOthersCount > 0" class="claimed-indicator">
                        {{ claimedByOthersCount }} claimed by others
                    </span>
                </div>
            </div>

            <!-- Quick Actions -->
            <div class="header-actions">
                <Button v-if="hasCompletedItemsWithoutPrices" variant="soft" size="sm" @click="showReceiptScanner"
                    class="receipt-scanner-btn">
                    <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M3 9a2 2 0 012-2h.93a2 2 0 001.664-.89l.812-1.22A2 2 0 0110.07 4h3.86a2 2 0 011.664.89l.812 1.22A2 2 0 0018.07 7H19a2 2 0 012 2v9a2 2 0 01-2 2H5a2 2 0 01-2-2V9z" />
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M15 13a3 3 0 11-6 0 3 3 0 016 0z" />
                    </svg>
                    Scan Receipt
                </Button>

                <Button v-if="canCreateExpense" variant="primary" size="sm" @click="showExpensePrompt"
                    class="create-expense-btn">
                    <svg class="w-4 h-4 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                    </svg>
                    Create Expense
                </Button>
            </div>
        </div>

        <!-- Conflict Alerts -->
        <TransitionGroup name="alert" tag="div" class="space-y-3 mb-4">
            <Alert v-for="conflict in activeConflicts" :key="conflict.id" type="warning" :message="conflict.message"
                class="conflict-alert" @dismiss="dismissConflict(conflict.id)" />
        </TransitionGroup>

        <!-- Smart Shopping Items -->
        <div class="shopping-items">
            <!-- Unclaimed Items -->
            <div v-if="unclaimedItems.length > 0" class="item-group">
                <h3 class="group-title">
                    <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
                    </svg>
                    Available to Shop ({{ unclaimedItems.length }})
                </h3>
                <div class="items-list">
                    <SmartShoppingItem v-for="item in unclaimedItems" :key="item.id" :item="item" :list="list"
                        :is-online="isOnline" @claim="handleClaimItem" @complete="handleCompleteItem"
                        @update-price="handleUpdatePrice" @edit="$emit('edit-item', item)" />
                </div>
            </div>

            <!-- My Claimed Items -->
            <div v-if="myClaimedItems.length > 0" class="item-group">
                <h3 class="group-title claimed-by-me">
                    <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
                    </svg>
                    My Items ({{ myClaimedItems.length }})
                </h3>
                <div class="items-list">
                    <SmartShoppingItem v-for="item in myClaimedItems" :key="item.id" :item="item" :list="list"
                        :is-online="isOnline" :is-claimed-by-me="true" @unclaim="handleUnclaimItem"
                        @complete="handleCompleteItem" @update-price="handleUpdatePrice"
                        @edit="$emit('edit-item', item)" />
                </div>
            </div>

            <!-- Others' Claimed Items -->
            <div v-if="othersClaimedItems.length > 0" class="item-group">
                <h3 class="group-title claimed-by-others">
                    <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M12 4.354a4 4 0 110 5.292M15 21H3v-1a6 6 0 0112 0v1zm0 0h6v-1a6 6 0 00-9-5.197m13.5-9a2.25 2.25 0 11-4.5 0 2.25 2.25 0 014.5 0z" />
                    </svg>
                    Claimed by Others ({{ othersClaimedItems.length }})
                </h3>
                <div class="items-list">
                    <SmartShoppingItem v-for="item in othersClaimedItems" :key="item.id" :item="item" :list="list"
                        :is-online="isOnline" :is-claimed-by-others="true" @edit="$emit('edit-item', item)" readonly />
                </div>
            </div>

            <!-- Completed Items -->
            <div v-if="completedItems.length > 0" class="item-group">
                <h3 class="group-title completed">
                    <svg class="w-5 h-5 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                        <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                            d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z" />
                    </svg>
                    Completed ({{ completedItems.length }})
                </h3>
                <div class="items-list completed-items">
                    <SmartShoppingItem v-for="item in completedItems" :key="item.id" :item="item" :list="list"
                        :is-online="isOnline" :is-completed="true" @update-price="handleUpdatePrice"
                        @edit="$emit('edit-item', item)" />
                </div>
            </div>
        </div>

        <!-- Undo Toast -->
        <Transition name="undo-toast">
            <div v-if="undoAction" class="undo-toast">
                <div class="undo-content">
                    <span class="undo-message">{{ undoAction.message }}</span>
                </div>
                <Button variant="ghost" size="sm" @click="performUndo" class="undo-button">
                    Undo
                </Button>
            </div>
        </Transition>

        <!-- Receipt Scanner Modal -->
        <Dialog v-model="showReceiptScanner" title="Scan Receipt">
            <div class="receipt-scanner">
                <div class="scanner-area">
                    <input ref="fileInput" type="file" accept="image/*" capture="environment"
                        @change="handleReceiptUpload" class="hidden" />
                    <Button @click="triggerFileUpload" variant="outline" class="upload-btn">
                        <svg class="w-6 h-6 mr-2" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
                                d="M12 6v6m0 0v6m0-6h6m-6 0H6" />
                        </svg>
                        Choose Receipt Image
                    </Button>
                </div>

                <div v-if="scanningReceipt" class="scanning-status">
                    <Spinner size="sm" />
                    <span>Scanning receipt...</span>
                </div>

                <div v-if="scannedData" class="scanned-results">
                    <h4 class="results-title">Detected Items & Prices:</h4>
                    <div class="detected-items">
                        <div v-for="(detectedItem, index) in scannedData.items" :key="index" class="detected-item">
                            <span class="item-name">{{ detectedItem.name }}</span>
                            <span class="item-price">${{ detectedItem.price.toFixed(2) }}</span>
                            <Button size="sm" variant="outline" @click="applyScannedPrice(detectedItem)">
                                Apply
                            </Button>
                        </div>
                    </div>
                </div>
            </div>
        </Dialog>

        <!-- Expense Creation Prompt -->
        <Dialog v-model="showExpensePrompt" title="Create Expense from Shopping">
            <div class="expense-prompt">
                <p class="prompt-message">
                    You have {{ completedItemsWithPrices.length }} completed items with prices totaling
                    <strong>${{ totalCompletedValue.toFixed(2) }}</strong>.
                    Would you like to create an expense for this shopping trip?
                </p>

                <div class="expense-options">
                    <div class="option-card" @click="createExpenseType = 'equal'">
                        <input type="radio" id="equal-split" v-model="createExpenseType" value="equal"
                            class="sr-only" />
                        <label for="equal-split" class="option-label">
                            <h4>Equal Split</h4>
                            <p>Split total amount equally among all group members</p>
                        </label>
                    </div>

                    <div class="option-card" @click="createExpenseType = 'item-based'">
                        <input type="radio" id="item-split" v-model="createExpenseType" value="item-based"
                            class="sr-only" />
                        <label for="item-split" class="option-label">
                            <h4>Item-Based Split</h4>
                            <p>Each person pays for items they added to the list</p>
                        </label>
                    </div>
                </div>

                <div class="prompt-actions">
                    <Button variant="outline" @click="showExpensePrompt = false">
                        Not Now
                    </Button>
                    <Button variant="primary" @click="createExpenseFromShopping">
                        Create Expense
                    </Button>
                </div>
            </div>
        </Dialog>
    </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted, watch } from 'vue'
import type { PropType } from 'vue'
import { useListsStore } from '@/stores/listsStore'
import { useAuthStore } from '@/stores/auth'
import { useNotificationStore } from '@/stores/notifications'
import type { Item } from '@/types/item'
import type { List } from '@/types/list'

// UI Components
import { Button, Alert, Dialog, Spinner } from '@/components/ui'
import SmartShoppingItem from './SmartShoppingItem.vue'

interface UndoAction {
    id: string
    type: 'claim' | 'unclaim' | 'complete' | 'price-update'
    message: string
    originalState: any
    item: Item
    timeRemaining: number
}

interface Conflict {
    id: string
    message: string
    type: 'simultaneous-claim' | 'concurrent-edit' | 'price-conflict'
}

const props = defineProps({
    list: {
        type: Object as PropType<List>,
        required: true
    },
    items: {
        type: Array as PropType<Item[]>,
        required: true
    },
    isOnline: {
        type: Boolean,
        default: true
    }
})

const emit = defineEmits([
    'edit-item',
    'create-expense'
])

// Stores
const listsStore = useListsStore()
const authStore = useAuthStore()
const notificationStore = useNotificationStore()

// Reactive state
const undoAction = ref<UndoAction | null>(null)
const undoProgress = ref(100)
const activeConflicts = ref<Conflict[]>([])
const showReceiptScanner = ref(false)
const showExpensePrompt = ref(false)
const scanningReceipt = ref(false)
const scannedData = ref(null)
const createExpenseType = ref<'equal' | 'item-based'>('equal')
const fileInput = ref<HTMLInputElement>()

// Computed properties for intelligent item grouping
const currentUser = computed(() => authStore.user)

const incompletedItems = computed(() =>
    props.items.filter(item => !item.is_complete)
)

const completedItems = computed(() =>
    props.items.filter(item => item.is_complete)
)

const unclaimedItems = computed(() =>
    incompletedItems.value.filter(item => !item.claimed_by_user_id)
)

const myClaimedItems = computed(() =>
    incompletedItems.value.filter(item =>
        item.claimed_by_user_id === currentUser.value?.id
    )
)

const othersClaimedItems = computed(() =>
    incompletedItems.value.filter(item =>
        item.claimed_by_user_id && item.claimed_by_user_id !== currentUser.value?.id
    )
)

const claimedByOthersCount = computed(() => othersClaimedItems.value.length)

const completedItemsWithPrices = computed(() =>
    completedItems.value.filter(item => {
        const price = typeof item.price === 'string' ? parseFloat(item.price) : (item.price || 0)
        return price > 0
    })
)

const hasCompletedItemsWithoutPrices = computed(() =>
    completedItems.value.some(item => {
        const price = typeof item.price === 'string' ? parseFloat(item.price) : (item.price || 0)
        return price <= 0
    })
)

const canCreateExpense = computed(() =>
    completedItemsWithPrices.value.length > 0 && props.list.group_id
)

const totalCompletedValue = computed(() =>
    completedItemsWithPrices.value.reduce((sum, item) => {
        const price = typeof item.price === 'string' ? parseFloat(item.price) : (item.price || 0)
        return sum + price
    }, 0)
)

// Item action handlers with optimistic updates and undo functionality
const handleClaimItem = async (item: Item) => {
    if (!props.isOnline) {
        notificationStore.addNotification({
            type: 'error',
            message: 'Cannot claim items while offline'
        })
        return
    }

    // Check for simultaneous claims
    if (item.claimed_by_user_id) {
        addConflict({
            id: `claim-conflict-${item.id}`,
            type: 'simultaneous-claim',
            message: `"${item.name}" was just claimed by ${item.claimed_by_user?.name}. Refresh to see latest state.`
        })
        return
    }

    const originalState = { ...item }

    // Optimistic update
    item.claimed_by_user_id = currentUser.value?.id ? Number(currentUser.value.id) : null
    item.claimed_by_user = currentUser.value || null
    item.claimed_at = new Date().toISOString()

    try {
        await listsStore.claimItem(item.id)

        // Add undo action
        addUndoAction({
            id: `claim-${item.id}`,
            type: 'claim',
            message: `Claimed "${item.name}"`,
            originalState,
            item,
            timeRemaining: 10000
        })

        // Haptic feedback
        if ('vibrate' in navigator) {
            navigator.vibrate(50)
        }

    } catch (error) {
        // Rollback optimistic update
        Object.assign(item, originalState)
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to claim item. Please try again.'
        })
    }
}

const handleUnclaimItem = async (item: Item) => {
    const originalState = { ...item }

    // Optimistic update
    item.claimed_by_user_id = null
    item.claimed_by_user = null
    item.claimed_at = null

    try {
        await listsStore.unclaimItem(item.id)

        addUndoAction({
            id: `unclaim-${item.id}`,
            type: 'unclaim',
            message: `Unclaimed "${item.name}"`,
            originalState,
            item,
            timeRemaining: 10000
        })

    } catch (error) {
        Object.assign(item, originalState)
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to unclaim item. Please try again.'
        })
    }
}

const handleCompleteItem = async (item: Item, completed: boolean) => {
    const originalState = { ...item }

    // Optimistic update
    item.is_complete = completed

    try {
        // Call the actual API through the store
        await listsStore.updateItem(item.id, { is_complete: completed })

        if (completed) {
            addUndoAction({
                id: `complete-${item.id}`,
                type: 'complete',
                message: `Completed "${item.name}"`,
                originalState,
                item,
                timeRemaining: 10000
            })

            // Celebration feedback
            if ('vibrate' in navigator) {
                navigator.vibrate([100, 50, 100])
            }
        }

    } catch (error) {
        Object.assign(item, originalState)
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to update item. Please try again.'
        })
    }
}

const handleUpdatePrice = async (item: Item, price: number) => {
    const originalState = { ...item }

    // Optimistic update
    item.price = price

    try {
        await listsStore.updateItem(item.id, { price })

        addUndoAction({
            id: `price-${item.id}`,
            type: 'price-update',
            message: `Updated price for "${item.name}" to $${price.toFixed(2)}`,
            originalState,
            item,
            timeRemaining: 10000
        })

    } catch (error) {
        Object.assign(item, originalState)
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to update price. Please try again.'
        })
    }
}

// Undo system
const addUndoAction = (action: UndoAction) => {
    // Clear any existing undo action
    if (undoAction.value) {
        clearUndoTimer()
    }

    undoAction.value = action
    undoProgress.value = 100

    // Start countdown timer
    const startTime = Date.now()
    const timer = setInterval(() => {
        const elapsed = Date.now() - startTime
        const remaining = Math.max(0, action.timeRemaining - elapsed)
        undoProgress.value = (remaining / action.timeRemaining) * 100

        if (remaining <= 0) {
            clearInterval(timer)
            undoAction.value = null
        }
    }, 50)

    // Auto-clear after timeout
    setTimeout(() => {
        if (undoAction.value?.id === action.id) {
            undoAction.value = null
        }
    }, action.timeRemaining)
}

const performUndo = async () => {
    if (!undoAction.value) return

    const action = undoAction.value
    undoAction.value = null

    try {
        // Restore original state
        Object.assign(action.item, action.originalState)

        // Make the API call to revert
        switch (action.type) {
            case 'claim':
                await listsStore.unclaimItem(action.item.id)
                break
            case 'unclaim':
                await listsStore.claimItem(action.item.id)
                break
            case 'complete':
                await listsStore.updateItem(action.item.id, { is_complete: action.originalState.is_complete })
                break
            case 'price-update':
                await listsStore.updateItem(action.item.id, { price: action.originalState.price })
                break
        }

        notificationStore.addNotification({
            type: 'success',
            message: 'Action undone successfully'
        })

    } catch (error) {
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to undo action. Please try again.'
        })
    }
}

const clearUndoTimer = () => {
    undoAction.value = null
}

// Conflict management
const addConflict = (conflict: Conflict) => {
    activeConflicts.value.push(conflict)

    // Auto-dismiss after 10 seconds
    setTimeout(() => {
        dismissConflict(conflict.id)
    }, 10000)
}

const dismissConflict = (conflictId: string) => {
    activeConflicts.value = activeConflicts.value.filter(c => c.id !== conflictId)
}

// Receipt scanning
const openReceiptScanner = () => {
    showReceiptScanner.value = true
}

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

const handleReceiptUpload = async (event: Event) => {
    const target = event.target as HTMLInputElement
    const file = target.files?.[0]

    if (!file) return

    scanningReceipt.value = true

    try {
        // This would integrate with Tesseract.js or a backend OCR service
        // For now, we'll simulate the scanning process
        await new Promise(resolve => setTimeout(resolve, 2000))

        // Mock scanned data - in reality this would come from OCR
        scannedData.value = {
            items: [
                { name: 'Milk', price: 4.99 },
                { name: 'Bread', price: 3.50 },
                { name: 'Eggs', price: 6.99 }
            ]
        } as any

    } catch (error) {
        notificationStore.addNotification({
            type: 'error',
            message: 'Failed to scan receipt. Please try again.'
        })
    } finally {
        scanningReceipt.value = false
    }
}

const applyScannedPrice = (detectedItem: any) => {
    // Find matching item in the list and apply the price
    const matchingItem = completedItems.value.find(item =>
        item.name.toLowerCase().includes(detectedItem.name.toLowerCase()) ||
        detectedItem.name.toLowerCase().includes(item.name.toLowerCase())
    )

    if (matchingItem) {
        handleUpdatePrice(matchingItem, detectedItem.price)
        notificationStore.addNotification({
            type: 'success',
            message: `Applied $${detectedItem.price.toFixed(2)} to "${matchingItem.name}"`
        })
    }
}

// Expense creation
const promptExpenseCreation = () => {
    showExpensePrompt.value = true
}

const createExpenseFromShopping = () => {
    emit('create-expense', {
        type: createExpenseType.value,
        items: completedItemsWithPrices.value,
        total: totalCompletedValue.value
    })

    showExpensePrompt.value = false

    notificationStore.addNotification({
        type: 'success',
        message: 'Expense creation initiated'
    })
}

// Lifecycle
onMounted(() => {
    // Connect to WebSocket for real-time updates if online
    if (props.isOnline && props.list.id) {
        listsStore.connectWebSocket(props.list.id, authStore.token)
    }
})

onUnmounted(() => {
    listsStore.disconnectWebSocket()
    clearUndoTimer()
})

// Watch for online status changes
watch(() => props.isOnline, (isOnline) => {
    if (isOnline && props.list.id) {
        listsStore.connectWebSocket(props.list.id, authStore.token)
    } else {
        listsStore.disconnectWebSocket()
    }
})
</script>

<style scoped>
.smart-shopping-list {
    @apply max-w-4xl mx-auto space-y-6;
}

.list-header {
    @apply flex items-start justify-between p-4 bg-white rounded-lg shadow-soft border border-neutral-200;
}

.header-info {
    @apply flex-1;
}

.list-title {
    @apply text-xl font-semibold text-neutral-900 mb-1;
}

.list-stats {
    @apply flex items-center space-x-4 text-sm text-neutral-600;
}

.claimed-indicator {
    @apply px-2 py-1 bg-amber-100 text-amber-800 rounded-full text-xs font-medium;
}

.header-actions {
    @apply flex items-center space-x-3;
}

.item-group {
    @apply bg-white rounded-lg shadow-soft border border-neutral-200 overflow-hidden;
}

.group-title {
    @apply flex items-center px-4 py-3 bg-neutral-50 border-b border-neutral-200 font-medium text-neutral-900;
}

.group-title.claimed-by-me {
    @apply bg-blue-50 text-blue-900;
}

.group-title.claimed-by-others {
    @apply bg-amber-50 text-amber-900;
}

.group-title.completed {
    @apply bg-green-50 text-green-900;
}

.items-list {
    @apply divide-y divide-neutral-200;
}

.completed-items {
    @apply opacity-75;
}

.conflict-alert {
    @apply border-l-4 border-l-amber-500;
}

.undo-toast {
    @apply fixed bottom-4 right-4 z-50 bg-neutral-900 text-white rounded-lg shadow-floating p-4 min-w-80;
    @apply flex items-center justify-between;
}

.undo-content {
    @apply flex-1 relative;
}

.undo-message {
    @apply text-sm font-medium;
}

.undo-progress {
    @apply absolute bottom-0 left-0 h-0.5 bg-blue-500 transition-all duration-50 ease-linear;
}

.undo-button {
    @apply ml-4 text-blue-400 hover:text-blue-300;
}

.receipt-scanner {
    @apply space-y-6;
}

.scanner-area {
    @apply flex flex-col items-center justify-center p-8 border-2 border-dashed border-neutral-300 rounded-lg;
}

.scanning-status {
    @apply flex items-center justify-center space-x-3 p-4 bg-blue-50 rounded-lg;
}

.scanned-results {
    @apply space-y-4;
}

.results-title {
    @apply font-semibold text-neutral-900;
}

.detected-items {
    @apply space-y-2;
}

.detected-item {
    @apply flex items-center justify-between p-3 bg-neutral-50 rounded-lg;
}

.item-name {
    @apply font-medium text-neutral-900;
}

.item-price {
    @apply text-green-600 font-mono;
}

.expense-prompt {
    @apply space-y-6;
}

.prompt-message {
    @apply text-neutral-700 leading-relaxed;
}

.expense-options {
    @apply space-y-3;
}

.option-card {
    @apply border border-neutral-200 rounded-lg p-4 cursor-pointer transition-all duration-200;
    @apply hover:border-blue-300 hover:bg-blue-50;
}

.option-card:has(input:checked) {
    @apply border-blue-500 bg-blue-50;
}

.option-label {
    @apply cursor-pointer;
}

.option-label h4 {
    @apply font-semibold text-neutral-900 mb-1;
}

.option-label p {
    @apply text-sm text-neutral-600;
}

.prompt-actions {
    @apply flex justify-end space-x-3;
}

/* Transitions */
.alert-enter-active,
.alert-leave-active {
    @apply transition-all duration-300 ease-out;
}

.alert-enter-from,
.alert-leave-to {
    @apply opacity-0 transform translate-y-2;
}

.undo-toast-enter-active,
.undo-toast-leave-active {
    @apply transition-all duration-300 ease-out;
}

.undo-toast-enter-from,
.undo-toast-leave-to {
    @apply opacity-0 transform translate-x-full;
}
</style>