<template>
    <suspense>
        <component :is="Default || 'div'">
            <div class="container mx-auto mt-20">
                <!-- <UNavigationMenu orientation="vertical" :items="listing" class="data-[orientation=vertical]:w-48">
                    <template #item="{ item, active }">
                        <div class="flex items-center gap-2 px-3 py-2">
                            <UIcon name="i-heroicons-book-open" />
                            <span>{{ item.name }}</span>
                        </div>
                    </template>
</UNavigationMenu> -->
                <h1 class="text-2xl font-bold mb-6 text-gray-900 dark:text-white">Products</h1>
                <div v-if="loading" class="text-center py-8">
                    <span class="text-gray-600 dark:text-gray-400">Loading products...</span>
                </div>
                <div v-else-if="error" class="mb-4 p-3 bg-red-100 text-red-700 rounded">
                    {{ error }}
                </div>
                <div v-else class="overflow-x-auto">
                    <div class="flex gap-2">
                        <CategoryMenuListing />
                        <UTable :data="productsList" :columns="columns" class="flex-1">
                            <template #expanded="{ row }">
                                <UTable :data="productsList.slice(0, 3)" :columns="columnsChild" :ui="{
                                    thead: 'hidden'
                                }" />
                            </template>
                        </UTable>
                    </div>
                    <div class="flex justify-center items-center py-8">
                        <UPagination v-model:page="page" :total="total" :page-size="perPage" />
                    </div>
                    <div v-if="productsList.length === 0" class="text-center py-8 text-gray-500 dark:text-gray-400">
                        No products found
                    </div>
                </div>
            </div>
        </component>
    </suspense>
</template>

<script setup lang="ts">
import { ref, watch, h, resolveComponent, computed } from 'vue'
import { useFetchJson } from '@/composable/useFetchJson'
import Default from '@/layouts/default.vue'
import { useRoute, useRouter } from 'vue-router'
import type { TableColumn } from '@nuxt/ui'
import CategoryMenuListing from '../inner/categoryMenuListing.vue'

interface Product {
    reference: number
    product_id: number
    name: string
    image_link: string
    link_rewrite: string
}

const router = useRouter()
const route = useRoute()

const page = computed({
    get: () => Number(route.query.page) || 1,
    set: (val: number) => {
        router.push({
            query: {
                ...route.query,
                page: val
            }
        })
    }
})
const sortField = computed({
    get: () => [
        route.query.sort as string | undefined,
        route.query.direction as 'asc' | 'desc' | undefined
    ],

    set: ([sort]: [string, 'asc' | 'desc']) => {
        const currentSort = route.query.sort as string | undefined
        const currentDirection = route.query.direction as 'asc' | 'desc' | undefined

        let query = { ...route.query }

        if (currentSort === sort) {
            if (currentDirection === 'asc') {
                query.direction = 'desc'
            } else if (currentDirection === 'desc') {
                delete query.sort
                delete query.direction
            } else {
                query.direction = 'asc'
                query.sort = sort
            }
        } else {
            query.sort = sort
            query.direction = 'asc'
        }

        router.push({ query })
    }
})

const perPage = ref(15)
const total = ref(0)

interface ApiResponse {
    message: string
    items: Product[]
    count: number
}

const productsList = ref<Product[]>([])
const loading = ref(true)
const error = ref<string | null>(null)
const filters = computed<Record<string, string>>({
    get: () => {
        const q = { ...route.query }
        delete q.page
        delete q.sort
        delete q.direction
        return q as Record<string, string>
    },
    set: (val) => {
        const baseQuery = { ...route.query }

        Object.keys(baseQuery).forEach(key => {
            if (!['page', 'sort', 'direction'].includes(key)) {
                delete baseQuery[key]
            }
        })

        router.push({
            query: {
                ...baseQuery,
                ...val,
                page: 1
            }
        })
    }
})

function debounce(fn: Function, delay = 400) {
    let t: any
    return (...args: any[]) => {
        clearTimeout(t)
        t = setTimeout(() => fn(...args), delay)
    }
}

const updateFilter = debounce((columnId: string, val: string) => {
    const newFilters = { ...filters.value }

    if (val) newFilters[columnId] = val
    else delete newFilters[columnId]

    filters.value = newFilters
}, 400)

async function fetchProductList() {
    loading.value = true
    error.value = null

    const params = new URLSearchParams()

    Object.entries(route.query).forEach(([key, value]) => {
        if (value) params.append(key, String(value))
    })

    const url = `/api/v1/restricted/list-products/get-listing?${params}`

    try {
        const response = await useFetchJson<ApiResponse>(url)
        productsList.value = response.items || []
        total.value = response.count || 0
    } catch (e: unknown) {
        error.value = e instanceof Error ? e.message : 'Failed to load products'
    } finally {
        loading.value = false
    }
}

function goToProduct(productId: number) {
    router.push({
        name: 'product-detail',
        params: { id: productId }
    })
}

const selectedCount = ref({
    product_id: null,
    count: 0
})

function getIcon(name: string) {
    if (sortField.value[0] === name) {
        if (sortField.value[1] === 'asc') return 'i-lucide-arrow-up-narrow-wide'
        if (sortField.value[1] === 'desc') return 'i-lucide-arrow-down-wide-narrow'
    }
    return 'i-lucide-arrow-up-down'
}

const UInputNumber = resolveComponent('UInputNumber')
const UInput = resolveComponent('UInput')
const UButton = resolveComponent('UButton')
const UIcon = resolveComponent('UIcon')

