import { observer } from 'mobx-react';
import React, { useContext, useEffect, useState } from 'react';
import { useSWRInfinite } from 'swr';
import { ADMINISTRES, PROFILS } from '../../../constantes/constantes';
import { isPresent } from '../../../helpers/objects';
import { fetcherPage, SANS_URL } from '../../../helpers/swr';
import AppConfigStore, { AppConfigContext } from '../../../stores/AppConfigStore';
import { Chargement } from '../../Commun/Chargement';
import AGGridConfigurationAdministres from '../../Commun/listes/configuration/AGGridConfigurationAdministres';
import { createGridContext, rafraichirContextAgGrid } from '../../Commun/listes/gridContext';
import ListePerimetre from './ListePerimetre';

/**
 * Composant générique permettant d'afficher une liste d'administrés d'un sous-vivier.
 *
 * @component
 *
 * @example
 * return (
 * <ListeAdministres />
 * )
 */
const ListeAdministres = observer(() => {
    /** @type {AppConfigStore} */
    const appConfig = useContext(AppConfigContext);

    // Chargement des données du sous-vivier ou des formations sélectionnées
    const getKey = (pageIndex) => {
        try {
            const manager = appConfig.managers.administres;
            const profil = appConfig.profilSelectionne;
            const annee = appConfig.PAMSelectionne;
            const params = { pageSize: 1000, page: pageIndex + 1 };
            annee && (params.pam__in = annee);
            profil && (params.profile = profil);
            if (profil === PROFILS.FILIERE) {
                return appConfig.idsSousViviersSelectionnees?.length
                    ? manager.buildCallKeySousVivier(appConfig.idsSousViviersSelectionnees, params)
                    : SANS_URL;
            }
            if (profil === PROFILS.BVT) {
                return appConfig.idsSousViviersSelectionnees?.length
                    ? manager.buildCallKeySousVivier(appConfig.idsSousViviersSelectionnees, params)
                    : SANS_URL;
            }
            if (profil === PROFILS.PCP) {
                return appConfig.idsFormationsEmploisSelectionnees?.length
                    ? manager.buildCallKeyFormationEmploi(appConfig.idsFormationsEmploisSelectionnees, params)
                    : SANS_URL;
            }
            return SANS_URL;
        } catch (e) {
            console.error(e);
        }
    };
    const { data, error, mutate, size, setSize } = useSWRInfinite(getKey, fetcherPage, { refreshInterval: 0 });
    const fullData = Array.isArray(data) ? [].concat(...data.map((d) => d.results)) : [];

    // Permet de charger la page suivante de données s'il reste des données à charger
    useEffect(() => {
        if (data && data[data.length - 1].next) {
            setSize(size + 1);
        }
    }, [data]);

    /** @type {[AGGridConfigurationAdministres, function]} */
    const [configurateur, setConfigurateur] = useState(undefined);
    useEffect(() => {
        setConfigurateur(new AGGridConfigurationAdministres(appConfig.donneesReference));
    }, [appConfig.donneesReference]);

    const [donneesAdaptees, setDonneesAdaptees] = useState(undefined);
    useEffect(() => {
        if (data) {
            setDonneesAdaptees(configurateur?.adapteAdministres(fullData));
        } else if (error) {
            console.error(error);
        } else {
            console.info('Chargement des données des administrés...');
        }
    }, [configurateur, data, error]);

    // Mise à jour des données suite au choix d'un autre sous-vivier
    useEffect(() => {
        // Lorsque les données ont été mises à jour, il faut mettre à jour aussi la sélection éventuelle
        if (donneesAdaptees && appConfig.hasSelectedAdministresPerimetre) {
            // On reconstruit la sélection
            const selectedIds = appConfig.selectedAdministresPerimetre.map((val) => val.id);
            const newSelection = donneesAdaptees.flatMap((val) => (selectedIds.includes(val.id) ? val : []));
            appConfig.setSelectedAdministresPerimetre(newSelection);
        }
    }, [donneesAdaptees]); // TODO appConfig.selectedAdministresPerimetre ?

    // Revalidation des donnees par un button dans l'entete page
    useEffect(() => {
        mutate()
    }, [appConfig.donneesRecharger])

    const [columnDefs, setColumnDefs] = useState(undefined);
    useEffect(() => {
        // génération du paramétrage des groupes de colonnes et colonnes pour AG Grid
        const isPcp = appConfig.profilSelectionne === PROFILS.PCP;
        const isBvt = appConfig.profilSelectionne === PROFILS.BVT;
        if (isPcp
            || appConfig.profilSelectionne === PROFILS.FILIERE
            || (!appConfig.profilSelectionne && appConfig.hasProfil(PROFILS.SUPER))) {

            setColumnDefs(configurateur?.buildAdministresColumnDefs(
                [
                    'identite',
                    isPcp ? 'EIPFutur_NonEditable' : 'EIPFutur',
                    'affectationActuelle',
                    'fonction',
                    'competences',
                    isPcp ? 'PAMEnCours_NonEditable' : 'PAMEnCours',
                    isPcp ? 'decision_PCP' : 'decision',
                    isPcp ? 'affectationFuture_PCP' : 'affectationFuture',
                    'situationFuture',
                    isPcp ? 'FORMOB_NonEditable': 'FORMOB',
                    'EIPActuel',
                    'matrimonial',
                    'service'
                ],
                { profils: isPcp ? [PROFILS.PCP] : [PROFILS.FILIERE] }
            ));
        } else if (isBvt) {
            setColumnDefs(configurateur?.buildAdministresColumnDefs(
                [
                    'identite',
                    'EIPFutur',
                    'affectationActuelle',
                    'fonction',
                    'competences',
                    'PAMEnCours',
                    'decision',
                    'affectationFuture',
                    'situationFuture',
                    'FORMOB',
                    'EIPActuel',
                    'matrimonial',
                    'service'
                ],
                { profils: isBvt ? [PROFILS.BVT] : [PROFILS.FILIERE] }
            ));
        } else {
            // TODO autre profils
            setColumnDefs(configurateur?.buildAdministresColumnDefs(['identite']));
        }
    }, [configurateur, appConfig.utilisateurConnecte?.profils, appConfig.profilSelectionne])

    const [contexteAgGrid] = useState(createGridContext(appConfig, ADMINISTRES));
    useEffect(() => { rafraichirContextAgGrid(contexteAgGrid, appConfig, ADMINISTRES, mutate) }, [appConfig.donneesReference, appConfig.profilSelectionne]);

    return (
        <div className={'d-flex flex-column h-100'}>
            {data ? (
                <ListePerimetre
                    columnDefs={columnDefs}
                    data={donneesAdaptees}
                    nbItems={fullData.length}
                    reqData={fullData}
                    mutator={mutate}
                    title="Administrés"
                    itemLabel="administré"
                    itemsLabel="administrés"
                    context={contexteAgGrid}
                    isLoadingData={donneesAdaptees ? data[0].count > donneesAdaptees.length : true}
                />
            ) : (
                <Chargement />
            )}
        </div>
    );
});

export default ListeAdministres;
