<template>
    <div>
        <div class="flex items-center justify-between">
            <h2 class="text-lg font-bold text-neutral-900">{{ $t('admin.audit.title') }}</h2>
        </div>

        <div class="mt-4 flex flex-wrap gap-4">
            <MalioSelect
                v-model="entityTypeFilter"
                :options="entityTypeOptions"
                :label="$t('admin.audit.filterEntityType')"
                :empty-option-label="$t('admin.audit.filterEntityTypeAll')"
                group-class="w-64"
            />
            <MalioSelect
                v-model="actionFilter"
                :options="actionOptions"
                :label="$t('admin.audit.filterAction')"
                :empty-option-label="$t('admin.audit.filterActionAll')"
                group-class="w-64"
            />
        </div>

        <DataTable
            :columns="columns"
            :items="rows"
            :loading="isLoading"
            :empty-message="$t('admin.audit.empty')"
        >
            <template #cell-performedAt="{ item }">
                {{ formatDate(item.performedAt) }}
            </template>
            <template #cell-entityType="{ item }">
                {{ entityTypeLabel(item.entityType) }}
            </template>
            <template #cell-action="{ item }">
                {{ actionLabel(item.action) }}
            </template>
        </DataTable>

        <div class="mt-4 flex items-center justify-between">
            <span class="text-sm text-neutral-500">{{ $t('admin.audit.page', { page }) }}</span>
            <div class="flex gap-2">
                <MalioButton
                    variant="secondary"
                    button-class="w-auto px-4"
                    :label="$t('admin.audit.previous')"
                    :disabled="page <= 1 || isLoading"
                    @click="goToPage(page - 1)"
                />
                <MalioButton
                    variant="secondary"
                    button-class="w-auto px-4"
                    :label="$t('admin.audit.next')"
                    :disabled="!hasNextPage || isLoading"
                    @click="goToPage(page + 1)"
                />
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import type { AuditLogAction, AuditLogItem } from '~/modules/core/services/audit-logs'
import { useAuditLogService } from '~/modules/core/services/audit-logs'

import type { DataTableColumn } from '~/components/ui/DataTable.vue'

const { t, te } = useI18n()

const PAGE_SIZE = 30

const columns = computed<DataTableColumn[]>(() => [
    { key: 'performedAt', label: t('admin.audit.date'), primary: true },
    { key: 'performedBy', label: t('admin.audit.performedBy') },
    { key: 'entityType', label: t('admin.audit.entityType') },
    { key: 'action', label: t('admin.audit.action') },
    { key: 'entityId', label: t('admin.audit.entityId') },
])

const actionOptions = computed<{ value: AuditLogAction, label: string }[]>(() => [
    { value: 'create', label: t('audit.action.create') },
    { value: 'update', label: t('audit.action.update') },
    { value: 'delete', label: t('audit.action.delete') },
])

const auditLogService = useAuditLogService()

const rows = ref<AuditLogItem[]>([])
const entityTypes = ref<string[]>([])
const totalItems = ref(0)
const page = ref(1)
const isLoading = ref(true)
const entityTypeFilter = ref<string | null>(null)
const actionFilter = ref<AuditLogAction | null>(null)

const entityTypeOptions = computed<{ value: string, label: string }[]>(() =>
    entityTypes.value.map((value) => ({ value, label: entityTypeLabel(value) })),
)

// PAGE_SIZE must match the API default page size. The full-page guard keeps the
// "next" button accurate even on the last (partial) page.
const hasNextPage = computed(() => rows.value.length >= PAGE_SIZE && page.value * PAGE_SIZE < totalItems.value)

function entityTypeLabel(value: string): string {
    const key = `audit.entity.${value}`
    return te(key) ? t(key) : value
}

function actionLabel(action: AuditLogAction): string {
    return t(`audit.action.${action}`)
}

function formatDate(value: string): string {
    return new Date(value).toLocaleString('fr-FR', {
        day: '2-digit',
        month: '2-digit',
        year: 'numeric',
        hour: '2-digit',
        minute: '2-digit',
    })
}

async function loadItems() {
    isLoading.value = true
    try {
        const result = await auditLogService.list({
            page: page.value,
            entityType: entityTypeFilter.value ?? undefined,
            action: actionFilter.value ?? undefined,
        })
        rows.value = result.items
        totalItems.value = result.totalItems
    } finally {
        isLoading.value = false
    }
}

async function loadEntityTypes() {
    entityTypes.value = await auditLogService.entityTypes()
}

function goToPage(target: number) {
    if (target < 1) {
        return
    }
    page.value = target
    loadItems()
}

watch([entityTypeFilter, actionFilter], () => {
    page.value = 1
    loadItems()
})

onMounted(() => {
    loadItems()
    loadEntityTypes()
})
</script>