const columns: TableColumn<Payment>[] = [
    {
        id: 'expand',
        cell: ({ row }) =>
            h(UButton, {
                color: 'neutral',
                variant: 'ghost',
                icon: 'i-lucide-chevron-down',
                square: true,
                'aria-label': 'Expand',
                ui: {
                    leadingIcon: [
                        'transition-transform',
                        row.getIsExpanded() ? 'duration-200 rotate-180' : ''
                    ]
                },
                onClick: () => row.toggleExpanded()
            })
    },
    {
        accessorKey: 'product_id',
        header: ({ column }) => {
            return h('div', { class: 'flex flex-col gap-1' }, [
                h('div', {
                    class: 'flex items-center gap-2 cursor-pointer',
                    onClick: () => {
                        sortField.value = ['product_id', 'asc']
                    }
                }, [
                    h('span', 'ID'),
                    h(UIcon, {
                        name: getIcon('product_id')
                    })
                ]),

                h(UInput, {
                    placeholder: 'Search...',
                    modelValue: filters.value[column.id] ?? '',
                    'onUpdate:modelValue': (val: string) => {
                        updateFilter(column.id, val)
                    },
                    size: 'xs'
                })
            ])
        },
        // header: '#',
        cell: ({ row }) => `#${row.getValue('product_id') as number}`
    },
    {
        accessorKey: 'image_link',
        header: 'Image',
        cell: ({ row }) => {
            return h('img', {
                src: row.getValue('image_link') as string,
                style: 'width:40px;height:40px;object-fit:cover;'
            })
        }
    },
    {
        accessorKey: 'name',
        header: ({ column }) => {
            return h('div', { class: 'flex flex-col gap-1' }, [
                h('div', {
                    class: 'flex items-center gap-2 cursor-pointer',
                    onClick: () => {
                        sortField.value = ['name', 'asc']
                    }
                }, [
                    h('span', 'Name'),
                    h(UIcon, {
                        name: getIcon('name')
                    })
                ]),

                h(UInput, {
                    placeholder: 'Search...',
                    modelValue: filters.value[column.id] ?? '',
                    'onUpdate:modelValue': (val: string) => {
                        updateFilter(column.id, val)
                    },
                    size: 'xs'
                })
            ])
        },
        cell: ({ row }) => row.getValue('name') as string,
        filterFn: (row, columnId, value) => {
            const name = row.getValue(columnId) as string
            return name.toLowerCase().includes(value.toLowerCase())
        }
    },
    {
        accessorKey: 'quantity',
        header: ({ column }) => {
            return h('div', { class: 'flex flex-col gap-1' }, [
                h('div', {
                    class: 'flex items-center gap-2 cursor-pointer',
                    onClick: () => {
                        sortField.value = ['quantity', 'asc']
                    }
                }, [
                    h('span', 'In stock'),
                    h(UIcon, {
                        name: getIcon('quantity')
                    })
                ]),
            ])
        },
        cell: ({ row }) => row.getValue('quantity') as number
    },
    {
        accessorKey: 'count',
        header: 'Count',
        cell: ({ row }) => {
            return h(UInputNumber, {
                modelValue: selectedCount.value.product_id === row.original.product_id ? selectedCount.value.count : 0,
                'onUpdate:modelValue': (val: number) => {
                    if (val)
                        selectedCount.value = {
                            product_id: row.original.product_id,
                            count: val
                        }
                    else {
                        selectedCount.value = {
                            product_id: null,
                            count: 0
                        }
                    }
                },
                min: 0,
                max: row.original.quantity
            })
        }
    },
    {
        accessorKey: 'count',
        header: '',
        cell: ({ row }) => {
            return h(UButton, {
                onClick: () => {
                    console.log('Clicked', row.original)
                },
                color: selectedCount.value.product_id !== row.original.product_id ? 'info' : 'primary',
                disabled: selectedCount.value.product_id !== row.original.product_id,
                variant: 'solid'
            }, 'Add to cart')
        },
    }
]

const columnsChild: TableColumn<Payment>[] = [
    {
        accessorKey: 'product_id',
        header: '',
        cell: ({ row }) => `#${row.getValue('product_id') as number}`
    },
    {
        accessorKey: 'image_link',
        header: '',
        cell: ({ row }) => {
            return h('img', {
                src: row.getValue('image_link') as string,
                style: 'width:40px;height:40px;object-fit:cover;'
            })
        }
    },
    {
        accessorKey: 'name',
        header: '',
        cell: ({ row }) => row.getValue('name') as string
    },
    {
        accessorKey: 'quantity',
        header: '',
        cell: ({ row }) => row.getValue('quantity') as number
    },
    {
        accessorKey: 'count',
        header: '',
        cell: ({ row }) => {
            return h(UInputNumber, {
                modelValue: selectedCount.value.product_id === row.original.product_id ? selectedCount.value.count : 0,
                'onUpdate:modelValue': (val: number) => {
                    if (val)
                        selectedCount.value = {
                            product_id: row.original.product_id,
                            count: val
                        }
                    else {
                        selectedCount.value = {
                            product_id: null,
                            count: 0
                        }
                    }
                },
                min: 0,
                max: row.original.quantity
            })
        }
    },
    {
        accessorKey: 'count',
        header: '',
        cell: ({ row }) => {
            return h(UButton, {
                onClick: () => {
                    console.log('Clicked', row.original)
                },
                color: selectedCount.value.product_id !== row.original.product_id ? 'info' : 'primary',
                disabled: selectedCount.value.product_id !== row.original.product_id,
                variant: 'solid'
            }, 'Add to cart')
        },
    }
]

watch(
    () => route.query,
    () => {
        fetchProductList()
    },
    { immediate: true }
)
</script>