<template>
    <div>
        <PageHeader>
            {{ t('admin.categories.title') }}
            <template #actions>
                <MalioButton
                    v-if="canManage"
                    :label="t('admin.categories.newCategory')"
                    icon-name="mdi:add-bold"
                    icon-position="left"
                    @click="openCreateDrawer"
                />
            </template>
        </PageHeader>

        <!-- Table des categories. Tri serveur (name ASC, RG-1.10) +
             pagination serveur via usePaginatedList (#73). Le composable
             remplace l'ancien chargement « tout en un coup » a volumetrie
             cible ≤ 300 — la pagination est desormais alignee sur la regle
             projet (toute collection paginee, regle ABSOLUE n°13). -->
        <MalioDataTable
            :columns="columns"
            :items="categoryItems"
            :total-items="totalItems"
            :page="currentPage"
            :per-page="itemsPerPage"
            :per-page-options="itemsPerPageOptions"
            :row-clickable="true"
            :empty-message="t('admin.categories.noCategories')"
            @row-click="onRowClick"
            @update:page="goToPage"
            @update:per-page="setItemsPerPage"
        />

        <!-- Drawer creation / consultation / edition. -->
        <CategoryDrawer
            v-model="drawerOpen"
            :category="selectedCategory"
            @saved="onCategorySaved"
            @delete="onDeleteRequest"
        />

        <!-- Modale de confirmation suppression (soft delete cote serveur). -->
        <CategoryDeleteModal
            v-model="deleteModalOpen"
            :category-name="categoryToDelete?.name ?? ''"
            :loading="deleting"
            @confirm="handleDelete"
        />
    </div>
</template>

<script setup lang="ts">
import type { Category } from '~/modules/catalog/types/category'

const { t } = useI18n()
const { can } = usePermissions()
const { fetchTypes } = useCategoriesAdmin()
const { submitDelete } = useCategoryForm()

useHead({ title: t('admin.categories.title') })

const canManage = computed(() => can('catalog.categories.manage'))

// Pagination serveur via le composable partage (#73). Le CategoryProvider
// applique deja name ASC (RG-1.10) — pas besoin de defaultSort cote front
// tant qu'aucun OrderFilter n'est expose.
const {
    items: categories,
    totalItems,
    currentPage,
    itemsPerPage,
    itemsPerPageOptions,
    fetch: fetchCategories,
    goToPage,
    setItemsPerPage,
} = usePaginatedList<Category>({ url: '/categories' })

const drawerOpen = ref(false)
const selectedCategory = ref<Category | null>(null)
const deleteModalOpen = ref(false)
const categoryToDelete = ref<Category | null>(null)
const deleting = ref(false)

// Colonnes du datatable. Le type est embarque cote API (cf. spec-back § 3.4) —
// on aplatit en label lisible pour l'affichage.
const columns = [
    { key: 'name', label: t('admin.categories.table.name') },
    { key: 'typeLabel', label: t('admin.categories.table.type') },
]

const categoryItems = computed(() =>
    categories.value.map(cat => ({
        id: cat.id,
        name: cat.name,
        typeLabel: cat.categoryType?.label ?? '',
    })),
)

function getCategoryById(id: number): Category | undefined {
    return categories.value.find(c => c.id === id)
}

function onRowClick(item: Record<string, unknown>) {
    const category = getCategoryById(item.id as number)
    if (category) openEditDrawer(category)
}

function openCreateDrawer() {
    selectedCategory.value = null
    drawerOpen.value = true
}

function openEditDrawer(category: Category) {
    selectedCategory.value = category
    drawerOpen.value = true
}

function onDeleteRequest() {
    if (!selectedCategory.value) return
    categoryToDelete.value = selectedCategory.value
    deleteModalOpen.value = true
}

/**
 * Soft delete via le composable de form (qui gere toast + erreur). Refresh
 * de la liste a la fin pour retirer la ligne. L'index unique partiel
 * autorise une recreation ulterieure avec le meme couple (name, type) —
 * RG-1.07.
 */
async function handleDelete(): Promise<void> {
    if (!categoryToDelete.value) return
    deleting.value = true
    try {
        const ok = await submitDelete(categoryToDelete.value.id)
        if (ok) {
            deleteModalOpen.value = false
            categoryToDelete.value = null
            drawerOpen.value = false
            await fetchCategories()
        }
    } finally {
        deleting.value = false
    }
}

function onCategorySaved() {
    fetchCategories()
}

// Chargement initial des deux ressources (liste + referentiel des types).
// Le referentiel est pre-charge ici (et pas dans le drawer) pour que le
// select soit pret au moment ou l'utilisateur clique sur « + Ajouter ».
onMounted(() => {
    fetchCategories()
    fetchTypes()
})
</script>
