export type HydraCollection<T> = {
    'hydra:member'?: T[]
    'hydra:totalItems'?: number
    'member'?: T[]
    'totalItems'?: number
}

export function extractHydraMembers<T>(response: HydraCollection<T>): T[] {
    return response['hydra:member'] ?? response['member'] ?? []
}

function extractHydraTotal<T>(response: HydraCollection<T>): number | undefined {
    return response['hydra:totalItems'] ?? response['totalItems']
}

/**
 * Récupère TOUS les éléments d'une collection Hydra paginée en parcourant les pages.
 *
 * `extractHydraMembers` ne lit que la première page (30 éléments par défaut côté
 * API Platform) : toute liste plus longue est tronquée silencieusement. Utiliser
 * ce helper dès qu'une collection potentiellement > 30 éléments doit être
 * affichée en entier alors que sa ressource back reste paginée.
 *
 * `fetchPage` reçoit le numéro de page (1-indexé) et doit renvoyer la collection
 * Hydra correspondante (passer `page` en query param de l'appel API).
 *
 * @param maxPages garde-fou anti-boucle infinie (par défaut 1000 pages).
 */
export async function fetchAllHydra<T>(
    fetchPage: (page: number) => Promise<HydraCollection<T>>,
    maxPages = 1000,
): Promise<T[]> {
    const first = await fetchPage(1)
    const all = extractHydraMembers(first)
    const total = extractHydraTotal(first)
    const pageSize = all.length

    // 1ʳᵉ page vide → collection vide, rien de plus à récupérer.
    if (pageSize === 0) {
        return all
    }

    let page = 2
    while (page <= maxPages) {
        if (total !== undefined) {
            // Total connu : on s'arrête dès qu'on a tout récupéré.
            if (all.length >= total) {
                break
            }
        } else if (all.length % pageSize !== 0) {
            // Total inconnu (provider custom sans `hydra:totalItems`) : la dernière
            // page récupérée n'était pas pleine → fin de collection. On ne s'arrête
            // pas en silence sur la 1ʳᵉ page, contrairement à `extractHydraMembers`.
            break
        }

        const next = await fetchPage(page)
        const members = extractHydraMembers(next)
        if (members.length === 0) {
            break
        }
        all.push(...members)
        page += 1
    }

    return all
}
