<template>
    <div>
        <!-- En-tete -->
        <div class="flex items-center justify-between">
            <h1 class="text-xl font-bold text-primary-500 sm:text-2xl">
                {{ t('admin.roles.title') }}
            </h1>
            <MalioButton
                v-if="can('core.roles.manage')"
                :label="t('admin.roles.newRole')"
                icon-name="mdi:plus"
                icon-position="left"
                @click="openCreateDrawer"
            />
        </div>

        <!-- Table des roles avec filtres + pagination -->
        <MalioDataTable
            v-model:page="page"
            v-model:per-page="perPage"
            class="mt-6"
            :columns="columns"
            :items="roleItems"
            :total-items="totalItems"
            :row-clickable="canManage"
            :empty-message="t('admin.roles.noRoles')"
            @row-click="onRowClick"
        >
            <template #header-label>
                <input
                    v-model="filters.label"
                    type="text"
                    :placeholder="t('admin.roles.table.label')"
                    class="w-full border-0 border-b border-black bg-transparent px-0 py-1 text-xl outline-none"
                >
            </template>
            <template #header-code>
                <input
                    v-model="filters.code"
                    type="text"
                    :placeholder="t('admin.roles.table.code')"
                    class="w-full border-0 border-b border-black bg-transparent px-0 py-1 text-xl outline-none"
                >
            </template>
            <template #header-permissions>
                <select
                    v-model="filters['permissions.code']"
                    class="w-full appearance-none border-0 border-b border-black bg-transparent px-0 py-1 text-xl outline-none"
                >
                    <option value="">
                        {{ t('admin.roles.table.permissions') }}
                    </option>
                    <option
                        v-for="perm in allPermissions"
                        :key="perm.id"
                        :value="perm.code"
                    >
                        {{ perm.code }}
                    </option>
                </select>
            </template>
            <template #header-system>
                <select
                    v-model="filters.isSystem"
                    class="w-full appearance-none border-0 border-b border-black bg-transparent px-0 py-1 text-xl outline-none"
                >
                    <option value="">
                        {{ t('admin.roles.table.system') }}
                    </option>
                    <option value="true">
                        {{ t('common.yes') }}
                    </option>
                    <option value="false">
                        {{ t('common.no') }}
                    </option>
                </select>
            </template>

            <template #cell-code="{ item }">
                <span class="font-mono text-xs">{{ item.code }}</span>
            </template>
            <template #cell-permissions="{ item }">
                {{ item.permissions }}
            </template>
            <template #cell-system="{ item }">
                <span
                    v-if="item.isSystem"
                    class="inline-flex items-center rounded-full bg-blue-100 px-2.5 py-0.5 text-xs font-medium text-blue-800"
                >
                    {{ t('admin.roles.table.system') }}
                </span>
            </template>
        </MalioDataTable>

        <!-- Drawer creation/edition -->
        <RoleDrawer
            v-model="drawerOpen"
            :role="selectedRole"
            @saved="onRoleSaved"
            @delete="onDeleteRequest"
        />

        <!-- Modale de suppression -->
        <RoleDeleteModal
            v-model="deleteModalOpen"
            :role-label="roleToDelete?.label ?? ''"
            :loading="deleting"
            @confirm="handleDelete"
        />
    </div>
</template>

<script setup lang="ts">
import type { Permission, Role } from '~/shared/types/rbac'

const { t } = useI18n()
const api = useApi()
const { can } = usePermissions()
const canManage = computed(() => can('core.roles.manage'))

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

// Etat DataTable centralise : pagination serveur + filtres debounces.
// `isSystem` est une string ('true'/'false'/'') plutot qu'un bool : les
// <select> HTML travaillent en string et API Platform BooleanFilter
// accepte les strings 'true'/'false' telles quelles.
const {
    items,
    totalItems,
    page,
    perPage,
    filters,
    reload,
} = useDataTableServerState<Role>('/roles', {
    label: '',
    code: '',
    isSystem: '',
    'permissions.code': '',
})

// Chargement one-shot des permissions pour alimenter le select filter.
// Independant du composable de table : cette liste ne bouge pas pendant
// la session admin.
const allPermissions = ref<Permission[]>([])

async function loadPermissions(): Promise<void> {
    const data = await api.get<{ member: Permission[] }>(
        '/permissions',
        { itemsPerPage: 999, orphan: false },
        { toast: false },
    )
    allPermissions.value = (data.member ?? []).sort(
        (a, b) => a.code.localeCompare(b.code),
    )
}

const columns = [
    { key: 'label', label: t('admin.roles.table.label') },
    { key: 'code', label: t('admin.roles.table.code') },
    { key: 'permissions', label: t('admin.roles.table.permissions') },
    { key: 'system', label: t('admin.roles.table.system') },
]

// Transformer les roles en items compatibles MalioDataTable
const roleItems = computed(() =>
    items.value.map(role => ({
        id: role.id,
        label: role.label,
        code: role.code,
        permissions: role.permissions.length,
        isSystem: role.isSystem,
        system: '', // colonne geree par le slot
    })),
)

function getRoleById(id: number): Role | undefined {
    return items.value.find(r => r.id === id)
}

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

const drawerOpen = ref(false)
const selectedRole = ref<Role | null>(null)
const deleteModalOpen = ref(false)
const roleToDelete = ref<Role | null>(null)
const deleting = ref(false)

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

function openEditDrawer(role: Role) {
    selectedRole.value = role
    drawerOpen.value = true
}

function onDeleteRequest() {
    if (!selectedRole.value || selectedRole.value.isSystem) return
    roleToDelete.value = selectedRole.value
    deleteModalOpen.value = true
}

async function handleDelete() {
    if (!roleToDelete.value) return
    deleting.value = true
    try {
        await api.delete(`/roles/${roleToDelete.value.id}`, {}, {
            toastSuccessMessage: t('admin.roles.toast.deleted'),
        })
        deleteModalOpen.value = false
        roleToDelete.value = null
        drawerOpen.value = false
        reload()
    } finally {
        deleting.value = false
    }
}

function onRoleSaved() {
    reload()
}

onMounted(() => {
    loadPermissions()
    reload()
})
</script>
