<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.users.title') }}
            </h1>
        </div>

        <!-- Table des utilisateurs -->
        <MalioDataTable
            class="mt-6"
            :columns="columns"
            :items="userItems"
            :total-items="users.length"
            :row-clickable="canManage"
            :empty-message="t('admin.users.noUsers')"
            @row-click="onRowClick"
        >
            <template #cell-admin="{ item }">
                <span
                    v-if="item.admin"
                    class="inline-flex items-center rounded-full bg-purple-100 px-2.5 py-0.5 text-xs font-medium text-purple-800"
                >
                    {{ t('admin.users.table.admin') }}
                </span>
            </template>
        </MalioDataTable>

        <!-- Drawer RBAC -->
        <UserRbacDrawer
            v-model="drawerOpen"
            :user="selectedUser"
            @saved="onUserSaved"
        />
    </div>
</template>

<script setup lang="ts">
import type { UserListItem } from '~/shared/types/rbac'
import type { Site } from '~/shared/types/sites'

const { t } = useI18n()
const api = useApi()
const { can } = usePermissions()

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

const canManage = computed(() => can('core.users.manage'))

const users = ref<UserListItem[]>([])
const sitesById = ref(new Map<number, Site>())
const loading = ref(false)
const drawerOpen = ref(false)
const selectedUser = ref<UserListItem | null>(null)

const columns = [
    { key: 'username', label: t('admin.users.table.username') },
    { key: 'admin', label: t('admin.users.table.admin') },
    { key: 'roles', label: t('admin.users.table.roles') },
    { key: 'directPermissions', label: t('admin.users.table.directPermissions') },
    { key: 'sites', label: t('admin.users.table.sites') },
]

// Extraire l'id numerique depuis une IRI API Platform type `/api/sites/3`.
function iriToId(iri: string): number {
    return Number(iri.split('/').pop())
}

const userItems = computed(() =>
    users.value.map(user => ({
        id: user.id,
        username: user.username,
        admin: user.isAdmin,
        roles: user.roles.length,
        directPermissions: user.directPermissions.length,
        // Affichage : liste des noms de sites separes par virgule. Les IRIs
        // du payload /api/users (groupe user:list) sont resolues via la Map
        // construite en parallele depuis /api/sites.
        sites: (user.sites ?? [])
            .map(iri => sitesById.value.get(iriToId(iri))?.name)
            .filter((name): name is string => Boolean(name))
            .join(', '),
    })),
)

async function loadUsers() {
    loading.value = true
    try {
        // Chargement parallele : les sites alimentent la Map de resolution
        // IRI→name pour la colonne "Sites" de la table.
        const [usersData, sitesData] = await Promise.all([
            api.get<{ member: UserListItem[] }>('/users', {}, { toast: false }),
            api.get<{ member: Site[] }>('/sites', { itemsPerPage: 999 }, { toast: false }),
        ])
        users.value = usersData.member
        sitesById.value = new Map(sitesData.member.map(s => [s.id, s]))
    } finally {
        loading.value = false
    }
}

function getUserById(id: number): UserListItem | undefined {
    return users.value.find(u => u.id === id)
}

function openDrawer(user: UserListItem) {
    selectedUser.value = user
    drawerOpen.value = true
}

function onRowClick(item: Record<string, unknown>) {
    const user = getUserById(item.id as number)
    if (user) openDrawer(user)
}

function onUserSaved() {
    loadUsers()
}

onMounted(() => {
    loadUsers()
})
</script>
