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

/**
 * Composant générique permettant d'afficher une liste de postes d'un sous-vivier.
 *
 * @component
 *
 * @example
 * return (
 * <ListePostes />
 * )
 */
const ListePostes = observer((props) => {
    /** @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.postes;

            // Profil selectionné
            const profil = appConfig.profilSelectionne;

            // Année selectionnée
            const annee = appConfig.PAMSelectionne;

            // Année selectionnée -1 
            // const annee_moins_1 = Number(appConfig.PAMSelectionne-1);

            // Année A+1 du backend
            // const annee_A_plus_1 = appConfig.donneesReference.PAMByStatut.get('PAM A+1').pam_id

            // Création des params 
            const params = { pageSize: 1000, page: pageIndex + 1 };

            // Ajout de le profil au params 
            profil && (params.profile = profil);

            // Ajout de l'année selectionnée au params 
            annee && (params.pam_annee = annee);

            // Ajout du statut de l'année selectionnée au params 
            // annee && annee_A_plus_1 == annee && (params.pam_statut = 'PAM A+1');

            // // Ajout du statut de l'année selectionnée au params 
            // annee && annee_A_plus_1 != annee && (params.pam_statut = 'PAM A');

            // Si on est dans la vue ITD, on remonte tout les postes ITD
            props.isITD && (params.p_specifique = 'ITD');

            // // Si l'année selectionnée est la même que l'année A+1, et on est dans la vue TID on remonte les postes ITD de l'année A. 
            // // TODO : A voir pour les ITD
            props.isITD && (params.pam__in = annee);

            // // Si l'année selectionnée est la même que l'année A+1, on remonte les postes de l'année A et A+1. Sauf pour les ITD NON
            // // TODO : A voir pour les ITD
            // !props.isITD && annee_A_plus_1 == annee && (params.pam__in = [annee, ',', annee_moins_1].join(''));
            
            // Si l'année selectionnée est la même que l'année A, on remonte les postes de l'année A seulement. Même pour les ITD 
            // TODO : A voir pour les ITD
            !props.isITD  && (params.pam__in = annee);

            

            

            if (props.isITD || profil === PROFILS.ITD) {
                return manager.buildCallKey(params);
            }
            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 {[AGGridConfigurationPostes, function]} */
    const [configurateur, setConfigurateur] = useState(undefined);
    useEffect(() => {
        setConfigurateur(new AGGridConfigurationPostes(appConfig.donneesReference));
    }, [appConfig.donneesReference]);

    const [donneesAdaptees, setDonneesAdaptees] = useState(undefined);
    useEffect(() => {
        if (data) {
            setDonneesAdaptees(configurateur?.adaptePostes(fullData));
        } else if (error) {
            console.error(error);
        } else {
            console.info('Chargement des données des postes...');
        }
    }, [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.hasSelectedPostesPerimetreEtITD) {
            // On reconstruit la sélection
            const selectedIds = appConfig.selectedPostesPerimetreEtITD.map((val) => val.id);
            const newSelection = donneesAdaptees.flatMap((val) => (selectedIds.includes(val.id) ? val : []));
            appConfig.setSelectedPostesPerimetreEtITD(newSelection);
        }
    }, [donneesAdaptees]); // TODO appConfig.selectedPostesPerimetre ?

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

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

    const [feColumnDefs, setFeColumnDefs] = useState(undefined);
    useEffect(() => {
        setFeColumnDefs(configurateur?.buildPostesColumnDefs([
            'organisme',
            {
                groupId: 'poste',
                columns: [
                    {
                        colId: 'poste_domaine'
                    },
                    {
                        colId: 'poste_filiere'
                    },
                    {
                        colId: 'poste_NF'
                    },
                    {
                        colId: 'poste_ETR'
                    },
                    {
                        colId: 'poste_competences'
                    }
                ]
            },
            'ponderations', 'PAMEnCours', 'avis', 'decisions'
        ]));
    }, [configurateur])

    const [columnDefs, setColumnDefs] = useState(undefined);
    useEffect(() => {
        // génération du paramétrage des groupes de colonnes et colonnes pour AG Grid
        setColumnDefs(configurateur?.buildPostesColumnDefs((() => {
            const isPcp = appConfig.profilSelectionne === PROFILS.PCP;
            const isItd = appConfig.profilSelectionne === PROFILS.ITD;
            const isBvt = appConfig.profilSelectionne === PROFILS.BVT;
            if (props.isITD) {
                return [
                    'organisme',
                    'poste_ITD',
                    isItd ? 'rattachement_perimetre' : 'rattachement_perimetre_NonEditable',
                    'avis_NonEditable',
                    'decision_ITD'];
            }
            if (isPcp
                || appConfig.profilSelectionne === PROFILS.FILIERE
                || (!appConfig.profilSelectionne && appConfig.hasProfil(PROFILS.SUPER))) {
                return [
                    'organisme',
                    isPcp ? 'poste' : 'poste_NonEditable',
                    'ponderations',
                    isPcp ? 'PAMEnCours_PCP' : 'PAMEnCours',
                    isPcp ? 'avis' : 'avis_NonEditable',
                    isPcp ? 'decisions' : 'decisions_NonEditable',
                ];
            }
            if (isBvt) {
                return [
                    'organisme',
                    'poste',
                    'ponderations',
                    'PAMEnCours',
                    'avis',
                    'decisions',
                ];
            }
            return ['organisme'];
        })()));
    }, [configurateur, appConfig.utilisateurConnecte?.profils, appConfig.profilSelectionne, appConfig.feSelected, feColumnDefs])

    const [contexteAgGrid] = useState(createGridContext(appConfig, POSTES, mutate));
    useEffect(() => { rafraichirContextAgGrid(contexteAgGrid, appConfig, POSTES) }, [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="Postes"
                    itemLabel="poste"
                    itemsLabel="postes"
                    isITD={props.isITD}
                    context={contexteAgGrid}
                    isLoadingData={donneesAdaptees ? data[0].count > donneesAdaptees.length : true}
                />
            ) : (
                <Chargement />
            )}
        </div>
    );
});

export default ListePostes;
