import React, { useState } from 'react';
import { AgGridReact } from 'ag-grid-react';

import 'ag-grid-enterprise';
import 'ag-grid-community/dist/styles/ag-grid.css';
import 'ag-grid-community/dist/styles/ag-theme-balham.css';

import { debounce, testLocalStorageAvailable } from '../../../helpers/misc-helpers';
import { autoSizeColumns } from '../../Commun/listes/fonctionsEtCallbacksAgGrid';

/**
 * Composant AgGridReact adapté pour mémorisation automatique du paramétrage.
 *
 * @component
 * @param {string} props.id - Identifiant unique de la grille
 * @param {?Object} props.gridOptions - Paramètre gridOptions du composant AgGridReact
 * @param {?Object} props.columnDefs - Paramètre columnDefs du composant AgGridReact
 * @param {string} props.rowData - Paramètre rowData du composant AgGridReact
 * @param {string} props.persistencePrefix - Préfixe à utiliser pour la persistence du paramétrage
 */
const CustomAgGridReact = (props) => {
    const isLocalStorageAvailable = testLocalStorageAvailable();

    const DEBOUNCE_DELAY = 500;

    const [gridId, setGridId] = useState(props.id);
    const [originalGridOptions, setOriginalGridOptions] = useState({ ...props.gridOptions });
    //const [gridApi, setGridApi] = useState(undefined);
    //const [gridColumnApi, setGridColumnApi] = useState(undefined);

    const debounceSaveGridColumnState = debounce((columnState) => {
        saveValue('columnState', columnState);
    }, DEBOUNCE_DELAY);

    const debounceSaveGridColumnGroupState = debounce((columnGroupState) => {
        saveValue('columnGroupState', columnGroupState);
    }, DEBOUNCE_DELAY);

    const debounceSaveGridPivotModeState = debounce((isPivotMode) => {
        saveValue('pivotModeState', isPivotMode);
    }, DEBOUNCE_DELAY);

    const onFirstDataRendered = (params) => {
        params.suppressColumnMoveAnimation = true;

        const isPivotMode = loadValue('pivotModeState');
        const isPivotModeDifferent = params.columnApi.isPivotMode() !== isPivotMode;
        if (isPivotMode !== null && isPivotModeDifferent) {
            params.columnApi.setPivotMode(isPivotMode);
        }

        const columnState = loadValue('columnState');
        if (columnState !== null) {
            params.columnApi.setColumnState(columnState);
        }

        const columnGroupState = loadValue('columnGroupState');
        if (columnGroupState !== null) {
            params.columnApi.setColumnGroupState(columnGroupState);
        }

        const sortModel = loadValue('sortModel');
        if (sortModel !== null) {
            params.api.setSortModel(sortModel);
        }

        const filterModel = loadValue('filterModel');
        if (filterModel !== null) {
            params.api.setFilterModel(filterModel);
        }

        params.suppressColumnMoveAnimation = false;
    };

    const onFilterChanged = (params) => {
        let filterModel = params.api.getFilterModel();
        saveValue('filterModel', filterModel);
    };

    const onSaveGridColumnState = (params) => {
        //        if (!params.columnApi) return;

        let columnState = params.columnApi?.getColumnState();
        let columnGroupState = params.columnApi?.getColumnGroupState();

        debounceSaveGridColumnState(columnState);
        debounceSaveGridColumnGroupState(columnGroupState);
    };

    const onSavePivotModeState = (params) => {
        let isPivotMode = params.columnApi.isPivotMode();

        let isPivotModeDifferentFromProps = params.columnApi.isPivotMode() !== isPivotMode;
        if (isPivotModeDifferentFromProps) debounceSaveGridPivotModeState(isPivotMode);
    };

    /**
     * Retourne la clé de stockage pour un nom de valeur donné.
     *
     * @param {string} name - Nom de la valeur
     * @return {string} key - Clé de stockage
     */
    const getStorageKey = (name) => {
        return props.persistencePrefix + '/CAGR/' + gridId + '/' + name;
    };

    /**
     * Charge une valeur de nom donné depuis le localStorage.
     *
     * @param {string} name - Nom de la valeur
     * @param {*} value - Valeur
     */
    const saveValue = (name, value) => {
        if (!props.persistencePrefix || !isLocalStorageAvailable) {
            return;
        }

        localStorage.setItem(getStorageKey(name), JSON.stringify(value));
    };

    /**
     * Charge une valeur de nom donné depuis le localStorage.
     *
     * @param {string} name - Nom de la valeur
     * @param {*} value - Valeur
     */
    const loadValue = (name, value) => {
        if (!props.persistencePrefix || !isLocalStorageAvailable) {
            return null;
        }

        const jsonValue = localStorage.getItem(getStorageKey(name));
        return jsonValue !== null ? JSON.parse(jsonValue) : null;
    };

    return (
        <AgGridReact
            gridOptions={props.gridOptions}
            columnDefs={props.columnDefs}
            rowData={props.rowData}
            // grid events
            onFirstDataRendered={(params) => {
                autoSizeColumns();
                onFirstDataRendered(params);
                originalGridOptions?.onFirstDataRendered?.(params);
            }}
            // grid state change events
            onFilterChanged={(params) => {
                onFilterChanged(params);
                originalGridOptions?.onFilterChanged?.(params);
            }}
            onSortChanged={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onSortChanged?.(params);
            }}
            onColumnVisible={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnVisible?.(params);
            }}
            onColumnPinned={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnPinned?.(params);
            }}
            onColumnResized={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnResized?.(params);
            }}
            onColumnMoved={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnMoved?.(params);
            }}
            onColumnRowGroupChanged={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnRowGroupChanged?.(params);
            }}
            onColumnValueChanged={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnValueChanged?.(params);
            }}
            onColumnPivotChanged={(params) => {
                onSaveGridColumnState(params);
                originalGridOptions?.onColumnPivotChanged?.(params);
            }}
            onColumnPivotModeChanged={(params) => {
                onSavePivotModeState(params);
                originalGridOptions?.onColumnPivotModeChanged?.(params);
            }}
            onGridSizeChanged={autoSizeColumns}
        ></AgGridReact>
    );
};

export default CustomAgGridReact;
