import React, { useContext, useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { useSWRInfinite } from 'swr';

import { AppConfigContext } from '../../../stores/AppConfigStore';
import AGGridConfigurationPostes from '../../Commun/listes/configuration/AGGridConfigurationPostes';
import ListeGestionGlobaleEtPerimetre from '../Commun/ListeGestionGlobaleEtPerimetre';
import { createContext } from '../../Commun/listes/gridContext';
import { POSTES } from '../../../constantes/constantes';
import { Chargement } from '../../Commun/Chargement';
import PostesManager from '../../../data-manager/PostesManager';
import { arrayToMap } from '../../../helpers/data-manipulation';

/**
 * Composant générique permettant d'afficher une liste de postes du vivier global ou d'un sous-vivier
 *
 * @component
 * @param {boolean} props.isVivierGlobal - Indique si on doit afficher la liste pour un vivier global (sinon c'est qu'il s'agit d'un sous-vivier)
 *
 * @example
 * return (
 * <ListePostes isVivierGlobal={true} />
 * )
 */
const ListePostes = observer((props) => {
    const appConfig = useContext(AppConfigContext);
    let postesManager = new PostesManager();

    const [postesAdaptes, setPostesAdaptes] = useState(undefined);

    //TODO à instancier une fois pour toute au niveau de l'application
    const agGridConfigurationPostes = new AGGridConfigurationPostes(appConfig.donneesReference);

    /*
     * Chargement des données du vivier global ou du sous-vivier sélectionné
     */
    const getKey = (index) => {
        return postesManager.buildCallKey(props.isVivierGlobal ? 0 : appConfig.idSousVivierSelectionne, { pageSize: 1000, page: index + 1 });
    };
    const { data, error, mutate, size, setSize } = useSWRInfinite(getKey, { refreshInterval: 0 });
    const fullData = 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]);

    // Mise à jour des données suite au choix d'un autre sous-vivier
    useEffect(() => {
        if (typeof data !== 'undefined') {
            setPostesAdaptes(agGridConfigurationPostes.adaptePostes(fullData || []));
        } else {
            //TODO: error handling ici
            if (typeof error == 'undefined') {
                console.info('Chargement des données des postes...');
            } else {
                console.error(error);
            }
        }
    }, [data, error]);

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


    useEffect(() => {
        // Lorsque les données ont été mises à jour, il faut mettre à jour aussi la sélection éventuelle
        if (postesAdaptes !== undefined && appConfig.hasSelectedPostesGlobalEtPerimetre) {
            // On reconstruit la sélection
            const selectedIds = appConfig.selectedPostesGlobalEtPerimetre.map((a) => a.id);
            const newSelection = postesAdaptes.flatMap((p) => (selectedIds.includes(p.id) ? p : []));
            appConfig.setSelectedPostesGlobalEtPerimetre(newSelection);
        }
    }, [postesAdaptes]);

    // Mise à jour de la liste des FE du sous-vivier sélectionné
    useEffect(() => {
        if (!props.isVivierGlobal) {
            let feSousVivier = [];
            if (fullData && fullData.length) {
                const feById = arrayToMap(
                    fullData.flatMap((p) => (p.formation_emploi ? p.formation_emploi : [])),
                    'fe_code'
                );
                feSousVivier = Array.from(feById.values());
                feSousVivier.sort(function (a, b) {
                    return (a.garnison || '').localeCompare(b.garnison) || (a.fe_code || '').localeCompare(b.fe_code);
                });
                //console.log('feSousVivier', feSousVivier);
            }
            appConfig.setFeSousVivierSelectionne(feSousVivier);
        }
    }, [fullData, error]);

    /* Génération du paramétrage des groupes de colonnes et colonnes pour AG Grid */
    const postesFields = agGridConfigurationPostes.buildPostesColumnDefs((() => {
        if (props.isVivierGlobal) {
            return ['organisme', 'poste_NonEditable', 'avis_NonEditable', 'decisions', 'perimetre'];
        }
        const gestionnairePcp = appConfig.isPCP;
        return [
            'organisme',
            gestionnairePcp ? 'poste' : 'poste_NonEditable',
            'ponderations',
            gestionnairePcp ? 'PAMEnCours_PCP' : 'PAMEnCours',
            'avis_NonEditable',
            'decisions'
        ];
    })());

    const postesFieldsFE = agGridConfigurationPostes.buildPostesColumnDefs(['organisme',  {
        groupId: 'poste',
        columns: [
            {
                colId: 'poste_domaine'
            },
            {
                colId: 'poste_filiere'
            },
            {
                colId: 'poste_NF'
            },
            {
                colId: 'poste_ETR'
            },
            {
                colId: 'poste_nbPostesREO'
            },
            {
                colId: 'poste_competences'
            }
        ]
    }, 'ponderations', 'PAMEnCours', 'avis', 'decisions']);

    return (
        <div className={'d-flex flex-column h-100'}>
            {data ? (
                <>
                    {appConfig.feSelected && !props.isVivierGlobal && (
                        <ListeGestionGlobaleEtPerimetre
                            columnDefs={postesFieldsFE}
                            data={postesAdaptes ?? []}
                            mutator={mutate}
                            reqData={fullData}
                            nbItems={fullData.length}
                            title="Postes"
                            itemLabel="poste"
                            itemsLabel="postes  "
                            context={createContext(appConfig, POSTES)}
                            isVivierGlobal={props.isVivierGlobal}
                            isLoadingData={postesAdaptes ? data[0].count > postesAdaptes.length : true}
                        />
                    )}
                    {(!appConfig.feSelected || props.isVivierGlobal) && (
                        <ListeGestionGlobaleEtPerimetre
                            columnDefs={postesFields}
                            data={postesAdaptes ?? []}
                            mutator={mutate}
                            reqData={fullData}
                            nbItems={fullData.length}
                            title="Postes"
                            itemLabel="poste"
                            itemsLabel="postes  "
                            context={createContext(appConfig, POSTES)}
                            isVivierGlobal={props.isVivierGlobal}
                            isLoadingData={postesAdaptes ? data[0].count > postesAdaptes.length : true}
                        />
                    )}
                </>
            ) : (
                <Chargement />
            )}
        </div>
    );
});

export default ListePostes;
